PHP Session Performance & Locking
debt(d8/e3/b4/t7)
Closest to 'silent in production until users hit it' (d9), but Blackfire profiling or strace can reveal serialised requests, so d8. Not caught by static tools — only manifests under concurrent load.
Closest to 'simple parameterised fix' (e3). Quick fix is switching session handler config to Redis, or adding session_write_close() calls — small config change plus possibly a few strategic call sites.
Closest to 'localised tax' (b3) leaning toward b5. Session handling touches web context broadly but the choice is centralised in session config; storing large objects or relying on file locks can create persistent productivity tax for AJAX-heavy apps.
Closest to 'serious trap' (t7). Per misconception, devs assume sessions have no concurrency impact — the 'obvious' use (just call session_start) silently serialises AJAX requests, contradicting how sessions work in most other ecosystems.
Also Known As
TL;DR
Explanation
By default PHP stores sessions as files and acquires an exclusive flock() lock when session_start() is called. This serialises all concurrent requests from the same user — an AJAX-heavy page making 5 simultaneous requests will queue them, each waiting for the previous to call session_write_close(). Fixes: call session_write_close() as early as possible once session data is no longer needed; use session_start(['read_and_close' => true]) for read-only requests; switch to a Redis or Memcached session handler (configurable via session.save_handler) which supports more granular locking or lock-free read operations. Redis sessions also enable horizontal scaling across multiple PHP-FPM servers without sticky sessions.
Common Misconception
Why It Matters
Common Mistakes
- Using file-based sessions for applications with concurrent AJAX requests — each request waits for the session lock.
- Not calling session_write_close() early when session data is no longer needed in a long request.
- Storing large objects in sessions — every request deserialises the entire session payload.
- Not using Redis or Memcached sessions for multi-server deployments — file sessions are per-server.
Code Examples
session_start(); // lock held for entire request
$data = $_SESSION['user'];
expensiveOperation(); // session locked while this runs
session_start();
$data = $_SESSION['user'];
session_write_close(); // release lock immediately
expensiveOperation();