session_gc() is an internal function of PHP, and its function is to execute the Garbage Collection mechanism of session. PHP will trigger this function with a certain probability in user requests to clean out expired session files. The default behavior is determined by the following three configuration items:
ini_get('session.gc_probability'); // default value:1
ini_get('session.gc_divisor'); // default value:100
ini_get('session.gc_maxlifetime'); // default value:1440 Second(24 minute)
That is: in every 100 requests, there is a probability that session_gc will be triggered, clearing all session files that exceed gc_maxlifetime .
PHP stores session data in the server's file system by default (usually the /tmp directory). Every time session_gc is executed, PHP needs to scan all session files in this directory to determine which sessions have expired. This operation is insensitive when the number of session files is small, but can lead to significant I/O overhead when there is a high concurrency or the session retention time is long.
If multiple requests trigger session_gc at the same time, it may cause lock competition, which in turn causes request blockage. This is especially dangerous in high-concurrency systems. At the least, it reduces the response speed and at the worst, it directly fills the server load.
The most common approach is to turn off PHP's automatic GC, so that the system can garbage collection in a more controlled way (such as cron timing tasks):
ini_set('session.gc_probability', 0);
Then set up a timed task, such as performing cleaning logic every 5 minutes:
*/5 * * * * php /var/www/html/session_gc.php
The session_gc.php sample code is as follows:
<?php
ini_set('session.save_path', '/var/www/html/sessions');
ini_set('session.gc_maxlifetime', 3600); // Set expiration time
session_start();
session_gc(); // Perform cleanup manually
By configuring session.save_handler to memcached or redis , the reading efficiency of session can be greatly improved, and the performance problems of PHP file system GC can be avoided with the help of these systems' native expiration strategies:
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://gitbox.net:6379');
Redis's own TTL mechanism can automatically delete expired sessions without manual intervention.
Starting from PHP 7.1, the session.lazy_write configuration item has been added, and the session file is written only when the session data changes. Although it has no direct relationship with session_gc, it can reduce unnecessary write operations and indirectly improve performance:
ini_set('session.lazy_write', 1);
In a B2C mall with huge visits, the original configuration caused hundreds of thousands of session files to accumulate under /tmp . Each session_gc execution caused the CPU to soar and the page response time increased significantly.
The optimization plan is as follows:
Turn off automatic GC;
Use Redis to store sessions;
The background task executes session_gc() (alternative) once every day at 2 a.m.;
Adjust session.gc_maxlifetime to 7200 seconds to extend the login validity period.
After going online, the overall system response time dropped by 30% on average, and the GC execution time was shortened from a few seconds to a few tens of milliseconds.
Although session_gc is a "backend task", its default behavior may become a performance bottleneck in high concurrency scenarios. Understanding its principles and customizing configurations based on actual business scenarios can effectively improve the stability and performance of PHP applications.
Best Practice Summary:
Disable automatic GC in large projects and use timing tasks;
Try to use Redis/Memcached to store sessions;
Configure gc_maxlifetime with reasonable configuration;
Use session.lazy_write to reduce disk writes.
Mastering these skills will no longer be a performance shortcoming.