A cost curve stepped up and you need to know which release did it. This is a correlation problem, and it is more tractable than it looks — provided you resist the urge to start reading diffs.
Get the timestamp before you get the theory
The first job is not "which deploy looks suspicious". It is "when exactly did the number change".
Pull the affected service at the finest granularity available. Daily is usually enough to identify the day; hourly, where the provider offers it, will often land you within the deploy window itself.
You are looking for the inflection point — the last normal interval and the first abnormal one. Write both down. Every subsequent step is a filter against that pair.
Understand the lag before you match
Cost data does not appear the moment the cause does, and the delay varies enough to mislead you.
Compute and inference show up fastest — the cost is incurred as the work happens, and typically surfaces within a few hours.
Storage lags by design. A change that starts accumulating data produces a curve that bends days later, so the deploy you want may be a week before the visible inflection.
Data transfer is the worst case: often aggregated, sometimes reported daily rather than hourly, and frequently attributed to a different service from the one that caused it.
If you match deploys to the exact hour of the visible change, you will systematically pick the wrong deploy for storage and transfer problems. Widen the window to a day either side and accept more candidates.
List every change in the window
Deploys are only one class of change. In a window either side of the inflection, gather:
- Application deploys, with timestamps
- Infrastructure-as-code applies
- Console or CLI changes, from the provider audit log
- Configuration or feature-flag changes
- Scheduled job additions, including anything that runs weekly rather than daily
- Dependency or SDK upgrades
The last two are the ones teams forget. A weekly job added on a Tuesday produces a spike the following Tuesday, which correlates with nothing that happened that day.
Use unit cost to break the tie
When several candidates survive, cost per request separates them.
If total cost rose and cost per request stayed flat, the deploy increased traffic or usage. The system is behaving as designed and doing more of it.
If cost per request rose, the deploy changed how work is done — a larger model, a bigger prompt, more retries, an extra call in a hot path, a query without an index. This is almost always the deploy you are looking for, and it is the one worth reverting.
This single ratio eliminates most false positives, because it distinguishes growth from regression.
Check the shape against the candidate
A deploy that adds a per-request call produces a change proportional to traffic — the curve should have the same daily shape as before, scaled up. If the new curve is flat while traffic varies, the cause is something that runs regardless of traffic: a scheduled job, an idle resource, a subscription.
A shape mismatch means you have the wrong candidate, no matter how plausible the diff looks.
Confirm rather than assume
The confirmation step is usually skipped and it is the one that prevents a wasted revert. Options, in order of confidence:
Revert in a low-traffic window and watch whether cost returns to baseline. Slowest, most conclusive.
Check whether a canary or a single region shows the same unit-cost change. If the deploy went out progressively, the cost curves should be staggered in the same order.
Reproduce the specific code path in a test environment and measure the calls it makes. Fastest, and sufficient when the mechanism is obvious once named.
Make the next one easier
Everything above is archaeology, and it is slow because the two datasets live apart: deploys in one system, cost in another, joined by hand.
Two things shorten it permanently. Tagging by service and environment means a cost change is already attributed when you start, so the account-and-service isolation step disappears. A daily anomaly signal means you are investigating a change from yesterday rather than from three weeks ago, while the deploy is still in someone's memory.
StackSpend attributes spend by tag and flags deviations against a per-service baseline the day they appear, so the correlation window is hours rather than a billing cycle.
FAQ
How long after a deploy does a cost change appear?
It depends on the service. Compute and inference costs usually surface within a few hours; storage bends the curve over days; data transfer is often aggregated and may not be attributable to an hour at all. Widen your correlation window accordingly.
Can I correlate deploys to cost automatically?
Partly. Tagging resources by service and environment gets you attribution, and comparing cost per request against deploy timestamps gets you correlation. Full automatic attribution requires the deploy system and the cost data to share an identifier, which most stacks do not have out of the box.
What if several deploys landed the same day?
Use cost per request to separate them. A deploy that raised unit cost changed how work is done; one that raised total cost with flat unit cost simply increased volume. Usually only one candidate did the former.
Why does the cost spike not line up with any deploy?
Look for scheduled jobs, especially weekly or monthly ones, and for changes made directly in the provider console rather than through your pipeline. Both produce cost changes with no corresponding release.

