Skip to main content

An ultra-fast local cache for Python, powered by Rust.

Project description

rust-py-cache

An ultra-fast local cache for Python, powered by Rust.

A local, in-memory, thread-safe cache with TTL, lazy expiration, and metrics. The core is written in Rust (PyO3 + maturin) on top of a concurrent DashMap; the Python API is minimal. Think of it as a "mini Redis" living inside your Python process.

PyPI Python License: MIT

🌐 Website: rust-py-cache.vercel.app

Installation

pip install rust-py-cache

To work on it locally (requires Rust + maturin):

python -m venv .venv && source .venv/bin/activate
pip install maturin pytest
maturin develop          # compiles the Rust core and installs into the venv
pytest                   # runs the tests

Usage

from rust_py_cache import Cache

cache = Cache()

cache.set("user:1", {"name": "Roberto"}, ttl=60)   # ttl in seconds
user = cache.get("user:1")                          # {"name": "Roberto"}
cache.get("missing", default=0)                     # 0

cache.exists("user:1")        # True (honors TTL)
cache.delete("user:1")        # True if removed, False if absent
cache.len()                   # approximate size
cache.keys()                  # list of keys
cache.cleanup_expired()       # remove expired entries; returns the count
cache.clear()                 # remove everything (keeps counters)
cache.stats()                 # {'hits','misses','sets','deletes','expired','evicted','size'}

Bounded cache with LRU eviction

# Cap the number of keys. When full and a new key arrives, evict the
# least-recently-used entry instead of rejecting the write.
cache = Cache(max_size=1000, eviction_policy="lru")
cache.eviction_policy            # "lru"

# Default policy is "reject": set() returns False when full (and the key is new).
cache = Cache(max_size=1000)     # eviction_policy="reject"
cache.set("a", 1)                # True / False

Background expiration

# A background thread reclaims expired entries every N seconds, so you don't
# have to call cleanup_expired() yourself. It stops when the cache is collected.
cache = Cache(cleanup_interval=30)   # seconds (int/float)

Memoization decorator

@cache.cached(ttl=60)
def add(a, b):
    return a + b

add(2, 3)   # runs and caches
add(2, 3)   # served from cache

# custom key (fixed string or callable):
@cache.cached(ttl=300, key=lambda user_id: f"user:{user_id}")
def load_user(user_id):
    ...

See full examples under examples/ (FastAPI and Django).

API

Constructor: Cache(max_size=None, eviction_policy="reject", cleanup_interval=None). eviction_policy must be "reject" or "lru" (any other value raises ValueError). cleanup_interval (seconds, > 0) enables the background sweeper.

Method Description
set(key, value, ttl=None) Store a value. ttl in seconds (int/float); None = no expiration; ttl <= 0ValueError. Overwrites. Returns True, or False when full under eviction_policy="reject" and the key is new.
get(key, default=None) The value, or default if missing/expired (expired entries are removed).
delete(key) True if removed, False if it didn't exist.
exists(key) True/False, honoring TTL.
keys() List of keys (may include expired-but-not-yet-collected ones).
len() / len(cache) Approximate size.
clear() Remove everything (does not reset counters).
cleanup_expired() Remove expired entries; returns how many.
eviction_policy (property) The active policy: "reject" or "lru".
stats() dict with hits, misses, sets, deletes, expired, evicted, size.
@cache.cached(ttl=None, key=None) Memoization decorator.

How it works

  • Serialization: in the MVP, values are serialized with pickle (on the Python side, via PyO3) and stored as opaque bytes (Vec<u8>) in the Rust core.
  • Concurrency: DashMap (a HashMap with per-shard locks) plus AtomicU64 counters, with no global lock on the hot path. Thread-safe, no busy loop.
  • TTL: expiration is lazy by default — an expired key is removed when accessed (get/exists) or via cleanup_expired(). Pass cleanup_interval to also run a background sweeper thread that reclaims expired keys on its own.
  • Eviction: with max_size + eviction_policy="lru", a full cache evicts the least-recently-used entry (recency updated on every get hit) to admit a new key.

Limitations

  • The cache is process-local: multiple workers = multiple independent caches.
  • It does not replace Redis for distributed caching.
  • Data is lost when the process restarts.
  • pickle must not be used to deserialize untrusted data.
  • Lazy TTL by default: without cleanup_interval, expired items may linger until accessed or until cleanup_expired() runs.

Development

cargo test          # Rust core tests
maturin develop     # rebuild and install
pytest              # Python tests

If maturin develop complains about both VIRTUAL_ENV and CONDA_PREFIX being set, run conda deactivate first, or use env -u CONDA_PREFIX maturin develop.

Roadmap

Stages and next steps (LRU/LFU eviction, background expiration, configurable serializer, namespaces, etc.) are in ROADMAP.md.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rust_py_cache-0.2.0.tar.gz (24.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rust_py_cache-0.2.0-cp310-abi3-win_amd64.whl (174.4 kB view details)

Uploaded CPython 3.10+Windows x86-64

rust_py_cache-0.2.0-cp310-abi3-manylinux_2_34_x86_64.whl (331.1 kB view details)

Uploaded CPython 3.10+manylinux: glibc 2.34+ x86-64

rust_py_cache-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (288.8 kB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file rust_py_cache-0.2.0.tar.gz.

File metadata

  • Download URL: rust_py_cache-0.2.0.tar.gz
  • Upload date:
  • Size: 24.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rust_py_cache-0.2.0.tar.gz
Algorithm Hash digest
SHA256 495ff1bcf096b02693fb17d986ba2a544aafcd70312d96e2d757fe57c409a950
MD5 d9460511f8346c1700c027cf4f820ed4
BLAKE2b-256 32374eed52bb2a3866f88828818061c849371ce4a455746a0253ac00fd7a4735

See more details on using hashes here.

Provenance

The following attestation bundles were made for rust_py_cache-0.2.0.tar.gz:

Publisher: release.yml on robertolima-dev/rust-py-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rust_py_cache-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for rust_py_cache-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 12ad33bd6bdc1b8cd31e404266be30bc7b875cefdaa436abf2117694df6a8aaf
MD5 18a9308fb5ac107a0104e2572f1725ba
BLAKE2b-256 8a2566cafb2129ce3d4c317993f336ee3299ff3409412b51aa5162be7a0c7219

See more details on using hashes here.

Provenance

The following attestation bundles were made for rust_py_cache-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: release.yml on robertolima-dev/rust-py-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rust_py_cache-0.2.0-cp310-abi3-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for rust_py_cache-0.2.0-cp310-abi3-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 698a8c13d9bec9bb3ac26eca03381788a572c9014f9d297fc503d8b11bfaa18e
MD5 741275137387a06567c88754dcd239b0
BLAKE2b-256 7a04955a01651488367f9171a51adb33b803d75e5fb48206a8999029672bfbd9

See more details on using hashes here.

Provenance

The following attestation bundles were made for rust_py_cache-0.2.0-cp310-abi3-manylinux_2_34_x86_64.whl:

Publisher: release.yml on robertolima-dev/rust-py-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rust_py_cache-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rust_py_cache-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 00bd06b984fec4222a893be65e42f89103d341045eb1339258eebaf3e8faaddc
MD5 a343ead62f380fe31622dded9845b486
BLAKE2b-256 ffcda868cd568cdc0b036e7a026af013a08e22e42727c0c946c2a781bf9d17cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for rust_py_cache-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on robertolima-dev/rust-py-cache

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page