Does Yii's default file session handler cause concurrent request latency only when writing to session?
0 reputation · 30 Nov 2021, 20:33 UTC
0 reputation · 30 Nov 2021, 20:33 UTC
Goal: determine whether the extra latency observed under concurrent requests in a Yii application stems solely from write operations to the default file‑based session handler, or whether read‑only session accesses also trigger the same blocking behavior.
With Yii’s default file session component, each request locks the session file for its whole duration, causing subsequent requests that touch the session to wait. It is not documented whether the lock is taken only when the session is written to, or also when it is merely read, and whether disabling auto‑start or initiating the session after the first read changes the lock timing. This uncertainty makes it hard to decide if a custom handler is required for read‑only workloads.
Does a read‑only session still block other requests? Does disabling auto‑start and starting the session lazily after the first read eliminate the lock? Is the latency proportional to the amount of data written to the session?
32775 reputation · 30 Nov 2021, 22:37 UTC
Yes, a read-only session still blocks other requests. In Yii's default configuration, latency is not caused by the write operation itself, but by the exclusive lock acquired the moment the session is opened. Any concurrent request attempting to access the same session ID will queue and wait until the first request releases that lock.
Yii typically relies on PHP's native files session handler. To prevent data corruption from race conditions (where two requests modify the same session data simultaneously), PHP implements a locking mechanism:
session_start() is called, PHP opens the session file and places an exclusive lock on it.session_start(). Because the first request holds the lock, the second request pauses execution entirely until the lock is available.session_write_close() is explicitly called.Disabling auto-start or initiating the session lazily does not eliminate the lock; it only defers it. The blocking behavior begins the instant the session is started, regardless of whether you intend to read or write data. If you delay the session start until the end of a request, you avoid blocking other requests for the duration of the page load, but you lose access to session data during the request.
The latency observed is generally not proportional to the amount of data written. The delay is a result of the waiting period (the time the first request spends holding the lock), not the I/O time required to write the file to disk.
To verify this behavior in your environment, you can use a simple sleep test:
// In a controller action
public function actionTest() {
// Session starts automatically in Yii
sleep(10);
return "Finished";
}
If you trigger this action and immediately attempt to load another page in the same browser session, the second page will hang for 10 seconds.
session_write_close() (or the Yii equivalent via the session component) as soon as you no longer need to modify session data. This releases the lock for other concurrent requests.FileSession to DbSession or RedisSession. While some database handlers still implement locking, Redis-based handlers often provide more granular control or non-blocking options.Diagnostic Detail Needed: To provide a more specific configuration recommendation, please confirm if you are using the default yii\web\Session component or a custom session class.
Use comments to ask for clarification. Post a solution as an answer.
32,775 reputation · 01 Dec 2021, 03:08 UTC
PHP’s default files handler acquires an exclusive lock as soon as session_start() opens the session file, regardless of whether the script will only read or will later write. Yii simply calls session_start() in its session component, so the lock behavior is identical to plain PHP.
session_start() locks the file until it calls session_write_close() or the script ends.session_start() will block until the lock is released.session_write_close() immediately after you finish reading the session to release the lock early.session.auto_start (or configure Yii’s autoStart property) so the lock is not taken until you explicitly start the session.The lock duration depends on how long the script holds the session open, not on the amount of data written. Even a small write can block for the full request time if session_write_close() is delayed.