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:

OSDefault 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>
SubcommandDescription
infoShow cache statistics: entry count, total size, oldest/newest entry.
listList all cache entries.
pruneRemove expired entries only.
clearDelete 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 — prune and clear are the escape hatches if something gets stuck.