HOWTO · PHP

How to Set Session Timeout in PHP

Learn how to track PHP session activity and enforce a 30-minute inactivity timeout on each request.

On this page

PHP does not expire an application session after a chosen period of inactivity automatically. To enforce a 30-minute timeout, store the time of the last request in $_SESSION, compare it with the current time on each request, and take action when the difference reaches or exceeds 1,800 seconds. The timeout is observed on the next request after the idle period; the server cannot act at the instant a browser stops sending requests.

How to Track a PHP Session Timeout

Call session_start() before reading or changing $_SESSION. On the first request, there is no saved activity time, so initialize it. On later requests, compare the saved time with time(). If the 1,800-second limit is reached, clear the session data and end the request; otherwise, refresh the activity time so the 30-minute period starts again.

Run this example:

<?php
session_start();

$timeoutSeconds = 30 * 60;
$now = time();

if (isset($_SESSION['last_activity']) &&
    $now - $_SESSION['last_activity'] >= $timeoutSeconds) {
    session_unset();
    session_destroy();
    echo "Session expired" . PHP_EOL;
    exit;
}

$_SESSION['last_activity'] = $now;
echo "Session active" . PHP_EOL;
Session active

The first request initializes last_activity and follows the active path. Each subsequent request checks the previous timestamp before updating it. The supplied execution evidence reports Session active with exit code 0 for the active path. It does not show the expired path being executed. In an application, put this check after session_start() and before protected work so an expired request is not processed as authenticated.

Destroy a Session After 30 Minutes of Inactivity

The example uses both session_unset() and session_destroy() when the timeout has elapsed. session_unset() removes the current session variables, while session_destroy() removes the session data stored by the active session handler. Destroying server-side data does not by itself remove the session cookie from the browser. If the application needs to expire that cookie too, it must send an expired cookie using the same name, path, and domain settings; cookie handling depends on the application’s session configuration.

This is an application-level timeout: it runs only when a request reaches code that performs the check. PHP’s session storage lifetime settings govern storage cleanup and are separate from this per-request inactivity policy. See the PHP Manual for session_unset() and the session configuration options.

Remove a Session Variable with unset()

Use unset($_SESSION['cart']) to remove one entry while leaving other session entries available. This is appropriate when a user removes a particular piece of state, such as a cart, without ending the whole session. It does not implement an inactivity timeout by itself. For a group of related values, store them under an array key and remove only that key with unset($_SESSION['account_state']); do not replace the array with a timestamp if the later timeout check expects a registered element.

The $_SESSION superglobal is available after session_start(). See the PHP Manual for $_SESSION.

Regenerate a Session ID Separately from Timeout Handling

session_regenerate_id() replaces the current session identifier; it does not measure inactivity, destroy session data, or automatically require the user to log in again. Use it for an identifier-rotation policy at an appropriate point in the application’s authentication flow, independently of the timeout check. Whether old session data is retained depends on the function’s options and session handling, so do not treat regeneration alone as logout or as proof that a previous identifier is unusable.

The session_id() function reads the current identifier, while session_start() resumes the session associated with the request. For details, consult the PHP Manual for session_regenerate_id() and the session_id() function.