cache.cache_entry
On this page
CacheEntry
@dataclass
class CacheEntry:
key: str
value: Any
created_at: float
last_access: float
hits: int = 0
ttl: Optional[float] = None
size_bytes: int = 0
Overview
The simple entry type used exclusively by MultiLevelCache. Unlike
IntelligentCacheEntry, it has no notion of tenants,
embeddings, or RL state — it exists purely to track a value plus enough metadata (hits, age,
idle time, size, TTL) to support eviction-strategy decisions and stats reporting.
A module-level config = CacheConfig() instance is created at import time and used only as
a source for the default fallback size_bytes value (config.size_bytes, 1024 by
default) when automatic size estimation fails.
[!WARNING] Contains Arabic/English bilingual comments The source file's docstrings and inline comments are bilingual (Arabic and English), reflecting the project's origin. This does not affect behavior, but is worth knowing when reading the raw source alongside this documentation.
Constructor / fields
__post_init__(self) -> None
If size_bytes == 0, calls _calculate_size() and stores the result.
_calculate_size(self) -> int
Attempts len(pickle.dumps(self.value)). If pickling fails for any reason (unpicklable
value), falls back to the module-level config.size_bytes default (1024).
[!NOTE] Every
CacheEntryis pickled at least once, just to measure it Even values that are never actually written to disk (L1/L2 entries) are serialized withpickle.dumpspurely to estimate their size in bytes, unlesssize_bytesis passed explicitly. For very large or expensive-to-pickle values, this has a real per-set()cost — see Known Issues.
Methods
Examples
from zerda.cache import CacheEntry
import time
entry = CacheEntry(key="user:42", value={"name": "Ada"}, ttl=60)
print(entry) # CacheEntry(key='user:42', hits=0, age=0.0s, status=valid)
entry.increment_hits()
print(entry.get_stats())
time.sleep(61)
print(entry.is_expired()) # True
Complexity
All methods are O(1) except _calculate_size(), which is O(size of value) due to
pickling.
Thread Safety
CacheEntry itself has no locking — it is a plain mutable dataclass. Thread safety is the
responsibility of its owner, MultiLevelCache, which guards all
access with self.lock.
Best Practices
- Pass
size_bytesexplicitly when constructing entries for very large or slow-to-pickle values, to avoid the implicitpickle.dumpssize-estimation cost. - Don't mutate
hits/last_accessdirectly from outsideMultiLevelCache— useincrement_hits()so both stay in sync.
Related APIs
MultiLevelCache— the sole consumer of this classCacheMetrics— records hit/miss counters alongside these entriesIntelligentCacheEntry— the unrelated, more complex entry type used by the semantic-cache pipeline