claudeers.
// Claude Skills

cachebeat

A tiny Claude Code skill that keeps your prompt cache warm during idle sessions, so your next message reads from cache instead of paying full price.

Actively maintained
98/100
last commit 15 days ago
last release none
releases 0
open issues 0

Install with your AI

Paste into Claude Code, Cursor, or any agent — it reads the repo and wires the tool into your project.

Install and set up cachebeat (claude-skill project) into my current project.
Found on https://claudeers.com/cachebeat
Repo: https://github.com/ARahim3/cachebeat
Homepage/docs: —
Detected install method: claude-skill → # copy this skill into .claude/skills/cachebeat/
Category: skills. Platforms: cli, api.
Read the repo's README for exact setup and env vars, then install it and wire it into my project.

Claudeers Health Verdict:
active; community-verified: false. Confirm the source before running anything.
// or install directly (claude-skill)
# copy the skill dir into your project:
# .claude/skills/cachebeat/   (or ~/.claude/skills/cachebeat/ for all projects)
// or clone
git clone https://github.com/ARahim3/cachebeat

// compatibility

Platformscli, api
Operating systems—
AI compatibilityclaude
License—
Pricingopen-source
Language—

Get your FREE $2.50 API credits to access TickAtlas financial data ↗

cachebeat 🫀

Stop paying full price to say "I'm back" to your own Claude Code session.

A tiny Claude Code skill that keeps your prompt cache warm while a session sits idle — so your next message reads the conversation from cache instead of re-billing it from scratch. Anthropic bills cache reads at 0.1× the input rate (published ratio, every model) — an uncached return costs ~10× more.

This is not just an API-billing thing. On Pro/Max subscriptions the same accounting drains your 5-hour window and weekly usage limit: come back to a long session cold, and one "how's it going?" can eat a visible chunk of your quota that a warm cache would barely have touched.

Why this exists

It was born in a real session: a multi-day model fine-tune babysat by Claude — training runs that took hours, checkpoints landing overnight, a human who occasionally sleeps. Every time the session went quiet for longer than the cache window, the next "how's it going?" re-billed the entire conversation history at full input price. On a long, tool-heavy session that's hundreds of thousands of tokens, re-billed every single time you stepped away too long.

One inactivity-triggered heartbeat later, it didn't.

The problem, concretely

Claude is stateless: your whole conversation is re-sent to the API on every turn. Anthropic's prompt caching makes this affordable — cached input costs ~10 % of the normal rate — but the cache expires after a TTL (up to 1 hour on long-TTL sessions). The failure mode:

  1. You run something long (training, CI, a big download) or just step away.
  2. The session is silent past the TTL. The cache dies.
  3. You come back, type one line — and the entire history is re-processed uncached: ~10× the tokens a cached read would have counted. On the API that's money; on a subscription that's your 5-hour window and weekly limit draining for nothing.

Do that a few times a day on a long-running session and the "idle tax" quietly becomes the biggest line in your bill — or the reason you hit your usage limit by mid-week.

The fix

/cachebeat arms a single background monitor inside your session. It's an inactivity timer, not a metronome: it fires only when the session has been truly silent for N minutes — any message, reply, or answered background event already refreshed the cache and resets the clock. On firing, Claude wakes, answers with a few words, and the cache TTL restarts.

Break-even math: going cold once costs as much as ten heartbeats. Come back to the session even once and the heartbeat has paid for itself many times over — and the bigger the session, the bigger the absolute savings (the 10× ratio is flat; the token count isn't).

It also kills itself after a deadline (default 8 h), so an abandoned session doesn't drip-bill forever.

Install

User-level (all projects):

mkdir -p ~/.claude/skills/cachebeat
cp SKILL.md ~/.claude/skills/cachebeat/

Or project-level: copy SKILL.md into <your-project>/.claude/skills/cachebeat/.

That's the whole setup — copy one file. Then in any Claude Code session, type /cachebeat and you're done; there's nothing to configure. (It just needs a Claude Code that runs background tasks, which is the default.)

Usage

/cachebeat            # fire after 50 min of inactivity, auto-stop after 8 h
/cachebeat 40         # custom idle threshold in minutes (clamped to 5–55)
/cachebeat 40 4       # custom threshold + auto-stop after 4 h
/cachebeat stop       # stop it

Verifying it's working

You don't have to take it on faith — you can watch the cache stay warm.

  • The status line. Claude Code's token readout looks like tok:312.0k/0.0k — total / served from cache. When you return to an idle session, the second number should be a large fraction of the first (warm). If it reads …/0.0k, the whole context was re-read uncached — the cache had died. With cachebeat armed on a long-TTL session, it should stay warm across your idle gaps.

  • The transcript (exact numbers). Every assistant reply records what it cost. Run this inside the session (prefix a shell command with !):

    F=$(ls ~/.claude/projects/*/"$CLAUDE_CODE_SESSION_ID".jsonl 2>/dev/null | head -1)
    echo "cache_read:     $(tail -n 400 "$F" | grep -oE '"cache_read_input_tokens":[0-9]+'     | tail -1 | grep -oE '[0-9]+')"
    echo "cache_creation: $(tail -n 400 "$F" | grep -oE '"cache_creation_input_tokens":[0-9]+' | tail -1 | grep -oE '[0-9]+')"
    

    A warm turn shows a big cache_read and a tiny cache_creation. A cold turn is the reverse — a large cache_creation means the context was rebuilt from scratch at full price.

  • The heartbeat itself. When a beat fires you'll see Claude answer with a few words ("Okay, still here.") — proof the monitor is alive and resetting the TTL. If instead you see CACHEBEAT_WARN, the beat fired on schedule but still came back uncached: your session's TTL is too short for any heartbeat to bridge, so stop it.

How it works

Claude Code writes every exchange to a session transcript (~/.claude/projects/<slug>/<session-id>.jsonl). The skill starts one persistent background monitor that, once a minute, checks when the last real turn happened and how long ago that was:

# Pin THIS session's transcript by its id (not "newest file", which another
# session in the same folder could hijack). Fall back to newest at arm time.
SID="$CLAUDE_CODE_SESSION_ID"
F=$(ls "$HOME/.claude/projects"/*/"$SID".jsonl 2>/dev/null | head -1)
[ -z "$F" ] && F=$(ls -t "$HOME/.claude/projects/$(pwd | tr '/._' '---')"/*.jsonl | head -1)

END=$(( $(date +%s) + HOURS*3600 )); PREV=__init__; LAST=$(date +%s)
while [ $(date +%s) -lt $END ]; do
  sleep 60
  # Activity signal = timestamp of the last transcript line. It changes only on a
  # real turn — a bare file-mtime bump (recap rewrite, atomic save) does NOT fool it.
  SIG=$(tail -n 1 "$F" | grep -oE '"timestamp":"[^"]+"' | tail -1)
  [ -z "$SIG" ] && SIG=$(wc -c < "$F")
  [ "$SIG" != "$PREV" ] && { PREV="$SIG"; LAST=$(date +%s); }   # new turn -> reset clock
  IDLE=$(( $(date +%s) - LAST ))
  if [ $IDLE -ge $((MINUTES*60)) ]; then
    echo "HEARTBEAT idle=${IDLE}s"                 # wakes Claude -> tiny reply -> cache refreshed
    sleep 300                                      # let the reply land; avoids double-fire
    # Self-check: if the beat itself came back uncached, the TTL is too short to bridge.
    CR=$(tail -n 400 "$F" | grep -oE '"cache_read_input_tokens":[0-9]+' | tail -1 | grep -oE '[0-9]+')
    CC=$(tail -n 400 "$F" | grep -oE '"cache_creation_input_tokens":[0-9]+' | tail -1 | grep -oE '[0-9]+')
    [ -n "$CC" ] && [ -n "$CR" ] && [ "$CC" -gt "$CR" ] && echo "CACHEBEAT_WARN uncached beat"
  fi
done
echo CACHEBEAT_EXPIRED

Every emitted line wakes Claude; the skill instructs it to reply with a few words only, because every extra token gets re-read by all future requests. CACHEBEAT_WARN flags a session whose cache TTL is too short for any heartbeat to help; CACHEBEAT_EXPIRED ends it.

Why the timestamp, not the file mtime? The mtime of a .jsonl advances whenever Claude Code rewrites the file for its own reasons (recap regeneration, atomic saves) — no turn, no cache refresh. Measuring idle from mtime therefore undercounts idle time and fires the beat late, past the TTL, so the beat lands as a full-price uncached re-read: the exact failure this is meant to prevent. The last line's timestamp only moves on a genuine turn, so it can't be fooled.

Compatibility

Linux, WSL2, and macOS. The monitor uses only portable tools — tail, grep, wc, date +%s — with no stat and no timestamp parsing, so there are no GNU-vs-BSD differences to trip over. Native Windows (non-WSL) is untested — the monitor assumes a POSIX shell.

It reads Claude Code's session transcript at ~/.claude/projects/<slug>/<session-id>.jsonl (found via $CLAUDE_CODE_SESSION_ID, else the newest transcript in the folder) — the default layout, but an internal one rather than a documented API, so a future Claude Code change could require an update here.

Honest caveats

  • Only helps on sessions with the long (1-hour) cache TTL. Some sessions run a 5-minute TTL; no practical heartbeat can bridge that. If your bills stay uncached despite beats, stop it.
  • Each beat costs a small cached-read request plus a few output tokens, and each beat's exchange is appended to the context that later requests re-read. Cheap, not free.
  • The idle threshold must stay under the TTL — the default 50 min leaves ~10 min of margin against the 1-hour TTL.
  • If you're not coming back to the session, any heartbeat is pure waste. That's what the auto-stop deadline is for.

License

MIT — do whatever you like with it.

// faq

What is cachebeat?

A tiny Claude Code skill that keeps your prompt cache warm during idle sessions, so your next message reads from cache instead of paying full price.. It is open-source on GitHub.

Is cachebeat free to use?

cachebeat is open-source, so it is free to use.

What category does cachebeat belong to?

cachebeat is listed under skills in the Claudeers registry of Claude-compatible tools.

9 views
★ 60 stars
unclaimed
updated 20 days ago

// embed badge

cachebeat on Claudeers
[![Claudeers](https://claudeers.com/api/badge/cachebeat.svg)](https://claudeers.com/cachebeat)

// retro hit counter

cachebeat hit counter
[![Hits](https://claudeers.com/api/counter/cachebeat.svg)](https://claudeers.com/cachebeat)

// reviews

// guestbook

0/500

// related in Claude Skills

🔓

An agentic skills framework & software development methodology that works.

// skillsobra/⟨Shell⟩★ 292,190◷ MIT[ claude ]
🔓

Public repository for Agent Skills

// skillsanthropics/⟨Python⟩★ 178,324[ claude ]
🔓

💫 Toolkit to help you get started with Spec-Driven Development

// skillsgithub/⟨Python⟩★ 138,919◷ MIT[ claude ]
🔓

AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, Gemini CLI, and more). Turn any folder of code, SQL schemas, R scripts, shell scripts, docs,…

// skillsGraphify-Labs/⟨Python⟩★ 123,800◷ MIT[ claude ]
→ see how cachebeat connects across the ecosystem