From the PHP manual, session.gc_probability and session.gc_divisor state that gc will occur based on this probability. I get that.
What I'm not clear on is whether this probability is on a session by session basis or overall.
So if my probability is 1% (1/100) that GC will occur, does that mean that if one session keeps getting extended, each time there is a 1% change that specific session will be cleaned up? Or does this mean that 1% of all existing sessions (as well as new ones) will trigger GC for all other existing sessions?
I'm pretty sure it's the latter, I just want to make sure.
The purpose of this question is that on our site, I want users to have long-term sessions (6 months). If 1% of all sessions trigger GC, then that effectively removes the purpose of having that long-term session, as GC will end up occurring every hour or two.
Every time a PHP script is executes and starts session there is a probability that it will sweep through the session folder killing off old session.
Cleanup will only delete sessions which were not accessed within a certain time. However PHP does not guarantee that the session WILL be destroyed within that time.
Your long-term session strategy should work just fine, but you might want to reduce 1% to something like 0.1%
Another thing to look out for is that operating system might clean up your /tmp folder during reboot so even if PHP won't do it.
last time I looked at the source each call to session_start() "rolled the dice" so to speak, using the divisor and probability. If you hit, then it would delete all files from the session.save_path
directory that were older than session.gc_maxlifetime
. I forget if it used modification or access time of the file, although it shouldn't matter in normal curcumstances because php overwrites the session file by default at the end of script execution, so mod and access times should almost always match very closely.
// Rough psuedo code of how php's session_start() function works regarding garbage collection.
function session_start() {
$percentChanceToGC = 100 * ini_get('session.gc_probability') / ini_get('session.session.gc_divisor');
$shouldDoGarbageCollection = rand(1, 100) < $percentChanceToGC;
if ($shouldDoGarbageCollection) {
$expiredCutoffTime = time() - ini_get('session.gc_maxlifetime');
foreach (scandir(ini_get('session.save_path')) as $sessionFile) {
if (filemtime($sessionFile) < $expiredCutoffTime) {
unlink($sessionFile);
}
}
}
// ... rest of code ....
}
I don't know how many session files you're going to end up having hang around if you want them to live for a minimum of 6 months. Consider it may take a little while for php to stat many thousands of files to determine their age. Maybe consider other options for durable storage of this data. Or you could disable php gc and just run a cron job to delete stale session files. Otherwise, that 1% of requests are gonna trigger gc and have to wait for php; in other words it could possibly lag.
I'm not an expert on this, but from reading the manual, I'd draw your attention to another setting, session.gc_maxlifetime
. From the docs:
session.gc_maxlifetime
specifies the number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Garbage collection may occur during session start (depending onsession.gc_probability
andsession.gc_divisor
).
So if you set this setting to a suitable value (60 * 60 * 24 * 365 / 2
for half a year, so 15768000
), then the appropriate data won't be eligible for garbage collection, no matter what the other settings are.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With