NimbusKV v3.1.0 README
Overview, architecture summary, installation, and usage as published on GitHub.
Reactive, TTL-aware, concurrent key/value store for Python - lock-free reads always, one short lock per write, correct on both standard GIL Python and free-threaded Python (3.13t/3.14t).
Free-threaded Python note: NimbusKV depends on immutables, whose C extension has not yet declared free-threading support, so importing it re-enables the GIL on 3.13t/3.14t. Run with PYTHON_GIL=0 (or python -X gil=0) to keep the GIL off. The NimbusKV test suite passes in that mode.
Renamed from livedict. If you're upgrading: pip uninstall livedict && pip install nimbuskv, then change from livedict import LiveDict to from nimbuskv import NimbusKV. The API is otherwise unchanged.
What changed in v3 (rewrite, not a patch)#
v2 was a TTL dict with callbacks and a fake "sandbox" - a recombination of things cachetools/aiocache already do better. v3 is a different architecture:
- Immutable-snapshot core - state lives as an immutable persistent snapshot (HAMT). Readers never lock, ever. Each write takes one short lock, builds the new snapshot from the current one and publishes it. (Up to v3.0.1 writers retried on conflict instead; under a hot key that turned into a retry storm, so it was replaced.)
- Adapts to the interpreter automatically - same code path on standard GIL Python and free-threaded Python (3.13t/3.14t). No mode flag; detected once at import time.
- Genuinely reactive -
subscribe()pushes every change (set/delete/expire) to callbacks, per-key or global. - Real async, not fake async - for the in-memory path,
aget/asetare truly non-blocking (norun_in_executorspent on work that was never I/O). When a persistence backend involves real I/O (SQLite/Redis), only that part is delegated to an executor. atomic()replaces v2's manuallock()/unlock()for compound read-modify-write (e.g. counters). Your function runs exactly once, under the write lock, so keep it short and don't write to the same store from inside it.- Persistence is a write-through mirror, not the source of truth - Memory (default), SQLite, or Redis. Reads never touch the backend; it only exists for durability and startup rehydration.
mset()/mget()- batch multiple keys into a single atomic swap (readers never see a partial update across related keys), plus a convenience multi-key read.wait_for()- block a thread until a condition on a key holds, driven by the subscription system, not polling. Built for producer/consumer coordination across threads.- Context manager support -
with NimbusKV() as ld:guarantees the scheduler and backend are cleanly stopped, even on exception. - TTL scheduler bugfix - rescheduling a key's TTL now correctly invalidates the old deadline via a generation counter, instead of leaving a stale heap entry behind.
py.typed- ships as a properly typed package (PEP 561); type checkers (mypy/pyright) will pick up the annotations.- Sandbox dropped for this release. v2's "sandbox" was a timeout wrapper, not real isolation, and calling it a sandbox was misleading. It was dropped rather than shipping something that doesn't do what its name claims.
Install#
bash
Works on Python 3.9+. For the lock-free write path, use a free-threaded build (3.13t/3.14t) - on standard GIL Python everything is still correct, just without the extra parallelism.
Quick usage#
python
TTL#
python
Reactive subscriptions#
python
Atomic compound updates (replaces manual locking)#
python
Batch operations#
python
wait_for - thread coordination without polling#
python
Context manager#
python
Async (genuinely non-blocking for the in-memory path)#
python
Persistence backends#
python
State is rehydrated from the backend on startup (already-expired keys are skipped).
Architecture#
Architecture Diagram (Source)graph TD A[NimbusKV public API] A --> B[ReactiveStore] B --> B1["in-memory, immutable-snapshot core"] B --> B2["readers: lock-free, always"] B --> B3["writers: one short lock,<br/>build + publish new snapshot"] A --> C[ExpiryScheduler] C --> C1["background thread, min-heap,<br/>fires TTL expiry against the store"] A --> D[PersistenceBackend] D --> D1["write-through mirror + startup rehydration"] D --> D2["NullBackend / SQLiteBackend / RedisBackend"]
Status#
v3.1.0 replaces the optimistic retry loop on the write path with a short lock and fixes several concurrency bugs (see CHANGELOG.md). Core, TTL, reactive subscriptions, atomic(), and all three persistence backends are implemented and tested for correctness (race-free under concurrent writers, verified with 10,000+ concurrent operations across 20 threads on standard Python - free-threaded benchmarks pending, to be published once run on a 3.14t interpreter).
We are constantly improving and adding features to the library to make it better with every version.
Documentation#
Full detailed docs, versioned:
docs/v3.1.0.md- current releasedocs/v3.0.1.md- previous releasedocs/v3.0.0.md- original release (includes a known-issue note for anyone still pinned to it)dev/API_REFERENCE.md- full generated API surface, straight from the docstrings
Development / Contributing#
bash
See CONTRIBUTING.md for guidelines, and the examples/ folder for runnable end-to-end scripts. Free-threaded (3.13t/3.14t) testing is run in CI, but if you have a free-threaded interpreter locally, running the suite there too is especially valuable - that's the runtime this library's core claim is actually about.
License#
NimbusKV is licensed under the Apache License 2.0. You can use it freely, including in commercial and closed-source products. If you redistribute it, keep the LICENSE and NOTICE files.
License change: versions up to and including 3.0.1 were released under the GNU GPL v3.0. From 3.1.0 onwards, NimbusKV is Apache-2.0. Copies of 3.0.1 and earlier that you already have remain under the GPL v3.0.
NOTICE: copyright and attributionTRADEMARKS.md: how you may use the NimbusKV nameCOMMERCIAL-LICENSING.md: terms beyond Apache-2.0 (no-attribution, warranty, support)CLA.md: required for contributions
Copyright 2026 Hemanshu Vaidya.
Support development#
If NimbusKV is useful to you, consider supporting development: 👉 NimbusKV on GitHub