Replay · Prompt cache analyser for coding agents · Source available
Your prompt cache expired while you were at lunch.
A gap longer than the TTL re-bills the whole prefix, and nothing tells you. Measured on one machine's corpus: 39 expiries, about 271,436 tokens each, 33.9% of everything that got paid for twice.
If you already run ccusage, this is the next question. Not what you spent, but which turn spent it twice, and what changed on that turn.
- total
- $4039.23
- median task
- $0.79
- p90 task
- $7.79
- avoidable
- $199.77 · 5% of the total
Real output, 119 of the maintainer’s own sessions, 2026-09-12. One machine, so run it on yours.
Your agent resends the whole conversation every turn. Most of it should come from the provider’s cache, and usually it does. Then one turn shifts something (a timestamp, a reordered tool list, a history the client re-rendered) and the cache stops matching.
Nothing errors. Nothing warns you. The bill roughly doubles for the rest of that session, and you find out weeks later looking at a number you cannot account for.
It reads the transcripts your agent already wrote, so there is nothing to instrument and no first run where you get nothing. Your history is already on disk.
Install
Short enough to read in one sitting, no dependencies, and it aborts rather than install something it could not verify. Read it before you run it. That is rather the point.
Install with AI
You already have an agent open, or none of this would be your problem. Paste this into it. The agent installs Replay, runs the doctor, then reads your most recent session and tells you what the cache cost you.
The prompt asks for the calibration line first, so your agent has to show whether the numbers can be trusted before it quotes them at you.
- $0.79
- Median task
Across 119 distinct sessions (1,881 transcripts) totalling $4039.23 at list rates, measured 2026-09-12. The p90 task cost $7.79, which is the spread you need before you can price a feature or forecast an unattended agent.
- 5%
- Paid twice
$199.77 of that bill was re-billed because a prompt cache broke and nobody was told. Not a forecast of savings: money already spent, with the turn and the cause named.
- ~1.7ms
- Added latency
Median overhead of the proxy on a 45KB request, measured against an instant local provider so nothing hides in it. A real round trip is hundreds of milliseconds, so this is a rounding error of the request it sits inside.
Three things your provider's dashboard cannot show you
- Silent cache breaks
- One reordered tool list or re-rendered history and the prefix stops matching. The bill roughly doubles for the rest of the session, no error is raised, and the aggregate on your dashboard looks like ordinary growth. Replay names the turn and the cause.
- No cost per task
- Spend by month is not a unit. Without a median and a p90 per task you cannot price a feature, forecast an unattended agent, or tell growth from a subsidy. Replay computes both from sessions you have already run.
- Secrets in tool output
- Keys and connection strings inside tool results ride along in every subsequent prompt. Replay's masking is a second layer for this, and it is experimental: read what it cannot catch before you rely on it.
Measured 2026-09-06
Parallel subagents don’t share the cache. Each one pays for it again.
When an agent fans out into parallel lanes, the siblings all carry the same prefix — and none of them reads it from the cache. Each writes it. A cache write bills at 1.25× and a read at 0.1×, so a sibling that writes pays 12.5× what one that reads would.
- lanes
- measured · ceiling · ratio
- 2+ · 483 groups
- 1.68× · 1.85× · 0.91
- 3+ · 79 groups
- 2.56× · 2.59× · 0.99
- 5+ · 24 groups
- 3.34× · 3.79× · 0.88
Read the middle column before the first one. The ceiling is fixed by the group size and the provider’s own 1.25 and 0.1 multipliers alone, and it is above 1 for every group larger than one. No corpus can produce a premium below 1, so the rise from 1.68× to 3.34× is the shape of the arithmetic and not a discovery about fan-out.
What is actually measured is the third column: how equal the sibling prompts turn out to be. It is about 0.9 and flat. The cost is real — five lanes genuinely are billed about 3.3× a shared-prefix baseline — but the honest claim is the price list plus one dispersion number, not a law of parallelism.
This page said otherwise for a few hours on 2026-09-06, and said it was robust because the figure barely moved across grouping windows from 30 to 300 seconds. That was not evidence either: neither the group size nor the multipliers depend on the window, so the number was never free to move. Corrected the same day. The correction, with the algebra and what would make it a finding — every input is already in the transcripts on your disk. One machine, one operator.
It shows its working before it offers an opinion
The first line is Replay proving it can reproduce what you were actually charged. Only then does it say what a different layout would have done. A tool that tells you what you should have done, without first showing it understood what you did, is guessing at your expense.
Tier: estimated (transcripts only)
Calibration: reproduced provider cache reads on 315/319 turns; 4 cache breaks
Rules: anthropic-2026-09-01; system prefix 39k (measured from the first cache read)
policy prompt tokens cached share vs as-run misses
as-run 22.87M 97% - 0
ttl-5m0s 22.87M 91% +35% 4
ttl-1h0m0s 22.87M 97% +0% 0
context-edit(keep=6,trigger=239k) * 20.98M 79% +206% 0
turn 32 at 22:08:56 (+2m30s): read 39k of 228k expected, 189k re-billed
cause: client re-rendered history after the system prefix
where: message 0 (user text) Figures from the published calibration corpus. Every number is labelled estimated when it came from a transcript or measured when it came off the wire, and that distinction is carried by the type system rather than by a convention someone might forget.
Three steps, and you have already done the first one
- 01
Nothing to instrument
Claude Code already writes a full transcript of every session to ~/.claude/projects/. Replay reads those files. There is no SDK, no wrapper, no flag to add to your workflow, and no first run where you get nothing because you had not started collecting yet. Your history is already there.
- 02
It reproduces the bill first
Before it offers an opinion it replays the session against the provider’s caching rules and checks its own answer against what you were actually charged. That match rate is the first line of every report. If it cannot reproduce your bill, it says so instead of quietly carrying on.
- 03
Then it scores the alternatives
Same session, different context layouts: a longer cache window, a shorter one, an editing policy that trims history at a threshold. Each comes back with what it would have cost and how many cache misses it would have caused, so the recommendation is a number rather than an opinion.
The failure path was built first
Most agent tooling has nowhere for "no" to happen. These are all off unless you turn them on, none of them alters a byte on the wire, and each refuses only the next request, never a response already in flight.
- Error budget
- Refuses the next request once too much of a session has gone to failed tools, failed edits and repeated identical calls. An agent stuck in a loop wastes money long before it has spent much.
- Loop detection
- Counts how many times in a row the agent has made the same call with the same input, then warns or blocks. A repeat from earlier in the session never counts.
- Circuit breaker
- Stops burning retries against a provider that is already saying no, and answers locally with Retry-After until the cooldown passes.
- Retry discipline
- A transport failure is only retried when the connection never opened. If any byte of the request already left, it may already have been billed, so it is not resent.
Everything else fails open, structurally rather than by a flag. The tap writes your bytes onward before it parses them. Retries sit below the proxy, so one physically cannot fire after a response has started. If Replay's own bookkeeping breaks, your traffic still flows.
It sits in your request path, so here is exactly what it does
- It forwards every request and response byte for byte, including streaming and cache markers. Two opt-in features modify traffic, and say so.
- It never reads your credential at all. There is no reference to any auth header anywhere in the source. It cannot log what it does not read.
- The ledger holds block kinds, sizes, timings and usage. No message text, ever, file paths are hashed, and the files are owner-only.
- It binds loopback only and refuses browser-originated requests. The proxy itself forwards your traffic and nothing else; the two commands that reach the network are ones you type.
Those four were checked by an adversarial reviewer who ran the proxy against a fake upstream rather than reading the documentation. The findings are published, including the ones that were not flattering.
What it costs, and what it does not do
One line, no account, no key.
Business Source License 1.1, converting to Apache 2.0 on 2029-09-06, the whole source on GitHub, nothing to sign up for and nothing to authenticate against, because the tool itself has no server to authenticate to. What happens to it commercially is an open question and I would rather say that than print a pricing table for products that do not exist.
One paid thing exists, and it is not selling. There is a hosted MCP server at redrobot.jp/mcp.json that serves this project’s own data to agents: the rules table, the current installer digest, a price lookup, and a tool that prices the tool definitions your session is already carrying — which is the one thing here you can use without installing anything. Four of its five tools are free. The fifth would sell the maintained rules feed over x402, and it refuses to quote a price at all, because that feed currently contains exactly the free feed and there is nothing to charge for. The refusal is a comparison the code runs before any price is named, not a promise in a document, and it stays until a maintained feed exists to differ from. Replay itself cannot pay for any of it: the binary holds no key and contains no code that can sign.
If you run agents across a team and want the figures in your own dashboards, the proxy already serves /replay/metrics on loopback and you can scrape it today. If you need more than that, the honest answer is a conversation, not a checkout button.
- Runs on
- macOS and Linux, amd64 and arm64. The installer detects musl and glibc rather than guessing.
- Depends on
- Nothing. The go.mod file is 45 bytes and there is no go.sum, because there is nothing to check.
- Sends
- Your requests to your provider, and nothing else anywhere.
What it is not, yet
This is early software, and the entire product is about numbers being believable. It would be a strange place to start overselling.
- Early release
- v0.5.0 is tagged and the installer downloads a signed binary, then runs it before reporting success. macOS and Linux only. The proxy has been run against the real provider for full sessions, and 0.4.0 was the release that made it measure parallel subagents correctly: before it, one lane’s numbers stood in for the whole session, and a headline of 98.8% was retracted to 4.2% the same day it shipped. Both numbers are in the commit history. It is still a young tool.
- One machine, however many sessions
- The corpus is 119 real sessions across 1,881 transcripts, which settles neither the sample size nor the sampling. They share an operating system, a client, and one person’s habits, so they are correlated no matter how many there are. The corpus says this about itself.
- Masking is a second layer
- It cannot catch a bare hex secret by shape, because a 32-character token and a git SHA are the same string to an entropy test. Read what it misses before you lean on it.
- One provider verified, a second only stubbed
- Replay models Anthropic’s caching and reads Claude Code transcripts, and that path is verified end to end. It also reads OpenAI-compatible traffic, the shape Cursor and DeepSeek speak, but that half has only ever been run against a test stub. Secret masking does not cover it, and the proxy says so out loud rather than letting you assume otherwise.
Questions people actually ask
Do I have to route my traffic through it?
No. Reading transcripts is the default and it needs no proxy at all. The proxy is the second mode, and it exists for one reason: a transcript tells you how many tokens were sent, while the wire tells you what the provider actually charged. Run it when you want measured numbers instead of estimated ones.
Does anything leave my machine?
Replay has no telemetry, no account, no first-run prompt that defaults to yes, and no install-time question. Four commands reach the network and you type all four: `rules --check-prices` fetches a public price database from GitHub, `probe --execute` sends billable measurement requests to your own provider on your own key after printing the plan and asking, `upgrade` fetches the release index and an archive from GitHub and then runs the binary it wrote, and `rules --update <url>` fetches from whatever host you name. One request is not typed: `replay burn` probes 127.0.0.1:11434 for a local Ollama on every run, and that never leaves the machine. The proxy forwards your own traffic and nothing else. Contributing writes a file to your disk and prints the path; the binary has no code that could send it.
Why should I believe the numbers?
Because you can check them, and because the tool checks itself in front of you. Every figure is tagged estimated or measured, the calibration line reports the match rate against your real bill on every run, and the published corpus documents where the provider’s own stated rules and the observed behaviour disagree.
What if it breaks?
Then your traffic still flows. The proxy writes your bytes onward before it parses them, and the retry logic sits below it so it physically cannot fire after a response has started. The parts that can say no are off by default, and each refuses only the next request.
Does it work with Cursor, DeepSeek or an OpenAI-compatible provider?
Partly, and the honest answer has two halves. Reading Cursor’s saved sessions cannot work: Cursor stores conversations in SQLite and records no cache accounting at all, so a reader would report spend and never waste. The proxy is the answer instead, and it reads OpenAI-compatible traffic at /v1/chat/completions, streaming included, with the spend cap, loop detector and error budget applied. That path is verified against a test stub and has not yet been run against a live OpenAI-compatible provider, and secret masking does not cover it. The proxy says so at runtime rather than letting you assume otherwise.
What does an AI coding agent actually cost per task?
On the maintainer’s own corpus, 119 sessions (1,881 transcripts, since a session writes one per lane), read on 2026-09-12, the median task cost $0.79 and the p90 cost $7.79, against a total of $4039.23. 5% of it was paid twice because a prompt cache broke and nothing said so. Those are one person’s numbers from one machine, which settles the sample size and not the sampling, so run it on your own sessions rather than trusting these.
Can it stop an agent running up a huge bill?
Yes, if you turn the guards on, and they are off until you do. A spend cap refuses the next request once a session or a UTC day passes a token or dollar limit, and the day counter survives a restart. A loop detector refuses a tool call repeating in the current run, and an error budget refuses a session that is mostly failing. Each answers locally with a reply shaped as Replay’s rather than the provider’s, so a local refusal is never mistaken for the provider saying no, and each can be waived for a single request with a header carrying a reason that gets logged.
Does it read my code or my prompts?
The ledger holds block kinds, sizes, timings and usage counts. No message text, ever. File paths are hashed, MCP server names are hashed, and the files are written owner-only. That protection is a POSIX one, which is part of why Windows is not supported: the checks that assert it have never passed there. Masking is a second layer on top of that, and the docs are specific about what it cannot catch.
Find the turn it broke
One line, no dependencies, and it reads sessions you have already run. If it finds nothing, that is a useful answer too, and it takes about a minute to get.
Before you trust it
- The installer, all of it install.sh
- The calibration corpus 119 sessions
- The adversarial security review findings
- Every surface a third party can see surfaces
Four documents, none of them flattering by design. If any of them changes your mind about running this, they have done their job.
Who built this
Replay is built and maintained by Daniel Saito at Red Robot K.K., a software studio in Tokyo. It came out of running coding agents on real client work and wanting to know where the money went, which is a less interesting origin story than most and happens to be the true one.
The command-line tool is free and the source is published. A coffee buys nothing and unlocks nothing; it is a thank-you, not a transaction. If that ever changes, this page will say so before anything else does.
GitHub issues and discussions are the fastest way to reach me about Replay itself. LinkedIn and X are the right doors for everything else.