Skip to content

Session cleanup without Redis

Snipe-IT's default file-based session driver (Laravel's file driver) has built-in garbage collection, but it's probabilistic and can fall behind on real traffic, letting thousands of stale session files pile up in storage/framework/sessions. If you don't have Redis set up, here's how to keep that under control.

Delete session files older than the configured session lifetime on a schedule, independent of anything Laravel does internally:

bash
# /etc/cron.d/snipeit-session-gc
0 3 * * * root find /var/www/snipe-it/storage/framework/sessions/ -type f -mmin +180 -delete

Set -mmin a bit above whatever SESSION_LIFETIME is configured to (in minutes) so you don't delete live sessions. This is the safest option — one cron line, no app config changes, no risk of breaking active logins.

Don't use a shell glob on a large directory

sudo rm -rf storage/framework/sessions/* can fail with Argument list too long once enough files accumulate — the shell expands the glob into a single command line before rm ever runs, and hits the OS argument-length limit (ARG_MAX). find ... -delete avoids this because it removes files one at a time internally instead of passing them all as arguments. If you hit this error, it's also a sign sessions have been accumulating for a long time without ever being pruned.

Option B: tighten Laravel's own GC settings

In .env:

SESSION_LIFETIME=120

Shorter lifetime means files expire and get swept sooner. In config/session.php:

php
'lottery' => [2, 100], // default: 2% chance per request to trigger GC

Lowering the second number raises GC frequency (e.g. [1, 20] = 5% chance per request). Treat this as a supplement to Option A, not a replacement — on a low-traffic instance the lottery may rarely fire even as files accumulate.

Option C: switch to the database session driver

Trades a directory of small files for one growing table, which is easier to monitor and prune:

# .env
SESSION_DRIVER=database

Create the sessions table if it doesn't already exist:

bash
php artisan session:table
php artisan migrate

Then prune old rows the same way you'd prune any table:

sql
DELETE FROM sessions WHERE last_activity < UNIX_TIMESTAMP(NOW() - INTERVAL 3 HOUR);

Still no Redis required, and avoids ever hitting the ARG_MAX failure mode above since you're not globbing a directory.

Which to use

Start with Option A — it's a single cron line and carries no risk. Layer Option B on top as a config tweak. Reach for Option C if you want something more robust than flat files without taking on Redis. See Redis setup on Debian if you're ready to move sessions and cache off the filesystem entirely.