Moodle sessions on Redis vs the database: lock behavior under concurrent requests
0 reputation · 19 Jul 2020, 13:36 UTC
0 reputation · 19 Jul 2020, 13:36 UTC
Moodle's documented session handling supports several backends, including the default database handler and optional Redis and Memcached handlers configured under Site administration > Server > Session handling. The documentation also describes an exclusive per-session lock that Moodle takes while serving a request, intended to prevent race conditions when one session is active in more than one request.
The goal is to decide whether moving session storage from the database to Redis changes the latency profile of pages that issue several parallel requests — for example, AJAX blocks or web-service calls — for the same logged-in user. The uncertainty is whether the Redis handler implements the same lock semantics as the database handler, or whether lock wait behavior, timeouts, and failure modes differ between handlers and across recent Moodle releases (4.x and 5.x).
Specific questions:
34775 reputation · 20 Jul 2020, 00:00 UTC
Yes — Moodle's Redis session handler still enforces an exclusive per-session lock, so parallel requests from one logged-in user serialize just as they do with the database handler. Moving to Redis changes where the lock lives and how it fails, not whether it exists. The latency profile of concurrent AJAX or web-service calls is therefore unlikely to improve from reduced lock contention; any gain comes from faster reads/writes once a request actually holds the lock.
Confirmed by design: Moodle's session manager takes an exclusive lock for the duration of a request and releases it at session_write_close(). The database handler implements this with a row lock; the Redis handler implements it with a lock key in Redis (a SETNX-style acquisition), released when the request ends.
Likely, but verify in your version: The Redis lock has a configurable acquisition timeout (commonly exposed as a redis.session.locking-style setting, with defaults in the tens-to-hundreds of seconds range depending on release). Unlike a database row lock — which dies with the transaction/request — a Redis lock key can outlive a crashed PHP process until its TTL expires. That is the main behavioral difference: a stalled or killed request under Redis can block the session for the full lock TTL, whereas the database lock is released by the connection closing.
Memcached: has no native locking primitive; Moodle emulates locking with a key, and the semantics are weaker. For high per-user concurrency, Memcached is the least safe choice of the three.
Moodle's admin documentation describes the exclusive session lock concept clearly but is thin on per-handler lock wait/timeout behavior, and the exact setting names and defaults have shifted across 4.x releases. Treat any specific default value (including the ones above) as needs verification against your installed version — check config.php and the handler source in lib/classes/session/ rather than relying on docs.
config.php for the session handler class and any Redis lock settings; confirm the handler isn't running in a lockless mode.for i in $(seq 1 8); do curl -b \"MoodleSession=...\" -s -o /dev/null -w '%{time_total}\\n' \"$URL\" & done; wait) against a slow page. Response times should stair-step, not overlap.Redis sessions will not unlock parallel requests for the same user — that serialization is intentional and handler-independent. Adopt Redis for scalability of session storage, not for concurrency relief, and only after confirming lock timeout headroom and orphaned-lock recovery in staging.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.