CacheWarm v0.5.2

Claude Code plugin / v0.5.2

Come back to a conversation that’s still warm.

Cache Warm sends one tiny keep-alive turn to idle Claude Code sessions before their prompt cache expires — so returning to a long context doesn't start with a full-price rewrite.

Works in the CLI, IDE extensions, and the Desktop app. Node 18+. Zero runtime dependencies.

Cache thermostat live
50m auto interval
Cache TTL1 hour
Warm at50 min
Time left41m 55s
Idle cap180 min
264db9faCLI · 245.3k ctx
31m 55snext ping
a3398cd8Desktop · 466.9k ctx 1 bg job
25m 55snext ping

Illustration. Values come from the shipped defaults and docs.

50 minauto interval on a 1-hour cache
4 minauto interval on a 5-minute cache
180 minidle cap before pings stop
20,000token floor — smaller contexts are skipped

01 The cold return

The most expensive turn is the one after you leave.

Claude Code re-sends the whole conversation on every turn. The prompt cache makes that cheap — until the conversation sits still for longer than the cache TTL.

The cache expires after a period of silence: 5 minutes on an API key, 1 hour on a Claude subscription or with CLAUDE_CODE_PROMPT_CACHE_TTL=1h. The first turn after expiry re-writes everything at 1.25× (5m) or 2× (1h) input price — and it is slow.

Every cache hit resets the timer. One tiny turn shortly before expiry keeps a large context alive for a fraction of the rebuild. Cache Warm automates exactly that, and only when the session is genuinely idle.

5m TTL → ping every 4m 1h TTL → ping every 50m interval must be shorter than TTL
800K-token contextOpus 5 · 1h cache
One keep-alive ping~$0.40

one cache read of the whole context

Cold return after 90 minutes~$8.00

one cache write of the whole context

List-price estimates from the plugin's own pricing table. One rebuild buys roughly 18 pings. On a subscription the same tokens come out of your usage limits.

02 How it works

One waker per session. No daemon, no cron.

The plugin is an ordinary Claude Code hook. At every turn end it starts a small sleeping process for that session. If the session is still idle one interval later, Claude Code wakes it with one line.

  1. 1

    Stop hook · asyncRewake

    The turn ends

    A waker starts for this session and records Claude Code's own background_tasks and session_crons.

  2. 2

    sleep until last request + interval

    The timer runs

    Any new request — you typing, an agent reporting back, a task firing — supersedes the sleeping waker. The next turn end starts a fresh one.

  3. 3

    wake, re-check, decide

    Still worth warming?

    It re-checks background work, this session's scoped settings, the idle cap, the token floor, and whether the cache is still alive.

  4. 4

    exit 2 → one turn → cache read

    Claude answers “ok”

    A one-line keep-alive note reaches the idle session. Claude replies ok; that turn reads the whole context from cache and resets the TTL.

It stands down when warming would not pay for itself.

  • No pending background work default policy
  • Cache already expired a ping would be the rewrite
  • Past maxIdleMinutes or the ping cap
  • Context below minContextTokens cheap to rebuild
  • Warming off for that scope session / project / surface / global
  • Headless runs claude -p, Agent SDK

03 What's in the box

Small surface, deliberate controls.

Scoped settings

Session overrides beat project folders, which beat the surface (CLI, Desktop, IDE), global settings, the plugin tab, and the defaults. Anything unset inherits.

session › project › surface › global

A status line that wraps, not replaces

Warming state, next ping, context, cached tokens, remaining TTL, model, branch, PR, fill and limits. Your existing status line runs first and keeps its output.

one setting restores the originals

Self-checking pings

Every ping is judged from the transcript once its turn lands. A cache read is a hit; a rewrite is a miss. Two misses in a row suspend that session until you are active again.

/cache-warm:test proves the loop

A local dashboard

Live sessions and countdowns, every scope's settings with inherited values, and analytics mined read-only from your own transcripts. Loopback only.

127.0.0.1:4777

Optional tray app

A thin Tauri v2 tray for the global scope. Ctrl+Alt+W toggles warming; Ctrl+Alt+D opens the dashboard.

desktop/ · built with npm

Isolation by construction

Each session has its own waker and resolves its own settings. A Desktop session cannot change a CLI session by accident. Writes are locked and atomic.

no shared engine switch

04 The dashboard

See what each session is waiting on.

A real capture of the local dashboard with sample sessions. It binds to loopback, computes analytics read-only from ~/.claude/projects/**/*.jsonl, and edits every scope with “Inherit” showing what each field falls back to.

127.0.0.1:4777
Cache Warm dashboard: live sessions with next ping countdowns, scoped settings, and cache analytics
Local dashboard, sample data. Each row has its own timer and its own effective settings.

05 Configuration

Defaults that do the right thing.

Most sessions need no configuration at all. These values live in scripts/lib.mjs; this table is generated from them at build time.

SettingDefaultWhat it doesScopes
enabled On all scopes
warmWhen background-work all scopes
intervalMinutes auto — 50 min on a 1h cache, 4 min on a 5m cache all scopes
maxIdleMinutes 180 min (0 = never) all scopes
minContextTokens 20,000 all scopes

Three more keys are global-only: statusline (auto), statuslineSegments (9 available parts), and dashboardPort (4777). Full reference →

06 Install

Two commands, then a new session.

Cache Warm installs as a Claude Code plugin from its own marketplace. Nothing is downloaded from npm; the plugin has no runtime dependencies.

Node 18+ on PATH Claude Code recent enough for asyncRewake hooks

Inside Claude Code

/plugin marketplace add FiredMosquito831/claude-cache-warm
/plugin install cache-warm@claude-cache-warm

Then, in each open session

/reload-plugins

Defaults: warming on, interval auto, only while a subagent, background task or scheduled task is pending. Verify with /cache-warm:status and /cache-warm:test.

Read the full tutorial →

07 Questions

“Will it actually save money?”

Only if the pause is long enough and the context is big enough. The dashboard shows your real rebuilds and what warming would have cost instead. The FAQ covers cost, safety, subscriptions, and the cases where warming is deliberately skipped.

Read the FAQ