Session timeouts in PHP: best practices

I spent some time looking for a good answer to how the php.ini server settings make
sessions expire. I found a lot of info but it took a while to figure out why
the settings work the way they do. If you’re like me, this might be helpful to you:

Sessions are stored as cookies (files on the client’s pc) or server side as files
on the server. Both methods have advantages and disadvantages.

For the sessions stored on the server, three variables are used.

session.gc_probability
session.gc_divisor
session.gc_maxlifetime

(session.gc_probability/session.gc_divisor) produces the probability that the
garbage collection routine will run. When the garbage collector runs, it
checks for session files that haven’t been accessed for at least session.gc_maxlifetime
and deletes them.

This is all explained pretty well in forum posts (this one especially!) – But the
following questions do come up:

1.) How is that probability applied? When does the server roll the dice?

A: The server rolls the dice every time session_start() is called during
any active session on the server. So this means you should see the garbage
collector run roughly once for every 100 times that session_start() is called
if you have the default of session.gc_probability = 1 and session.gc_divisor = 100

2.) What happens on low volume servers?

A: When session_start() is called it FIRST refreshes the session and makes the
session values available to you. This updates the time on your session file on the
server. It THEN rolls the dice and if it wins (1 out of 100 chance) it calls the garbage collector. The garbage collector then checks all session id files and sees if there are
any that are eligible for deletion.

So this means that if you are the only person on the server, your session will
never go inactive and it will appear as though changing the settings have no
effect. Let’s say you change session.gc_maxlifetime to 10 and session.gc_probability
to 100. This means there is a 100% chance the garbage collector will run and it
will clear out any session files that haven’t been accessed in the last 10 seconds.

If you’re the only one on the server, your session will not be deleted. You need
at least 1 other active session running for yours to go inactive.

So basically, on a low volume server or at a low volume time – it could be MUCH
longer than session.gc_maxlifetime before the garbage collector actually runs and
the sessions are actually deleted. And without knowing how this works, it may
appear completely random to you.

3.) Why do they use the probability?

A: Performance. On a higher volume server you don’t want the garbage collector
running on every request of session_start(). It will slow down the server
needlessly. So depending on your server volume, you may want to increase
or decrease the probability that the garbage collector runs.

I hope that this ties things together for you. If you’re like me and you tried
session.gc_maxlifetime and it didn’t seem to work (because you tried it
out on a development server so as not to disturb anyone), then this post
hopefully saved you some head scratching.

Good luck!

Leave a Comment