Skip to content

fix(memory): proactively flush expired entries after TTL - #759

Merged
pi0 merged 2 commits into
mainfrom
fix/mem-ttl
Mar 19, 2026
Merged

pi0 merged 2 commits into
mainfrom
fix/mem-ttl

Conversation

@pi0

@pi0 pi0 commented Mar 19, 2026 •

Copy link
Copy Markdown
Member

Summary

  • Schedule a setTimeout per TTL entry to proactively delete it from the internal Map when it expires
  • Prevents unbounded memory growth from entries that are never read again (e.g. unique URLs with varying query params)
  • Timers use .unref() so they don't prevent process exit
  • Previous timers for the same key are cleared on overwrite or delete

Ref unjs/ocache#10 nitrojs/nitro#2138

Test plan

  • Added regression test: stores entries with short TTL, waits for expiry without reading, verifies proactive cleanup
  • All existing memory driver tests pass

Summary by CodeRabbit

  • New Features

    • The in-memory driver now supports Time-to-Live (TTL) expiration for individual items, automatically removing items after a configured duration.
    • Expired items are proactively cleaned up and no longer accessible via storage queries.
  • Tests

    • Added regression tests validating TTL expiration behavior and automatic cleanup without requiring manual key reads.

Schedule a setTimeout per TTL entry to delete it from the internal Map
when it expires, preventing unbounded memory growth from entries that
are never read again (e.g. unique URLs with varying query params).

Closes nitrojs/nitro#2138
Ref unjs/ocache#10
@coderabbitai

coderabbitai Bot commented Mar 19, 2026 •

Copy link
Copy Markdown

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9338e45a-a883-4676-9696-978667f66b97

📥 Commits

Reviewing files that changed from the base of the PR and between e9bdc8b and 7ac54a3.

📒 Files selected for processing (2)
  • src/drivers/memory.ts
  • test/drivers/memory.test.ts

📝 Walkthrough

Walkthrough

Added per-key TTL support to the in-memory cache driver using a timers map. When setting items with optional TTL, existing timers are cleared and new expiry timers are scheduled to auto-delete keys. A regression test validates automatic expiration after TTL expires without explicit reads.

Changes

Cohort / File(s) Summary
In-memory TTL implementation
src/drivers/memory.ts
Added timers map to track expiry timers per key. Updated setItem and setItemRaw to accept optional opts with ttl parameter; clearing existing timers before scheduling new expiry timers. Updated removeItem, clear, and dispose to cancel and clean up timers.
TTL regression test
test/drivers/memory.test.ts
Added async test validating that items with short TTL (0.01s) are automatically removed from the in-memory driver after expiration, confirming proactive cleanup without requiring explicit reads.

Sequence Diagram

sequenceDiagram
    actor User
    participant Driver as Memory Driver
    participant Storage as Storage Map
    participant Timers as Timers Map
    participant Timer as Node Timer

    User->>Driver: setItem(key, value, {ttl: 0.01})
    Driver->>Timers: Check & clear existing timer
    alt Timer exists
        Timers->>Timer: clearTimeout()
    end
    Driver->>Storage: Store value
    Driver->>Timer: setTimeout(callback, 10ms)
    Timer->>Timers: Store timer reference
    Note over Driver: ~10ms delay
    Timer->>Driver: Timer fires (expiry callback)
    Driver->>Storage: Delete key
    Driver->>Timers: Remove timer reference
    Driver->>User: Confirm deletion
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A hopping tale of TTL grace,
Expired crumbs we've now erased!
Timers tick, then melt away,
No stale cache to clutter our day. ✨

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/mem-ttl
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@pi0
pi0 merged commit b5b0449 into main Mar 19, 2026
4 of 5 checks passed
@pi0
pi0 deleted the fix/mem-ttl branch March 19, 2026 13:41
@codecov

codecov Bot commented Mar 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.20690% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.81%. Comparing base (e9bdc8b) to head (7ac54a3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/drivers/memory.ts 86.20% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #759      +/-   ##
==========================================
+ Coverage   64.52%   64.81%   +0.29%     
==========================================
  Files          43       43              
  Lines        2207     2234      +27     
  Branches      520      523       +3     
==========================================
+ Hits         1424     1448      +24     
- Misses        675      678       +3     
  Partials      108      108              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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