From fno
Keep prompt cache alive during idle. Prevents 10x cost spike when cache expires. Use when: 'keep cache warm', 'cache keepalive', or auto-activated at session start when project opts in.
How this skill is triggered — by the user, by Claude, or both
Slash command
/fno:cache-keepaliveThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Schedules 4 pings via ScheduleWakeup to keep prompt cache warm during idle periods. Self-terminates after ~18 minutes. Max cost: ~$0.52.
Schedules 4 pings via ScheduleWakeup to keep prompt cache warm during idle periods. Self-terminates after ~18 minutes. Max cost: ~$0.52.
ScheduleWakeup resumes the same conversation, which keeps cached tokens alive by definition. Each ping is a lightweight wake that re-reads the cached context and reschedules.
Project opt-in via .claude/settings.local.json:
{
"cacheKeepalive": true
}
When enabled, the SessionStart hook auto-activates keepalive silently.
When absent or false, keepalive is manual-only (/cache-keepalive).
/cache-keepalive config claude - enables auto-activation for the current project:
mkdir -p .claude
SETTINGS=".claude/settings.local.json"
if [[ -f "$SETTINGS" ]]; then
jq '.cacheKeepalive = true' "$SETTINGS" > "${SETTINGS}.tmp" && mv "${SETTINGS}.tmp" "$SETTINGS"
else
echo '{"cacheKeepalive": true}' | jq . > "$SETTINGS"
fi
Confirm with: Cache keepalive auto-activation enabled for this project. Takes effect next session.
To disable: /cache-keepalive config claude off
SETTINGS=".claude/settings.local.json"
if [[ -f "$SETTINGS" ]]; then
jq '.cacheKeepalive = false' "$SETTINGS" > "${SETTINGS}.tmp" && mv "${SETTINGS}.tmp" "$SETTINGS"
fi
SESSION_ID=$(cat ~/.claude/.session-context.json 2>/dev/null | python3 -c "import json,sys; print(json.load(sys.stdin).get('session_id',''))" 2>/dev/null)
if [ -n "$SESSION_ID" ]; then
find ~/.claude/projects/ -name "${SESSION_ID}.jsonl" 2>/dev/null | head -1 | xargs python3 -c "
import json, sys
last_usage = None
model = 'unknown'
for line in open(sys.argv[1]):
try:
obj = json.loads(line)
if obj.get('type') == 'assistant':
u = obj.get('message', {}).get('usage', {})
m = obj.get('message', {}).get('model', '')
if u.get('cache_read_input_tokens', 0) > 0:
last_usage = u
model = m
except: pass
if last_usage:
cr = last_usage.get('cache_read_input_tokens', 0)
inp = last_usage.get('input_tokens', 0)
cc = last_usage.get('cache_creation_input_tokens', 0)
total_ctx = cr + inp + cc
print(f'CACHE_READ={cr}')
print(f'INPUT={inp}')
print(f'TOTAL_CTX={total_ctx}')
print(f'MODEL={model}')
else:
print('NO_USAGE_DATA')
" 2>/dev/null
fi
Pricing per million tokens (use ONLY these values):
Calculate: uncached = TOTAL_CTX / 1M * input_price. cached = TOTAL_CTX / 1M * cache_read_price.
Report cache stats to user:
Cache keepalive active.
Context: ~[X]K tokens ([MODEL])
Cache miss would cost: ~$[uncached] | Cached: ~$[cached] | Savings: ~$[diff]
Schedule: 4 pings at ~270s intervals (~18 min total)
Total keepalive cost: ~$0.52
Cancel: just type anything (user input naturally cancels the loop)
Only fires when idle. Normal work refreshes cache automatically.
Then schedule the first ping:
ScheduleWakeup({
delaySeconds: 270,
reason: "cache keepalive ping 1/4 - keeping prompt cache warm",
prompt: "/cache-keepalive"
})
Determine current ping number by checking conversation for the most recent [cache-keepalive] Ping N/4 message. If none found, this is ping 1.
Output ONLY:
[cache-keepalive] Ping N/4 | cache warm
Then:
if [[ "$(uname)" == "Darwin" ]]; then
osascript -e 'display notification "Return to your session or the cache will expire on next ping" with title "Cache Keepalive"' 2>/dev/null
elif command -v notify-send &>/dev/null; then
notify-send "Cache Keepalive" "Return to your session or the cache will expire on next ping" 2>/dev/null
fi
[cache-keepalive] Ping 4/4 | final ping, cache protection ending. Type anything to continue working.
Do NOT call ScheduleWakeup after ping 4.User input at any point naturally cancels the ScheduleWakeup loop. No explicit cancel handler needed.
npx claudepluginhub bllshttng/footnote --plugin fnoCaches LLM prompts and responses using Anthropic prompt caching, Redis response caching, and Cache Augmented Generation (CAG).
Implements LLM prompt caching with Anthropic's native API, Redis-based response caching via hashing, and CAG patterns. Optimizes costs and latency for repeated prefixes or queries.
Provides a KV cache (slm_cache_get/set) to avoid re-reading files, query results, or tool outputs within a session. Standard cache-aside pattern with TTL support.