Keep Warm
Schedules a recurring heartbeat that touches the prompt cache before its 60-minute TTL expires. Without this, idle gaps past 1 hour force the next turn to reprocess the entire context as fresh input — billed at full input rate against weekly usage.
This skill assumes the user has ENABLE_PROMPT_CACHING_1H=1 set (the 1-hour cache tier, not the 5-minute default).
Cadence
Only cron */N patterns where N divides 60 produce uniform gaps — i.e. 15, 20, 30, 60. Anything else (*/55, */45, */40, */25) resets at the top of each hour and produces a broken alternating pattern. */55 is the canonical trap: it fires at :00 and :55, giving 55-min then 5-min gaps.
/loop <interval> also uses cron under the hood for interval mode, so /loop 55m is broken the same way — do not suggest it as a workaround. (/loop dynamic mode, invoked with no interval, uses ScheduleWakeup and can pick any delay in [60s, 3600s] — but that's an active self-paced loop, not a passive heartbeat, and isn't appropriate for keep-warm.)
True 55-min cadence is not reachable for keep-warm purposes. Pick a cron-friendly cadence instead:
*/30 * * * * (default): uniform 30-min gaps, well under the 60-min TTL. One extra heartbeat per hour vs. a hypothetical 55-min cadence — cheap, since the heartbeat is a single short reply.
*/20 * * * * or */15 * * * *: tighter cadences if extra safety margin is wanted.
- Avoid
0 * * * * (every 60 min): fires at the TTL boundary, leaving zero margin for delivery jitter.
Do not call ScheduleWakeup directly from this skill — it's gated to /loop dynamic mode and its prompt must be a /loop input.
Start
- Use CronCreate with
*/30 * * * *. If the user explicitly asks for "every 55 minutes" or another non-divisor cadence, tell them it's not expressible cleanly and offer the nearest divisor (30 or 60-but-risky) — do not silently substitute or use /loop 55m.
- Heartbeat prompt:
Cache heartbeat. Reply with one short line and stop. No file reads, no tool calls, no other action.
- Tag the schedule's reason field with
keep-warm heartbeat so stop can find it.
- Report to the user: scheduled, cadence, next fire time, and how to stop.
Stop (arg: stop, cancel, off)
- List active schedules with
CronList (or equivalent).
- Delete the one whose reason contains
keep-warm heartbeat.
- Confirm cancellation.
Rules
- One heartbeat per session. Before scheduling, list existing schedules. If one tagged
keep-warm heartbeat already exists, report it and skip — do not duplicate.
- The heartbeat must be a no-op turn. When it fires, do not start new work, read files, or invoke tools. One short line and stop.
- Don't schedule for short tasks. If the user's current task is clearly under 1 hour, tell them they don't need this and skip.
1---2name: keep-warm3description: Schedule a recurring heartbeat that keeps Claude Code's 1-hour prompt cache from expiring during long unattended tasks. Use when starting a multi-hour run, or when the user says "keep cache warm", "warm cache", "stay warm", "heartbeat", "keep alive", or invokes "keep-warm". Pass "stop", "cancel", or "off" to cancel an active heartbeat.4---56# Keep Warm78Schedules a recurring heartbeat that touches the prompt cache before its 60-minute TTL expires. Without this, idle gaps past 1 hour force the next turn to reprocess the entire context as fresh input — billed at full input rate against weekly usage.910This skill assumes the user has `ENABLE_PROMPT_CACHING_1H=1` set (the 1-hour cache tier, not the 5-minute default).1112## Cadence1314Only cron `*/N` patterns where **N divides 60** produce uniform gaps — i.e. 15, 20, 30, 60. Anything else (`*/55`, `*/45`, `*/40`, `*/25`) resets at the top of each hour and produces a broken alternating pattern. **`*/55` is the canonical trap: it fires at :00 and :55, giving 55-min then 5-min gaps.**1516`/loop <interval>` also uses cron under the hood for interval mode, so `/loop 55m` is broken the same way — do not suggest it as a workaround. (`/loop` dynamic mode, invoked with no interval, uses `ScheduleWakeup` and can pick any delay in [60s, 3600s] — but that's an active self-paced loop, not a passive heartbeat, and isn't appropriate for keep-warm.)1718**True 55-min cadence is not reachable for keep-warm purposes.** Pick a cron-friendly cadence instead:1920- **`*/30 * * * *`** (default): uniform 30-min gaps, well under the 60-min TTL. One extra heartbeat per hour vs. a hypothetical 55-min cadence — cheap, since the heartbeat is a single short reply.21- **`*/20 * * * *`** or **`*/15 * * * *`**: tighter cadences if extra safety margin is wanted.22- **Avoid `0 * * * *`** (every 60 min): fires *at* the TTL boundary, leaving zero margin for delivery jitter.2324Do **not** call `ScheduleWakeup` directly from this skill — it's gated to `/loop` dynamic mode and its `prompt` must be a `/loop` input.2526## Start27281. Use **CronCreate** with `*/30 * * * *`. If the user explicitly asks for "every 55 minutes" or another non-divisor cadence, tell them it's not expressible cleanly and offer the nearest divisor (30 or 60-but-risky) — do **not** silently substitute or use `/loop 55m`.292. Heartbeat prompt: `Cache heartbeat. Reply with one short line and stop. No file reads, no tool calls, no other action.`303. Tag the schedule's reason field with `keep-warm heartbeat` so `stop` can find it.314. Report to the user: scheduled, cadence, next fire time, and how to stop.3233## Stop (arg: `stop`, `cancel`, `off`)34351. List active schedules with `CronList` (or equivalent).362. Delete the one whose reason contains `keep-warm heartbeat`.373. Confirm cancellation.3839## Rules4041- **One heartbeat per session.** Before scheduling, list existing schedules. If one tagged `keep-warm heartbeat` already exists, report it and skip — do not duplicate.42- **The heartbeat must be a no-op turn.** When it fires, do not start new work, read files, or invoke tools. One short line and stop.43- **Don't schedule for short tasks.** If the user's current task is clearly under 1 hour, tell them they don't need this and skip.