expiringdict

Thread-safe dictionary with auto-expiring keys — provides a dict subclass where entries automatically expire after a TTL. expiringdict features: ExpiringDict(max_len, max_age_seconds) constructor, standard dict interface (get/set/del/in/items/values), thread-safe via RLock, max_len for LRU-style eviction, max_age_seconds for TTL expiry, expired keys invisible on access (lazy expiry), copy() creates snapshot, and len() excludes expired entries. Simpler than cachetools TTLCache with fewer features but easier API.

Evaluated Mar 06, 2026 (0d ago) v1.2.x
Homepage ↗ Repo ↗ Developer Tools python expiringdict cache ttl dict expiry mailchimp
⚙ Agent Friendliness
65
/ 100
Can an agent use this?
🔒 Security
90
/ 100
Is it safe for agents?
⚡ Reliability
80
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
80
Error Messages
78
Auth Simplicity
99
Rate Limits
99

🔒 Security

TLS Enforcement
92
Auth Strength
92
Scope Granularity
90
Dep. Hygiene
92
Secret Handling
85

Pure Python in-memory dict with no network calls. Do not cache secrets beyond their required lifespan — set max_age_seconds to match secret TTL. Thread-safe via RLock. Expired entries still in memory until lazily cleaned — sensitive data may persist beyond TTL until accessed.

⚡ Reliability

Uptime/SLA
78
Version Stability
80
Breaking Changes
82
Error Recovery
82
AF Security Reliability

Best When

Simple TTL-expiring dict for rate limiting, deduplication windows, and short-lived session storage — expiringdict provides the simplest possible API for auto-expiring keys.

Avoid When

Complex eviction policies (use cachetools), high-throughput (use functools.lru_cache), or disk persistence (use cachelib).

Use Cases

  • Agent rate limiting tracker — from expiringdict import ExpiringDict; rate_tracker = ExpiringDict(max_len=10000, max_age_seconds=60); def check_rate(user_id): count = rate_tracker.get(user_id, 0); if count >= 100: raise RateLimitError(); rate_tracker[user_id] = count + 1 — rate limiting; agent tracks per-user request counts that reset after 60s automatically
  • Agent session token store — tokens = ExpiringDict(max_len=1000, max_age_seconds=3600); tokens[session_id] = user_data; user = tokens.get(session_id) — returns None if expired — session store; agent stores short-lived session tokens; expired tokens automatically invisible; no cleanup thread needed
  • Agent deduplication window — seen = ExpiringDict(max_len=50000, max_age_seconds=300); def is_duplicate(msg_id): if msg_id in seen: return True; seen[msg_id] = True; return False — dedup; agent deduplicates messages within 5-minute window; old IDs expire automatically; memory bounded by max_len
  • Agent cache with TTL — results = ExpiringDict(max_len=500, max_age_seconds=600); def get_result(key): cached = results.get(key); if cached is not None: return cached; result = expensive_compute(key); results[key] = result; return result — simple TTL cache; agent caches computation results for 10 minutes; simpler than cachetools for basic TTL
  • Agent connection pool health — health = ExpiringDict(max_len=100, max_age_seconds=30); health[endpoint] = True; if endpoint not in health: check_and_add() — freshness tracking; agent marks endpoints as healthy; entry expires after 30s forcing recheck; simpler than background health check threads

Not For

  • Complex eviction policies — expiringdict only does TTL+maxlen; for LRU, LFU, sized eviction use cachetools
  • High-performance caching — expiringdict is pure Python with per-access lock overhead; for high-throughput use cachetools or functools.lru_cache
  • Persistent caching — expiringdict is in-memory only; for persistence use cachelib or diskcache

Interface

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

No auth — in-memory data structure library.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

expiringdict is Apache 2.0 licensed. Free for all use.

Agent Metadata

Pagination
none
Idempotent
Full
Retry Guidance
Not documented

Known Gotchas

  • get() returns None for both missing AND expired — cannot distinguish expired from never-set; agent code: use cache.get(key) is None as cache miss indicator; do NOT store None as a valid value in expiringdict — ambiguous with cache miss; if None is needed as a value, use a sentinel: MISSING = object(); if cache.get(key, MISSING) is MISSING: compute
  • items() and values() include only non-expired at call time — expiringdict.items() filters expired entries; but entries can expire between items() call and iteration; agent code iterating items() should be aware of this race condition; for atomic snapshot: dict(expiringdict.items()) creates copy but still races
  • max_len eviction is approximate and FIFO-like — when max_len exceeded, oldest entries evicted (insertion order); not LRU; agent code assuming LRU behavior (most-used entries stay) will be surprised; expiringdict evicts oldest regardless of access frequency; for LRU behavior use cachetools.LRUCache instead
  • No bulk expiry or cleanup API — expiringdict has no expire_all() or cleanup() method; expired entries removed lazily on access; agent code needing immediate cleanup of all expired entries must iterate: [k for k in cache.keys()] to trigger lazy cleanup; or recreate the ExpiringDict
  • Thread safety via RLock not asyncio-safe — expiringdict uses threading.RLock; not safe for concurrent asyncio tasks in same event loop without additional sync; agent async code: use asyncio.Lock wrapping expiringdict access; or use per-task instances without sharing; RLock only protects threading.Thread concurrency
  • ExpiringDict is not a defaultdict — cache.get(key, default) returns default but does NOT store default in cache; agent code expecting cache population on get() miss must: value = cache.get(key); if value is None: value = compute(); cache[key] = value; returning default without storing is intentional but differs from defaultdict behavior

Alternatives

Full Evaluation Report

Comprehensive deep-dive: security analysis, reliability audit, agent experience review, cost modeling, competitive positioning, and improvement roadmap for expiringdict.

AI-powered analysis · PDF + markdown · Delivered within 30 minutes

$99

Package Brief

Quick verdict, integration guide, cost projections, gotchas with workarounds, and alternatives comparison.

Delivered within 10 minutes

$3

Score Monitoring

Get alerted when this package's AF, security, or reliability scores change significantly. Stay ahead of regressions.

Continuous monitoring

$3/mo

Scores are editorial opinions as of 2026-03-06.

5229
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered