Setting a dedicated PHP session directory keeps file-backed session data out of shared temporary locations and makes permissions, cleanup, and per-application isolation easier to control. That matters on shared hosts, multi-pool PHP-FPM deployments, and any stack where session files should stay with the application instead of blending into general-purpose temporary storage.

When session.save_handler is files, PHP writes one sess_* file per active session under the directory resolved by session.save_path. The effective value can come from the main php.ini file, scanned .ini fragments, PHP-FPM pool directives, web-server FastCGI overrides, per-directory .user.ini files, or application code, so the final check has to come from the same web-facing runtime that serves the site.

The new path also needs ownership and permissions that match the runtime user, and session expiry needs a cleanup path that still reaches the new directory. Some hosts run garbage collection during requests while others rely on an OS-level timer or cron job, so a pool-specific override may need matching cleanup logic. Separate directories are also safer when different pools or applications use different owners or session.gc_maxlifetime values.

Steps to set the PHP session save path:

  1. Identify the loaded PHP-FPM php.ini file and confirm that the runtime still uses the file-backed session handler.
    $ php-fpm8.3 -i | grep -E 'Loaded Configuration File|^(session.gc_probability|session.save_handler|session.save_path) =>'
    Loaded Configuration File => /etc/php/8.3/fpm/php.ini
    session.gc_probability => 0 => 0
    session.save_handler => files => files
    session.save_path => /var/lib/php/sessions => /var/lib/php/sessions

    Use php-fpm instead of php-fpm8.3 when the local binary is not versioned. The php --ri session and php --ini commands only report the CLI SAPI, which can differ from the runtime that serves web requests.

    If session.gc_probability is 0, old sessions may be cleaned by a distro timer or cron job instead of request-time garbage collection.

    If the handler is already redis, memcached, or another non-files backend, changing session.save_path will not move the active session store.

  2. Search PHP-FPM pool files for session overrides before changing the global php.ini value.
    $ sudo grep -REn 'php_(admin_)?value\[(session.save_path|session.save_handler|session.gc_maxlifetime)\]' /etc/php/8.3/fpm/pool.d
    /etc/php/8.3/fpm/pool.d/www.conf:492:php_admin_value[session.save_path] = /var/lib/php/www-session

    No output means the pool files are not overriding these directives. If a pool file already sets session.save_path, update that pool instead of assuming the global php.ini controls the site.

    When the host relies on a timer or cron job for old-session cleanup, confirm that job follows the new directory if the path is changed only in a pool override.

  3. Back up the active php.ini file before editing it.
    $ sudo cp /etc/php/8.3/fpm/php.ini /etc/php/8.3/fpm/php.ini.bak-$(date +%Y%m%d%H%M%S)
  4. Create a dedicated session directory with ownership and permissions that match the runtime user.
    $ sudo install -d -m 700 -o www-data -g www-data /var/lib/php/app-session
    $ ls -ld /var/lib/php/app-session
    drwx------ 2 www-data www-data 4096 Mar 25 23:03 /var/lib/php/app-session

    Avoid broad locations such as /tmp on multi-user hosts because another local account could read or replace session files there.

    Use a separate directory per pool or application when owners, group permissions, or session.gc_maxlifetime differ.

  5. Open the active php.ini file and set session.save_path to the dedicated directory.
    $ sudoedit /etc/php/8.3/fpm/php.ini
    session.save_path = "/var/lib/php/app-session"

    Keep the setting in the FPM php.ini or a scanned conf.d file when the host cleanup routine needs to discover the custom path automatically. Use a pool override only when the change must stay pool-specific.

    The optional N;MODE;/path format changes directory depth and file mode. Keep the value quoted when semicolons are present, and remember that automatic garbage collection does not run when N is greater than 0.

  6. Test the PHP-FPM configuration before reloading the service.
    $ sudo php-fpm8.3 -t
    [25-Mar-2026 23:03:10] NOTICE: configuration file /etc/php/8.3/fpm/php-fpm.conf test is successful

    Do not reload the service until the configuration test succeeds.

  7. Reload the runtime that serves the application so new workers read the updated directive.
    $ sudo systemctl reload php8.3-fpm

    Use the matching unit name for the installed package, such as php-fpm on many Fedora, Red Hat, or CentOS Stream hosts. Reload Apache instead when PHP runs as an Apache module, and skip the service reload entirely for a CLI-only change.

  8. Create a temporary probe script in the document root served by the edited runtime.
    $ sudo tee /var/www/example.com/public/session-path-check.php >/dev/null <<'PHP'
    <?php
    session_start();
    header('Content-Type: text/plain');
    echo session_save_path(), PHP_EOL;
    PHP

    Replace /var/www/example.com/public with the document root for the site that uses this pool. Using a web request for the final check confirms the same SAPI, pool, and FastCGI overrides that serve live traffic.

    Remove the probe file after verification so session configuration details are not left exposed over HTTP.

  9. Request the probe script and confirm that the reported path and created sess_* file both point to the new directory.
    $ curl -s http://example.com/session-path-check.php
    /var/lib/php/app-session
    
    $ find /var/lib/php/app-session -maxdepth 1 -type f -name 'sess_*'
    /var/lib/php/app-session/sess_d83e17r0qssa74fsi7vc2chtei

    If the returned path is still the old value, check for a pool override, a web-server PHP_VALUE or PHP_ADMIN_VALUE directive, a .user.ini entry, or application code that calls session_save_path() or ini_set() before session_start().

  10. Remove the temporary probe file after the check succeeds.
    $ sudo rm /var/www/example.com/public/session-path-check.php