Last month, Maxim Khailo published "Your Agentic Workflow's Cache Keepalive Costs 8x Too Much". He ran controlled benchmarks across Anthropic, OpenAI, DeepSeek, and Gemini to map exactly where cache keepalive pays off and where it becomes actively harmful. His finding: a 4-minute keepalive interval is ~7.8x cheaper than 30-second pings for the same cache warmth. Past each provider's TTL, keepalive turns toxic.
We had already learned the same lesson the expensive way. In July 2026, while investigating token usage in Prompter Hawk, we discovered scheduled agent heartbeats had consumed the majority of a working session's budget, and we had not noticed until the session died.
Khailo's post covers API economics rigorously. This post covers the complement: production incidents, subscription-plan economics, and the observability gap that lets this problem hide.
What Khailo Established
His benchmarks are worth reading in full. The key findings relevant here:
- Anthropic's cache TTL is 5 minutes. Past that, your cache is gone. Pinging at 8-minute intervals cost 4x more than never pinging at all, because you are re-prefilling a dead cache at full price.
- 4-minute intervals are optimal for Anthropic. That is ~7.8x cheaper than the 30-second pings many implementations default to.
- Break-even for Anthropic is ~46 minutes. If your pause will exceed that, do not ping at all. Let the cache die and reload fresh when needed.
- The "paying band" is narrow. Keepalive only saves money when pause duration exceeds the eviction point but stays under break-even. Outside that band, you are paying for nothing.
His math is solid. What he did not cover is what happens when the cost is not API dollars.
The Subscription-Plan Angle
Khailo prices everything in API dollars. That is correct for direct API usage. But Claude subscription plans (Pro, Max, Team) operate on a different economy: you pay a flat monthly fee and get a token budget, typically structured as a 5-hour sliding window or weekly allocation.
This changes the failure mode:
- API users: overspend shows up on your invoice next month
- Subscription users: overspend shows up as "session unavailable" mid-task
When scheduled heartbeats ate 68% of our tokens, we did not get a bill. We got an agent that could not finish its work because the budget was exhausted.
Max Plan Cache Behavior
There is another difference. Khailo measured a 5-minute cache TTL on the Anthropic API. Max-plan sessions appear to run a 1-hour cache TTL, likely because the session is held open longer and context is managed differently.
This means Max-plan users have a wider paying band but also higher stakes. A 30-minute heartbeat is inside the API break-even but outside the API TTL. On Max, it might be inside the TTL but the tokens still count against your weekly cap. The economics shift, but the waste does not disappear.
The Observability Gap
Why did we not notice 11.5M tokens going to heartbeats until the session died?
Because Anthropic's built-in monitoring cannot automatically attribute cron-scheduled agent runs. Each scheduled wake looks like a separate conversation in your dashboard. To see the cumulative cost of heartbeats versus productive work, you need to:
- Log timestamps for every scheduled wake
- Tag those sessions distinctly from user-initiated work
- Aggregate across days or weeks
- Manually correlate timestamps to figure out which conversations were heartbeats
Most teams have not built this. So they do what we did: assume the agent is working, wonder why the budget feels tight, and not discover the problem until something breaks.
Key insight: If your heartbeat interval exceeds the cache TTL, you are not keeping the cache warm. You are paying full context-reload costs on every ping. This is the "toxic edge" Khailo identified, and it is easy to hit without realizing it.
Our 30-Minute Heartbeats Were Toxic
We were running heartbeats every 30 minutes (48/day). By Khailo's math, this is well past Anthropic's 5-minute TTL. Every heartbeat was a full context reload, not a cache read.
Worse, 30 minutes is also well under the 46-minute break-even. We were in the worst possible zone: paying full reload costs without any cache benefit, and doing it 48 times a day.
His analysis says we should have either:
- Pinged every 4 minutes to actually keep the cache warm
- Pinged rarely or never to stay past break-even and reload only when needed
We chose option two. Cut from 48/day to 2/day.
What The Heartbeats Were Actually Doing
Before cutting them, we audited what each heartbeat accomplished:
- Task queue status: Can be checked via database query, no agent needed
- Agent health: Can be inferred from last activity timestamp
- Pending notifications: Can use webhooks instead of polling
The only things that truly required the agent to wake up and reason:
- Daily summary generation
- Stale task cleanup
Two wakes per day handles both. Everything else moved to lightweight checks that do not invoke an LLM.
The Result
The agents still work. Tasks still get processed. Notifications still arrive. We just stopped paying to ask "anything happening?" 48 times a day when the cache was cold anyway.
How to Check Your Own Usage
1. Know Your TTL
Khailo measured these (as of July 2026):
Anthropic API: 5 minutes
OpenAI: ~30 minutes
DeepSeek: ~10 minutes
Google Gemini: Unreliable (33-83% hit rate lottery)
If your heartbeat interval exceeds your provider's TTL, you are not keeping anything warm.
2. Tag Your Scheduled Runs
Add a flag that distinguishes cron-triggered runs from user-triggered ones. Something as simple as source: "scheduled" in your logging.
3. Aggregate and Compare
SELECT
source,
SUM(input_tokens + output_tokens) as total_tokens,
COUNT(*) as session_count
FROM agent_sessions
WHERE created_at > NOW() - INTERVAL '7 days'
GROUP BY source
If scheduled sessions account for more than 50% of your tokens, you have the same problem we did.
4. Ask What Each Heartbeat Actually Does
For each scheduled task: Does this require the agent to reason, or could it be a database query? If it is just checking status, you probably do not need an LLM.
The Broader Pattern
This is not unique to heartbeats. Any time you have an LLM polling for changes, you are paying context loading costs on every poll, and if your interval exceeds the cache TTL, you are paying full price.
Khailo's recommendations hold:
- If you must ping, ping inside the TTL (4 minutes for Anthropic)
- If your pauses exceed break-even, do not ping at all
- Webhook-based architectures avoid the problem entirely
On subscription plans, add one more: watch your token budget attribution, because the cost will not show up on an invoice. It will show up as a dead session.
Bottom line: Khailo's benchmarks are the reference. Our production numbers confirm them. If you are on a subscription plan, the failure mode is worse because you do not get a bill, you get session death. Audit your heartbeats. The fix is usually trivial.