Index in-memory session expiration deadlines - #7062
Conversation
Greptile SummaryThis PR replaces repeated full scans of retained in-memory sessions with a bounded deadline heap and reverse index.
Confidence Score: 5/5The PR appears safe to merge with no actionable correctness, security, or repository-rule issues identified. The heap and reverse index remain synchronized across refresh, purge, locked-token restoration, and fallback rebuild paths, while the added tests cover the principal ordering and batch-processing risks.
|
| Filename | Overview |
|---|---|
| reflex/istate/manager/memory.py | Adds consistent indexed expiration bookkeeping while preserving existing lock and worker scheduling semantics. |
| tests/units/istate/manager/test_expiration.py | Adds broad regression coverage for deadline reordering, removal, locked sessions, randomized sequences, and bounded fallback behavior. |
| tests/benchmarks/test_memory_expiration.py | Adds benchmarks for earliest-deadline lookup, rotating refreshes, and bulk due or locked-session batches. |
| news/+memory-expiration-index.performance.md | Concisely documents the downstream performance improvement. |
Reviews (1): Last reviewed commit: "Index in-memory session expiration deadl..." | Re-trigger Greptile
Merging this PR will not alter performance
Performance Changes
Comparing Footnotes
|
The memory state manager scans every retained session to find the next expiration. Index deadlines with one heap entry per session, update entries in place on refresh, and retain the existing lock and expiration semantics. When many entries are due or locked, cap heap work and use a linear scan plus index rebuild so a large batch remains O(N).
In an isolated replay of 10,000 staggered expirations, aggregate cleanup CPU fell from 4,583 ms to 15.23 ms. Looking up the next deadline with no sessions due also avoids the full scan. These are manager microbenchmarks against main on Python 3.14.5 / Apple M5 Pro, not request-latency measurements.
The index has costs worth reviewing separately: at 10,000 sessions, rotating refreshes increased from 0.132 to 1.371 Β΅s, and traced bookkeeping grew by 1.11 MB. A batch with every session due took 1.89 β 3.12 ms; a batch with every lock held took 0.71 β 2.85 ms. The bounded fallback limits those batch costs but does not eliminate them.
Validation:
Independent of the other performance drafts; based directly on main.