Cache commands
kanros uses a SQLite-backed response cache to avoid paying for provider
calls twice. The cache is keyed by (provider_id, request); a hit
skips the provider call entirely and returns the stored response.
The kanros cache namespace lets you inspect and prune the cache.
Default location
The cache lives in the platform's standard cache directory:
| OS | Default path |
|---|---|
| Linux | $XDG_CACHE_HOME/kanros/cache.db (typically ~/.cache/kanros/cache.db) |
| macOS | ~/Library/Caches/kanros/cache.db |
| Windows | %LOCALAPPDATA%\kanros\cache.db |
Override the location with --cache-path <FILE>, which is a global flag
on the cache namespace.
Subcommands
kanros cache [--cache-path <PATH>] <SUBCOMMAND>
| Subcommand | Description |
|---|---|
info | Show cache statistics: entry count, total size, oldest/newest entry. |
list | List all cache entries. |
prune | Remove expired entries only. |
clear | Delete all entries. |
kanros cache info
kanros cache info
Sample output:
Cache at /Users/me/Library/Caches/kanros/cache.db:
428 entries
total size: 18.32 MB (19,209,344 B)
oldest: 2025-09-12T08:03:27Z
newest: 2025-11-20T16:42:11Z
Useful as a quick sanity check before a long run — if info reports a
suspiciously empty cache, you probably want --no-cache off.
kanros cache list
kanros cache list
provider_id created_at expires_at size (B)
--------------------------------------------------------------------------------------------------------------
openai:gpt-4o-mini 2025-11-20T16:42:11Z 2025-12-20T16:42:11Z 1,432
anthropic:claude-3-5-haiku 2025-11-20T16:42:09Z 2025-12-20T16:42:09Z 2,047
…
The columns are deliberately fixed-width for piping into awk / cut.
kanros cache prune
Remove expired entries:
kanros cache prune
# Pruned 12 expired cache entries.
A no-op when there is nothing to prune. The TTL is set per-entry when
the response is stored; see RunOptions::cache_ttl.
kanros cache clear
Delete every entry:
kanros cache clear
# Cleared 428 cache entries.
This is occasionally what you want before a deterministic benchmark or when a provider has changed in a way that invalidates the cached responses (model migration, billing tier change, prompt-template refactor).
CI-scoped caches
When kanros runs in CI, you usually want a per-PR or per-pipeline cache file so that:
- Workers do not share cache state across PRs (which would make results irreproducible).
- The cache is small enough to upload as a build artifact between stages.
kanros run --cache-path ./.kanros-cache.db
kanros cache info --cache-path ./.kanros-cache.db
A common pattern is to upload .kanros-cache.db as an artifact at the
end of the test stage and download it at the start of the next pipeline
run for the same branch.
What gets cached
The cache stores serialised CompletionResponse values keyed by a
hash of the (provider_id, CompletionRequest) pair. Cells whose
provider response can be replayed from the cache report
cached: true in JSON output and [cached] in the terminal view.
The cache does not store:
- Assertion outcomes — assertions always re-run against the cached response. This means you can change an assertion's threshold and re-run without re-paying for the provider call.
- Run summaries — those go to a separate table in the same database
(and feed
kanros diff/kanros share).
Notes
- The cache database is opened with the bundled
rusqlite. No external SQLite install required. - Concurrent runs against the same cache file are safe (SQLite's WAL mode handles the locking).
- A failed run leaves a partial cache. The next run picks up where the
previous one left off —
pruneandclearare the escape hatches if something gets stuck.