Debugging Production Issues: The Systematic Approach That Reduced Our MTTR by 70%
Production incidents are inevitable. Systems fail, dependencies go down, traffic spikes overwhelm capacity, and bugs slip through testing. What separates good teams from chaotic ones is not preventing all incidents — it is resolving them quickly when they occur.
Our mean-time-to-resolution (MTTR) used to be 2-3 hours. A typical incident went: someone notices something is wrong, panics, starts checking random things, maybe finds the cause, deploys a fix, and hopes it works. No structure, no systematization, lots of wasted time.
After implementing a systematic approach, our MTTR dropped to 30-45 minutes. Here is the system.
The Incident Response Framework
When something breaks, follow this sequence:
Each step has specific actions. Following the sequence prevents the panic-driven, random-checking approach that wastes time.
Step 1: Detect and Classify
How you detect: automated alerts (Sentry error spike, uptime monitor failure, performance degradation alert), user reports (support tickets, social media mentions), or manual discovery (team member notices something wrong).
Classification determines urgency:
Severity 1 (Critical): site is completely down, or a critical feature (login, payments) is broken for all users. Drop everything.
Severity 2 (High): a feature is broken for a subset of users, or performance is severely degraded. Address within 30 minutes.
Severity 3 (Medium): a non-critical feature has issues, or errors are occurring but users are not visibly affected. Address within a few hours.
Classification prevents over-reaction (treating a minor bug as an emergency) and under-reaction (treating a site outage as a minor bug).
Step 2: Communicate
Before investigating, communicate: post in the incident channel that there is an issue, what severity, and who is investigating. This prevents: multiple people investigating the same thing, people wondering "is anyone working on this?", and stakeholders reaching out individually asking for updates.
For Severity 1: update every 15 minutes, even if the update is "still investigating, no root cause identified." Silence during incidents creates more anxiety than bad news.
Step 3: Investigate Systematically
This is where most teams waste time. Instead of randomly checking things, follow the investigation hierarchy:
What changed recently? In the majority of incidents, the cause is something that changed in the last 24 hours: a deployment (new code introduced a bug), a configuration change (environment variable modified), a dependency update (third-party service changed behavior), or a traffic pattern change (sudden spike overwhelming capacity).
Check: recent deployments (git log, deployment history), recent configuration changes (environment variables, feature flags), dependency status (status pages of services you depend on), and traffic patterns (unusual spikes or patterns).
If the change is obvious (deployed 10 minutes ago, errors started 10 minutes ago): revert immediately. Investigate after service is restored. Reverting takes 2 minutes. Debugging while users suffer takes 30 minutes.
If the cause is not immediately obvious: narrow down systematically.
Where is the error occurring? Frontend (JavaScript errors), backend (API errors), database (slow queries, connection issues), or infrastructure (server unreachable, DNS issues)?
Check: error monitoring (Sentry — what are the actual error messages?), application logs (error details with stack traces), database monitoring (slow queries, connection pool exhaustion), and infrastructure metrics (CPU, memory, disk, network).
What specific error? Read the actual error message. Not the user-facing "something went wrong" — the actual stack trace in Sentry. The error message usually points directly to the cause.
Step 4: Fix or Mitigate
Once you identify the cause, you have two options:
Fix: if the fix is quick and low-risk (a one-line code change, reverting a deployment), implement the fix directly.
Mitigate: if the fix requires investigation or is high-risk, implement a temporary mitigation: disable the broken feature (feature flag), route traffic away from the broken service, increase resource limits if the issue is capacity-related, or enable a fallback mechanism.
The goal is: restore service first, perfect fix later. A mitigation that restores service in 5 minutes is better than a perfect fix that takes 2 hours while users suffer.
Step 5: Verify
After deploying the fix or mitigation: monitor error rates (do they drop?), check affected features manually, and verify from multiple locations (not just your machine).
Declare the incident resolved only when: the error rate returns to baseline, affected features work correctly, and no new errors are appearing.
Step 6: Post-Incident Documentation
After resolution (not during the incident), document: what happened (timeline of events), why it happened (root cause), how it was resolved (what fix or mitigation was applied), how to prevent recurrence (action items), and what went well and what could improve in the response.
This documentation: prevents the same incident from happening again, improves the team's incident response skills, creates institutional knowledge that survives team changes, and identifies patterns (if similar incidents keep happening, there is a systemic issue).
The Tools That Enable This
Error monitoring (Sentry): tells you what errors are occurring, how many users are affected, and provides stack traces for investigation.
Uptime monitoring (Better Uptime, Pingdom): alerts when the site is unreachable. Catches total outages immediately.
Application Performance Monitoring: tracks response times, identifies slow endpoints, and alerts on degradation.
Deployment tracking: knowing what deployed and when is critical for correlating incidents with changes.
Status page (Instatus, Statuspage): communicate with users during incidents. They see the status without contacting support.
Incident Patterns and Prevention
After 20+ incidents, patterns emerge:
60% are caused by deployments: new code introduces a bug, a missing environment variable, or an incompatible database migration. Prevention: better testing, staged rollouts, and instant rollback capability.
20% are caused by dependency failures: a third-party service goes down, a database exhausts connections, or a CDN has issues. Prevention: circuit breakers, fallback mechanisms, and connection pooling.
15% are caused by traffic spikes: unexpected load exceeds capacity. Prevention: auto-scaling, rate limiting, and load testing.
5% are novel failures: genuinely unexpected combinations of circumstances. These are unavoidable — the goal is detecting and resolving them quickly.
Building the Muscle
Incident response is a skill that improves with practice. Early incidents are chaotic — you do not know what to check, where to look, or how to communicate. After 10 incidents following the systematic approach, it becomes natural: detect, classify, communicate, investigate (what changed? where? what error?), fix or mitigate, verify.
The system eliminates panic. When you know the steps and have practiced them, incidents become problem-solving exercises rather than emergencies. You move methodically instead of frantically. And methodical beats frantic every time.
Written by AIDToolStack Editorial
The AIDToolStack editorial team reviews developer tools, AI products, and MCP servers with hands-on testing and honest assessments. We use the tools we review every day in production.
References & Further Reading
Related Posts
Sponsor Our Newsletter
Reach thousands of developers who are actively evaluating AI tools, MCP servers, and dev infrastructure. Our weekly newsletter goes to engaged technical decision-makers.
All sponsored content is clearly labeled per our editorial policy.