Error Spike Right After a Deploy: How to Confirm the Release and Roll Back Fast
In this worked example, a deploy timestamp pins a 340% error spike to commit a7f2e19. Rollback takes 4 minutes. The fix takes longer.
Picture an incident like this one (an illustrative scenario, not a customer case). The page fires at 09:17 on a Thursday. Error rate on checkout — up 340% in the last 10 minutes. Three support tickets already open.
The on-call engineer has two browser tabs, a coffee, and a sinking feeling.
The team deployed 11 minutes earlier. Version a7f2e19. A "safe" change — removing a deprecated payment method that exactly 0 customers had used in the last 90 days. The PR got a quick review. Two thumbs up, ship it, go get breakfast.
Except the enum removal also deleted a fallback branch that caught malformed payment intents from the mobile app. An edge case. A very popular edge case, as it turns out.
The slow version of this incident takes 45 minutes: check the error tracker, check analytics, try to correlate timestamps by hand, argue about whether to roll back while still debugging.
The fast version starts from one fact. The deploy finished at 09:06, and the error rate was flat until 09:07. Error rate before: 0.4%. After: 1.76%. Session replays show users hitting "Complete Purchase" and getting a blank modal. The stack trace points to line 247 of PaymentProcessor.tsx.
Rollback to v2.14.2 starts at 09:21. Traffic is served from the old artifact at 09:24. Error rate drops to 0.5% by 09:28.
Four minutes from decision to fix. The actual fix still has to be written later, and if the mobile app needs an update too, that can take days. But production is stable. Customers can check out.
That's what a clean deploy record buys you. Peace of mind? No. Faster incident resolution? Yes.
The Pain: Error Spikes Without Context
Here's the problem with most error tracking setups: they tell you what broke, but not when — or more specifically, not which deploy broke it.
Your error tracker shows a spike in PaymentIntentError. Great. Now scroll through your deployment history. Was it the 9:06 deploy? The 8:45 deploy? The 7:30 deploy that you thought was fine but maybe wasn't?
The error count graph goes up. Your Slack is blowing up. Your VP of Engineering is asking "are we down?" in the way that means they're already drafting the customer email. And you're playing timestamp detective across three dashboards.
Confirming which release caused an incident can eat half an hour. That's not debugging — that's archaeology. And every minute you spend confirming is a minute customers spend failing to convert. Take your own average order value and a 10% checkout failure rate, multiply by a 30-minute incident, and look at the number. It's depressing.
The worse version: you can't confirm the release, so you roll back speculatively. You revert the last two deploys. Error rate drops. Victory? Maybe. Or maybe you just reverted a feature that was fine and the bug is still lurking.
Why Ad-Hoc Approaches Fall Apart
Checking the deploy timestamps by hand. Sure. If your error tracking tool and your deployment log are in the same timezone. If your CI timestamps match your observability tool's timestamps. If you have one deploy pipeline instead of three. If nobody deployed during the incident (they always do). If your error aggregation hasn't collapsed 4 hours of errors into a single issue. The manual timestamp approach works in toy examples. It falls apart when you're sweating.
Keeping a spreadsheet of deploys. It's exactly as useful as you'd expect. The spreadsheet is never current. The person who deployed forgot to update it. The timezone is wrong. During an incident, you're not opening a spreadsheet — you're panicking.
Rolling back whatever shipped last. Fine when exactly one thing shipped. Less fine when three services deployed in the same hour and you pick the wrong one.
Honestly? I think the spreadsheet approach is a symptom of a bigger problem: we treat observability as an afterthought instead of infrastructure. Hot take, but if you can't answer "which deploy caused this" in under 60 seconds, your monitoring isn't done.
What you actually need: a deploy record written automatically by CI, paired with error tracking and session replays in one tool. One timeline. No correlation guesswork across multiple dashboards.
The Pattern That Actually Works
The workflow below is built to keep time-to-recovery short for deploy-related incidents. Here's the anatomy of it.
Step 1: Every deploy leaves a record
Your CI pipeline writes a line the moment a deploy completes. Not starts — completes. The timing matters. The line needs four things: version, environment, who deployed, and a one-line message. Post it to a chat channel your on-call people already watch, or write it to wherever your team keeps its deploy log.
# .github/workflows/deploy.yml
- name: Deploy to production
run: ./deploy.sh
env:
APP_VERSION: ${{ github.sha }}
# Follow with a step that posts "version / environment / deployer / message"
# to your deploy channel, only if the deploy succeeded (if: success()).
The commit message is optional but useful. During an incident, seeing "Remove deprecated BACS payment method" right in the deploy channel saves you a git log lookup.
Step 2: Alert on error rate, not error count
Don't alert on absolute error counts. They scale with traffic, so they either fire constantly at peak or never at 3 a.m. Alert on the error rate for your critical paths (checkout, login, signup) over a short window, and set the threshold well above your normal baseline. Most observability tools with error tracking and alerting can express this rule. Route the alert to your incident channel.
A threshold of roughly double your usual rate is a sensible starting point for deploy-caused spikes. Pick a minimum number of events so a quiet service doesn't page you over three failed requests.
When a7f2e19 hit production and the rate jumped from 0.4% to 1.76%, a rule like that fires within a few minutes — as soon as enough affected requests exist to tell the difference from noise.
Step 3: The incident response flow
Page fires. Here's what happens next:
-
Open the deploy channel. See which release went live in the last 30 minutes. If there's exactly one, that's your prime suspect.
-
Compare the windows. Set the error view to the hour before the deploy and the hour after. Did the spike start at the deploy time, or earlier? A spike that began before the deploy points somewhere else.
-
Check which errors are new. What error types appeared after this deploy? What existing errors spiked? A brand-new error class starting at the deploy time is about as close to a smoking gun as you get.
-
Watch one session replay. Optional but often decisive. Seeing a user hit "Complete Purchase" and get a blank modal is faster than reading stack traces. Session replay supports privacy masking, so sensitive fields can stay out of the recording.
-
Decision point: rollback or not. If the deploy is the clear cause and you have a known-good previous version, rollback. If you're not sure, keep debugging — but set a timer. Five more minutes of diagnosis, max. Then decide.
For the a7f2e19 incident, steps 1-4 took under three minutes. The decision was obvious.
Step 4: Execute the rollback
Rollback means re-deploying the previous artifact, not reverting code. Code revert comes later, once you understand the fix.
If you're on Vercel, Railway, or Render: one click to redeploy a previous deployment. If you're on Kubernetes with ArgoCD or similar: sync to the previous commit. If you're managing your own deploy scripts: keep the last known-good artifact accessible and have a rollback.sh that points to it.
# Example: Manual rollback script
./rollback.sh v2.14.2
The rollback should trigger the same deploy-record step. You want a line that says "Rollback to v2.14.2" so your after-action review shows exactly when you recovered.
Step 5: Verify the rollback worked
Don't assume. Check the error rate for the window after the rollback. If v2.14.2 is healthy, error rate should drop within 5-10 minutes (depending on traffic volume and caching).
In the scenario above, error rate hits baseline by minute 7 post-rollback, and the "we're back" message goes out at 09:31, fourteen minutes from first page.
What This Requires (And Doesn't)
To make this work, you need:
-
Error tracking with session replays. When an error spikes, you need to see both the stack trace and a recording of what the user was doing. Most error trackers (Sentry, Datadog, JustAnalytics) offer both. JustAnalytics bundles them in one under-5KB script — the alternative is juggling separate tools and manually matching timestamps.
-
A deploy record. Your CI writes it on every successful deploy, one short step.
-
Rate-based alerts. Not absolute thresholds. The config is straightforward, but you have to actually set it up. Default alerts won't catch this.
-
A rollback mechanism that takes under 5 minutes. If rolling back requires a 15-minute CI build, your recovery will never be fast. Pre-built artifacts are your friend. Vercel, Netlify, Railway and Render all offer redeploying a previous deployment.
What you don't need:
- A dedicated SRE team. A small on-call rotation can run this workflow.
- Fancy ML-based anomaly detection. A simple "double the baseline" threshold is a good place to start. ML anomaly detection sounds cool in vendor demos, but I'd start with the dumb threshold. Your mileage may vary, but it's hard to beat for this job.
- A $10K/month observability bill. JustAnalytics Pro is $49/month ($39/month billed annually) with 1M events. The free tier (100K events/month) covers analytics; error tracking, session replay and alerts are Pro features.
What This Won't Fix
A deploy record plus a rate alert catches deploy-caused regressions. They don't help with:
-
Slow degradation over multiple releases. If P95 latency creeps up 20ms per release over two months, no single deploy triggers an alert. You need periodic baseline audits for this.
-
Infrastructure failures. Your database running hot isn't a deploy problem. The deploy record won't explain a spike if AWS is having a bad day.
-
Third-party outages. Stripe goes down, your checkout fails. The error rate spikes, but it doesn't line up with any deploy — and it stays high after you roll back. That's your clue it's not your code. (For deeper correlation, pairing this with uptime monitoring like JustAnalytics uptime checks helps isolate third-party failures.)
-
The root cause. The deploy record tells you which release broke things. It doesn't tell you why. That still requires reading stack traces, checking session replays, and occasionally staring at diffs. It removes the "which release?" question. The debugging still happens — just faster.
Quick Start: Get This Running Today
Whether you're on JustAnalytics or any error tracker with session replay, here's the 15-minute setup:
-
Add a deploy-record step to your CI. Post version, environment, deployer and message to your incident channel after each successful deploy.
-
Create an error-rate alert on your checkout or login path, with a threshold about double your normal rate and a minimum event count. Send it to the same channel as the deploy records.
-
Deploy something small. Watch the record land, then open the error view and compare the hour before with the hour after.
-
Watch a session replay from the error window to see what users experienced. This step often shortens diagnosis.
-
Test the rollback. Redeploy your previous release to confirm the workflow works. Don't wait for a real incident to discover your rollback script is broken.
For teams running several services, post one deploy record per service so every release lands in the same channel.
Frequently Asked Questions
How quickly can you detect an error spike after a bad release?
It depends on your alert window and traffic. With an error-rate alert on a 5-minute window and steady traffic, you can expect to hear about a regression within a few minutes of the first affected requests. Low-traffic services take longer because there is less data to compare.
What's the difference between rollback and revert for fixing a bad deploy?
Rollback re-deploys the previous known-good artifact without changing code history. Revert creates a new commit that undoes the changes, then deploys that new commit. Rollback is faster (no CI build step) but doesn't fix your main branch. Revert is slower but leaves your git history clean. For urgent production incidents, rollback first, revert later.
Why record the exact deploy time somewhere your whole team can see it?
Because the first question in any incident is "what changed?". If the answer is a timestamp in your CI log or a chat channel, you can line it up against the start of the error spike in a minute instead of reconstructing it from memory.
Can I do this with my existing CI/CD pipeline?
Yes. Any CI system that can run a script step (GitHub Actions, GitLab CI, CircleCI, Jenkins) can post a message with the version, environment and time after a successful deploy. That message is your deploy record.
Try JustAnalytics
All-in-one observability in one under-5KB script: cookieless analytics + error tracking + APM + session replay + uptime + structured logs. Replaces GA4 + Sentry + Datadog + Pingdom + LogRocket. Free tier (100K events/mo), Pro $49/month ($39 annual).
Author at JustAnalytics.