Skip to main content

stillwarm

Your local LLM re-reads everything after every restart. stillwarm fixes that.

llama.cpp's llama-server can save a conversation's KV cache (the model's per-token "notes") to disk and load it back — but nothing does it automatically, and nothing checks that the file you're loading matches the server you're loading it into. stillwarm is a zero-dependency Python library + small CLI:

  • restore-before-request, save-after-response — sessions survive restarts;
  • a metadata sidecar per save — incompatible files are refused with a reason, never silently misloaded;
  • a silently-ineffective guard — if a restore "succeeds" but the server re-prefills anyway (the measured SWA-without---swa-full trap), you get a loud warning instead of silently paying cold-start cost;
  • LRU pruning under a disk budget (KV files are ~128 KiB/token for an 8B model — a 32K-token session is ~4.3 GB);
  • verify — an integrity mode that byte-checks a restored state against a probe captured at save time.

Measured on an M3 Max (llama.cpp b9871, Llama-3.1-8B Q4_K_M, same-session thermally controlled): resuming a session from disk instead of re-reading it is 71x faster at 8K tokens, 159x at 32K, 201x at 64K (restore + first-token time vs cold prefill), and ~50x cheaper in energy at 32K. Even with a purged page cache, restore wins for any document longer than ~300 tokens.

Quickstart

from stillwarm import LlamaServer, ServerProfile, Session

# llama-server ... -fa on --slot-save-path ~/.stillwarm/   (must be running)
server  = LlamaServer("http://127.0.0.1:8080")
profile = ServerProfile(model_sha256="<sha256 of your .gguf>",
                        flash_attn="on", cache_type_k="f16", cache_type_v="f16",
                        swa_full=False, ctx_size=16384)
sw = Session(server, profile, cache_dir="~/.stillwarm",
             server_build_tag="b9871", disk_budget_gb=50)

r = sw.ask("paper-review", document + "\n\nQ: Summarize.\nA:", n_predict=256)
# ... llama-server restarts ...
r = sw.ask("paper-review", document + "\n\nQ: And the weaknesses?\nA:", n_predict=256)
print(r.restored, r.prompt_n)   # True, ~a few dozen tokens instead of thousands

cache_dir must be the directory passed to --slot-save-path. CLI:

stillwarm list  ~/.stillwarm            # sessions, sizes, ages
stillwarm inspect ~/.stillwarm/paper-review.bin
stillwarm prune ~/.stillwarm --budget-gb 50 [--dry-run]

Compatibility contract (every rule measured, not guessed)

From a 480-row benchmark matrix (stillwarm-bench, Block D portability taxonomy):

you change... what happens stillwarm's response
flash-attention on<->off restore fails (400) both directions REFUSE up front
KV cache type (f16/q8_0/q4_0) layout mismatch REFUSE
model file meaningless state REFUSE
--swa-full (SWA models) restore "works" but silently re-prefills REFUSE + runtime guard
server ctx < saved tokens restore fails (fit rule) REFUSE with a clear message
server ctx >= saved tokens works OK
-ngl (GPU layers) works (measured both directions) OK — not part of the cache key
llama.cpp build (+-5 weeks measured) works both directions ADVISORY warning only

verify — honest semantics

At save time, stillwarm writes the slot file first (the file is the pre-probe state), then generates a 64-token pinned-greedy probe and stores its hash in the sidecar. restore(..., verify=True) restores, re-runs the probe, compares hashes, then re-restores so the served state is exactly the restored state.

This is a determinism check (does the restored state reproduce the save-time continuation?), deliberately not a cold-equivalence check (does it match a full recompute?). Cold-equivalence measurably fails without any corruption: different prefill batch splits flip marginal tokens, and quantized caches amplify this to near-certainty (q4_0: 5/5 divergent at 8K in stillwarm-bench Block C) while both outputs stay coherent. A verify failure therefore means the file/model/config does not reproduce what was saved — a real integrity signal, not batching noise.

Cost: ~2x restore time + one 64-token decode (~1.5 s for an 8B model).

Non-goals (v1 fence)

  • Not a serving framework — one machine, one llama-server.
  • No multi-machine cache sharing; no vLLM (LMCache owns that space).
  • llama-server only: Ollama and LM Studio do not expose the slot save/restore endpoints this needs.
  • No compression research. Small and finished beats large and abandoned.

Platforms

  • macOS (Apple Silicon) — tested; all measured numbers come from an M3 Max against llama.cpp b9871.
  • Linux — expected to work (same llama-server HTTP API; the demo Space runs the identical mechanism on Linux/CPU); not part of the measured matrix.
  • Windows — untested. The code is audited for portability (pathlib throughout, atomic writes via os.replace, no POSIX-only stdlib modules, and pruning tolerates PermissionError on files Windows holds open) — reports welcome.

Tests

pytest — unit tests run anywhere; integration tests need a llama-server binary and a tiny GGUF (defaults: SmolLM2-135M-Instruct Q8_0, ~145 MB; override via STILLWARM_TEST_SERVER_BIN / STILLWARM_TEST_MODEL; they skip if absent).

License

MIT — see LICENSE.

Metadata

Release files for stillwarm 0.1.1

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

Source distribution (sdist)

Source distribution for stillwarm 0.1.1
File Size Uploaded Provenance
stillwarm-0.1.1.tar.gz 23.3 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 42.2 kB

Release files / stillwarm-0.1.1.tar.gz

Download URL stillwarm-0.1.1.tar.gz
Size 23.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7cb931cb1579eb5fed622d057eb490951d96e8a11044c70ec1fab07de55a51a0
BLAKE2b-256 checksum
How to use checksums
ff371288a0c4aa9c0d37014f507ffa5087a4c2eb0bef5edb237d9d5c73309cf9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Release files / stillwarm-0.1.1-py3-none-any.whl

Download URL stillwarm-0.1.1-py3-none-any.whl
Size 18.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3031f7587dfd22b2b05aefc7e9e75df539e873df7a2112e45253dd0b1b0e54f7
BLAKE2b-256 checksum
How to use checksums
5214946a6716f5e7a250f2f924cd8b9ee47a0087ac6e9a18170c8e318d371174
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.14.6

Security for stillwarm 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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