Skip to main content

RoTTL — Rotating TTL Data Structures

RoTTL provides memory-efficient rotating sets, dicts, and Bloom filters with approximate TTL-based eviction.

Rather than maintaining per-item expiry timestamps, the TTL window is divided into a fixed number of rotating buckets — expired buckets are evicted as a whole, trading per-item precision for significantly lower memory usage and faster writes, at the cost of sequential bucket scans.

Installation

pip install rottl

The only dependency is rbloom. If you encounter installation issues, refer to their documentation.

Quickstart

  • RotatingTTLSet — exact membership tracking backed by native Python set buckets.
from rottl import RotatingTTLSet

seen_ids = RotatingTTLSet(
    ttl=24 * 60 * 60, num_buckets=6, bucket_capacity=1_000_000
)
seen_ids.add("user_42")
print("user_42" in seen_ids)  # True
  • RotatingTTLDict — key-value storage backed by native Python dict buckets.
from rottl import RotatingTTLDict

response_cache = RotatingTTLDict(
    ttl=60 * 60, num_buckets=4, bucket_capacity=10_000
)
response_cache["GET /api/status"] = {"ok": True}
print(response_cache.get("GET /api/status"))  # {'ok': True}
  • RotatingTTLBloom — probabilistic membership tracking backed by rbloom.Bloom buckets.
from rottl import RotatingTTLBloom

visited_urls = RotatingTTLBloom(
    ttl=7 * 24 * 60 * 60, num_buckets=7, bucket_capacity=10_000_000, bucket_fpr=0.001
)
visited_urls.add("https://example.com")
print("https://example.com" in visited_urls)  # True

All three structures rotate automatically based on time and capacity, though capacity tracking differs between implementations:

  • RotatingTTLSet and RotatingTTLDict: Capacity is checked inline on every insertion via an $O(1)$ len() call.
  • RotatingTTLBloom: Estimating the number of unique inserted items requires inspecting filter occupancy by counting set bits — an $O(M)$ operation. To keep the hot path $O(1)$ for the vast majority of insertions, capacity is managed via an amortized countdown that defers the check.

When to use RoTTL

  • Approximate TTL is acceptable. Expiry happens at bucket boundaries, not per item. Under normal load (no capacity-based eviction), items live between ttl - (ttl / num_buckets) and ttl seconds. Capacity pressure can cause earlier eviction. Setting bucket_ttl_jitter_ratio further reduces the minimum, but helps avoid synchronized eviction spikes across instances.
  • Memory-constrained environments. RoTTL's bucket-level eviction avoids per-item bookkeeping, keeping structure overhead proportional to bucket count rather than item count.
    • RotatingTTLDict uses roughly 3–4× less memory than cachetools.TTLCache.
  • Write-heavy workloads. RoTTL's write path is lightweight — no per-item expiry metadata is maintained on insertion.
    • RotatingTTLDict is 6–15× faster than cachetools.TTLCache on insertions (varies by fast-reject usage and rotation pressure).
  • Lookup performance scales with configuration. Lookups scan up to num_buckets buckets, so with a small bucket count the overhead is negligible. With a large bucket count, hit cost depends on which bucket the item is found in, and miss cost grows linearly. RotatingTTLSet and RotatingTTLDict's history fast-reject option makes most miss latency independent of num_buckets, at the cost of slower rotations.

Advanced Usage

Because eviction happens at the bucket level, a rotation event drops all items in that bucket at once. In deployments with multiple instances — such as Kubernetes pods — all instances initialized around the same time will rotate in lockstep, causing simultaneous cache drops across the fleet. bucket_ttl_jitter_ratio addresses this by randomly shortening each bucket's TTL by up to ratio * bucket_ttl seconds on rotation, spreading eviction events out over time.

RotatingTTLSet and RotatingTTLDict support an optional history fast-reject mode, which maintains an auxiliary Bloom filter over all non-expired historical buckets. This allows most negative lookups to be rejected without scanning the full bucket deque, at the cost of filter rebuild on each rotation.

Metadata

Release files for rottl 0.0.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rottl 0.0.5
File Size Uploaded
rottl-0.0.5.tar.gz 12.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for rottl 0.0.5
File Interpreter ABI Platform
rottl-0.0.5-py3-none-any.whl Python 3 none any Details

Total release size: 22.9 kB

Release files / rottl-0.0.5.tar.gz

Download URL rottl-0.0.5.tar.gz
Size 12.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a8b7ac843ca8be91235263c83b2cecdffa8773465b267a86c1509dfb4d692fd9
BLAKE2b-256 checksum
How to use checksums
585bff52594a99669cf05485b47e616def51f24182b64b50e083b7c5889a8ba4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Release files / rottl-0.0.5-py3-none-any.whl

Download URL rottl-0.0.5-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0fbf5588d7d4506a4aa593d4a4e5946cedc078cd9766586a2dad3934f050d167
BLAKE2b-256 checksum
How to use checksums
767adabe9e810979da30254f10b7ca7e43eb223765601e600a2ff29e5cddd9cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 17, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.5 This release

2 release files

0.0.4

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page