PHP sessions directory keeps filling until overflowing

I have a problem with my PHP session data folder. It seems to not be expiring sessions and has hit some sort of limit, presumably the filesystem limit for files in a directory. Requests that involve writing sessions fail with fatal error due to not enough disk space.

I have temporarily worked around it by pointing the sessions.save_path to a new directory.

Would like to know what is wrong with my php.ini that is preventing sessions being expired.

Also I tried truncating the sessions directory using rm but it just seems to hang forever?

Problem directory:

drwxr-xr-x  2 www-data www-data 294215680 Jan  5 13:42 sessions

Session section of php.ini:

[Session]
session.save_handler = files
session.save_path = "N;/var/www/data/sessions"
session.use_strict_mode = 0
session.use_cookies = 1
session.use_only_cookies = 1
session.name = PHPSESSID
session.auto_start = 0
session.cookie_lifetime = 2592000
session.cookie_path = /
session.cookie_domain =
session.cookie_httponly =
session.serialize_handler = php
session.gc_probability = 0
session.gc_divisor = 1000
session.gc_maxlifetime = 1440
session.referer_check =
session.cache_limiter = nocache
session.cache_expire = 180
session.use_trans_sid = 0
session.hash_function = 0
session.hash_bits_per_character = 5

Solution 1:

session.save_path = "N;/var/www/data/sessions"

The doesn't seem to be causing a problem (as PHP is obviously generating sessions), but isn't right.

The two formats for this option are:

/path/to/sessions
N;/path/to/sessions

The integer N defines how many sub-directories to create under the specified path, useful to spread the session files out over lots of directories if you expect a lot of session files. (You've already discovered that systems don't like lots of files in one directory...)

session.gc_probability = 0

This is most likely the main problem (unless PHP automatically handles someone setting this incorrectly to 0)

The probability that the cleanup will happen is defined by probability/divisor. 0/1000 is 0 so will likely never run.

Edit: Regarding deleting the files, you may just have to wait for it to finish. If it's millions of files it probably will seem like it's hanging.

Solution 2:

You need a cron job to clean the session files, they are not being cleaned by themselves. Ubuntu/Debian have a script (/etc/cron.d/php) to do the cleanup automatically.

If you don't have such script, put find /var/www/data/sessions -cmin +1440 -print0 | xargs -0 -r rm on a cronjob.

It will clean files 24 hours older or more.