
Sessions expiring unexpectedly, users getting logged out randomly, or having to log in again every page load — these are classic PHP session problems on shared hosting. The root causes are different from VPS or dedicated servers because of how the shared environment handles session garbage collection and file permissions. This guide covers every fix, from simple .htaccess tweaks to database-backed sessions.
Why PHP Sessions Expire Fast on Shared Hosting
GC Triggered by Other Users
Shared hosting stores sessions in a common directory. When another user's script triggers GC (Garbage Collection), it may delete your sessions too.
session.gc_maxlifetime Too Short
Default is 1440 seconds (24 minutes). Without activity, the session expires and gets deleted on the next GC run.
Session Path Permissions
If PHP can't write to the session directory, sessions are never saved. On next request, PHP finds no session and treats the user as logged out.
Cookie Domain/Path Mismatch
If the session cookie is misconfigured, the browser won't send it back with requests — making every request appear as a new session.
Check Your Current Session Settings
Create a temporary session_info.php to see what the server is actually using (delete after checking):
Fix 1 — Set Values via .htaccess or php.ini
The simplest fix is to override session settings in .htaccess or a local php.ini:
86400 = 24 hours. Adjust to match your app's requirements. For most apps, 24 hours is a reasonable maximum.
Fix 2 — Move Sessions to a Private Directory
The core issue on shared hosting is that other users' GC runs can delete your sessions. Fix this permanently by storing sessions in a directory only your account can access:
Security: The sessions/ directory must not be web-accessible. Add a deny from all rule in sessions/.htaccess or place the folder outside public_html.
Fix 3 — Store Sessions in the Database (Recommended for Production)
The most robust solution — eliminates GC interference entirely by storing sessions in MySQL:
Fix 4 — Secure Cookie Settings
If the session data exists but users still get logged out, the browser may not be sending the session cookie back. Fix cookie settings:
Fix 5 — Regenerate Session ID After Login
Always regenerate the session ID after a successful login to prevent session fixation attacks:
Debug with a Test Script
Refresh the page repeatedly. If the counter keeps increasing, sessions are working. If the counter resets to 1 every time, the session is still broken.
Summary: Small app → move sessions to a private directory (Fix 2). Production app with many users → store sessions in MySQL (Fix 3). Always combine with secure cookie settings (Fix 4).
Comparing Session Storage Methods
Each session storage approach has different trade-offs. Choosing the right one for your application size and requirements leads to a permanent fix rather than a temporary workaround.
| Storage Method | Best For | Advantages | Limitations |
|---|---|---|---|
| Filesystem (Default) | Local / development | Zero configuration needed | Other users' GC can delete your sessions |
| Private directory | Shared hosting, small apps | Eliminates cross-user GC, easy to implement | Still relies on disk; disk-full events cause issues |
| MySQL database | Production apps with many users | Very stable, precise expiry control | Adds DB load; expired rows need cleanup |
| Redis / Memcached | VPS / high-traffic apps | Extremely fast, supports multiple servers | Requires extra PHP extensions; not on all hosts |
Session Security — What to Harden When You Extend Session Lifetime
Longer-lived sessions are more convenient but carry greater security risk. Every fix that extends session lifetime should be paired with the following security measures.
Prevent Session Hijacking
Session hijacking occurs when an attacker steals a user's session ID and impersonates them. Key defences:
- Enforce HTTPS — set
session.cookie_secure = 1so cookies are only sent over encrypted connections - Set
session.cookie_httponly = 1to prevent JavaScript from accessing the session cookie (mitigates XSS) - Verify User-Agent and IP address against the values stored at login time
- Regenerate the session ID whenever privileges change (login, logout, role change)
Prevent Session Fixation
Session fixation is when an attacker forces a victim to use a known session ID. One line of code prevents it:
Implement Both Idle and Absolute Timeouts
Relying solely on gc_maxlifetime is not enough for production applications. Enforce two separate expiry rules in PHP itself:
Common Questions About PHP Sessions on Hosting
I increased gc_maxlifetime but sessions still expire early — why?
On shared hosting, another account may run GC with a shorter gc_maxlifetime setting and delete your session files in the process. This is the most common reason why simply increasing gc_maxlifetime does not fully solve the problem. Moving to a private session directory (Fix 2) or a database (Fix 3) eliminates this interference entirely because other users cannot touch your storage.
Does WordPress have the same PHP session problem?
WordPress does not use PHP's native $_SESSION at all — it uses its own Authentication Cookies (wordpress_logged_in_*, wordpress_*). WordPress login timeouts are caused by incorrect cookie domain settings, HTTPS/HTTP mixed content, or regenerated Secret Keys in wp-config.php. The fix is to set COOKIEPATH and COOKIE_DOMAIN correctly in wp-config.php and ensure the site runs on HTTPS consistently.
Can I use Redis for sessions on shared hosting?
Only if your hosting plan includes the phpredis or predis PHP extension. You can check with phpinfo() or ask support. For applications that need Redis, a VPS gives you a dedicated Redis service with full configuration control, starting at ฿500/month on AsiaGB.
PHP Hosting with Full Session Control
AsiaGB Hosting supports custom PHP session handlers, MySQL sessions, and private session paths. Starting at ฿500/year.
View Hosting Plans