Skip to content

Index in-memory session expiration deadlines - #7062

Draft
Alek99 wants to merge 1 commit into
mainfrom
codex/perf-memory-expiration-index
Draft

Index in-memory session expiration deadlines#7062
Alek99 wants to merge 1 commit into
mainfrom
codex/perf-memory-expiration-index

Conversation

@Alek99

@Alek99 Alek99 commented Sep 7, 2026

Copy link
Copy Markdown
Member

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:

  • Full unit suite: 8,307 passed, 18 skipped, 76.01% coverage; 59 focused expiration tests passed.
  • Regressions cover held locks, deadline refresh/removal, bounded index storage, randomized deadline sequences, and coalesced expiration/lock batches.
  • CodSpeed cases cover deadline lookup, rotating refreshes and bulk/held batches. Repository-wide Ruff and Pyright passed.

Independent of the other performance drafts; based directly on main.

Review in cubic

@greptile-apps

greptile-apps Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces repeated full scans of retained in-memory sessions with a bounded deadline heap and reverse index.

  • Updates deadlines in place when sessions are refreshed.
  • Falls back to a linear scan and index rebuild for large due or locked batches.
  • Adds randomized correctness, lock-handling, bounded-storage, batch-work, and performance coverage.
  • Adds a user-facing performance news fragment.

Confidence Score: 5/5

The 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.

Important Files Changed

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

@codspeed-hq

codspeed-hq Bot commented Sep 7, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

βœ… 32 untouched benchmarks
πŸ†• 12 new benchmarks
⏩ 8 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
πŸ†• test_memory_expiration_batches[all_due-1000] N/A 8.1 ms N/A
πŸ†• test_memory_expiration_batches[all_due-10000] N/A 84.4 ms N/A
πŸ†• test_memory_expiration_batches[all_held-1000] N/A 4.3 ms N/A
πŸ†• test_memory_expiration_batches[all_held-10000] N/A 44.3 ms N/A
πŸ†• test_memory_expiration_batches[half_due-1000] N/A 6.4 ms N/A
πŸ†• test_memory_expiration_batches[half_due-10000] N/A 64.4 ms N/A
πŸ†• test_memory_expiration_batches[held_and_future-1000] N/A 4.3 ms N/A
πŸ†• test_memory_expiration_batches[held_and_future-10000] N/A 43.6 ms N/A
πŸ†• test_next_memory_expiration[1000] N/A 22.8 Β΅s N/A
πŸ†• test_next_memory_expiration[10000] N/A 24.8 Β΅s N/A
πŸ†• test_refresh_memory_expiration[1000] N/A 54.9 Β΅s N/A
πŸ†• test_refresh_memory_expiration[10000] N/A 57.2 Β΅s N/A

Comparing codex/perf-memory-expiration-index (33d13c7) with main (c49a85d)

Open in CodSpeed

Footnotes

  1. 8 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant