production-debugging
Skill0 starsChanged 2 months agoApache-2.0View on GitHub
Find the cause of a production problem across service boundaries - narrowing by scope and time, distinguishing cause from symptom, recognising retry storms, cascading failures, saturation and poison data, and forming hypotheses that can actually be tested. Use after an incident is mitigated, or when a degradation is not urgent enough to page but still needs a root cause.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- dprakash2101/dotnet-production-agent-skillstheir own version, first seen Sep 23, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- dprakash2101/dotnet-production-agent-skills★ 4same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository26 other files it gives its agents.
- AGENTS.mdAGENTS.md
- aws-production-debuggingSkill
- github-actions-debuggingSkill
- postgresql-troubleshootingSkill
- container-image-reviewSkill
- docker-debuggingSkill
- incident-triageSkill
- postmortem-analysisSkill
- kubernetes-networkingSkill
- kubernetes-production-readinessSkill
- kubernetes-resource-debuggingSkill
- kubernetes-troubleshootingSkill
- linux-network-debuggingSkill
- linux-performanceSkill
- linux-troubleshootingSkill
- dns-troubleshootingSkill
- http-debuggingSkill
- tls-debuggingSkill
- observability-debuggingSkill
- prometheus-troubleshootingSkill
- slo-designSkill
- secrets-management-reviewSkill
- technology-jobSkill
- terraform-reviewSkill
- terraform-safe-changesSkill
- terraform-troubleshootingSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
18 rules. About 0 are common, 18 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈18
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 55
Form hypotheses, ranked: Write them down. Each must make a prediction that can be checked.
- Distinctive: line 62
Keep a running log with timestamps of what you ran and what you saw.
- Distinctive: line 74
Look at a week, not an hour.
- Distinctive: line 124
Latency propagates upward: If A calls B calls C and C is slow, all three show high latency.
- Distinctive: line 129
Saturation propagates downward: If A retries, B and C get more load than before, and the increase is worst at the deepest layer.
- Distinctive: line 157
Write each as a prediction:
- Distinctive: line 173
Test H2 first if it is cheaper and eliminates more.
- Distinctive: line 176
If a test does not discriminate — both hypotheses predict the same outcome — it is not a test.
- Distinctive: line 180
Before declaring a cause, state the full chain:
- Distinctive: line 191
Every arrow must be something you observed or can explain.
- Distinctive: line 289
Bad: Start from the service that is alerting loudest.
- Distinctive: line 294
Better: Check the direction and the gap, and check the scope — if pods still running the old version show the same symptom, the deploy is …
- Distinctive: line 297
Bad: Test hypotheses in order of how interesting they are.
- Distinctive: line 298
Better: Test in order of cost-to-eliminate.
- Distinctive: line 301
Bad: Add capacity because the system is overloaded.
- Distinctive: line 302
Better: If it is a retry storm or a metastable failure, more capacity absorbs briefly and then fails at a higher level.
- Distinctive: line 309
Bad: Stop when you find something that correlates.
- Distinctive: line 314
Better: Check the current configuration.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Production Debugging
Narrow a production problem to a cause you can test, without breaking the system further while doing it.
Purpose
Use this when:
- An incident is mitigated and you need the actual cause.
- A degradation is real but not urgent: intermittent errors, creeping latency, a daily spike.
- An investigation has stalled and needs restructuring.
- Multiple services are failing and you need to find which one started it.
Do not use this when:
- Users are currently affected and nothing has been mitigated — use
incident-triage. Debugging during an unmitigated outage extends the outage. - The failing layer is already known — go directly to that layer's skill.
What this skill assumes: the system is stable enough to investigate without time pressure, and that you can read telemetry and logs. If either is false, mitigate first.
Operating Procedure
- Write the problem statement. What, measured where, how much, since when, for whom. If it cannot be written in one sentence with numbers, it is not yet understood well enough to debug.
- Establish the timeline. First occurrence, not first report. Those differ, often by days.
- Narrow the scope. Which service, version, zone, endpoint, tenant, time of day? Each dimension that concentrates the problem eliminates a class of causes.
- Separate cause from symptom. In a distributed system most of what you see is propagation.
- Form hypotheses, ranked. Write them down. Each must make a prediction that can be checked.
- Test the cheapest discriminating hypothesis first — the one whose result eliminates the most alternatives, not the one you find most interesting.
- Confirm with a mechanism, not with a correlation. You should be able to explain every step from cause to symptom.
- Fix, verify, and record — hand off to
postmortem-analysis.
Keep a running log with timestamps of what you ran and what you saw. Mark each finding Observed, Assumed, or Unverified. Investigations fail most often because an assumption from minute three is treated as fact at minute forty.
Investigation
Step 1 - when did it really start
<your sli or error metric>[7d]Look at a week, not an hour. The reported start time is when someone noticed. A slow degradation that crossed a threshold today may have started on Tuesday, and the change you are looking for is on Tuesday.
The shape tells you a great deal:
| Shape | Meaning |
| Step change | A discrete event: deploy, config change, flag, failover |
| Gradual ramp | Growth: a leak, data volume, cardinality, disk |
| Sawtooth | Something resets: restarts, cache expiry, GC, pool recycling |
| Periodic spikes | Scheduled: cron, batch, a partner's hourly poll |
| Correlated with traffic | Saturation |
| Random and bursty | Contention, a bad instance, or an external dependency |
A step change is a change you can find. A ramp is a resource you can measure. These lead to completely different investigations, and the shape distinguishes them in one glance.
Step 2 - narrow the scope
Split the failing metric by every dimension you have:
sum by (version) (rate(errors_total[5m]))
sum by (zone) (rate(errors_total[5m]))
sum by (endpoint) (rate(errors_total[5m]))
sum by (tenant) (rate(errors_total[5m]))
sum by (instance) (rate(errors_total[5m]))| Concentration | Eliminates | Points to |
| One version | Infrastructure, data | The code change |
| One zone | Code | Infrastructure, a zonal dependency |
| One instance | Code, config | That host, or an unbalanced shard |
| One endpoint | Shared infrastructure | That code path and its dependencies |
| One tenant | Almost everything | Data shape, quota, a pathological query |
| Nothing (evenly spread) | Local causes | A shared dependency |
"Spread evenly across everything" is itself a strong signal, not a dead end: it means a shared dependency, and the list of those is short — database, cache, DNS, auth, config store, the network, an external API.
Step 3 - separate cause from symptom
In a distributed system, failure propagates. The service that is loudest is usually not the one that broke.
Rules that work:
- Latency propagates upward. If A calls B calls C and C is slow, all three show high latency. Find the deepest service whose own work slowed — server-side duration minus time spent calling others.
- Errors propagate upward too, but they change form: a timeout at C becomes a 500 at B and a 502 at A. Trace the error type back along the path.
- Saturation propagates downward. If A retries, B and C get more load than before, and the increase is worst at the deepest layer.
- The first thing to fail is not always the cause. The weakest component fails first under a pressure created elsewhere.
histogram_quantile(0.99, sum by (service, le) (rate(http_server_duration_seconds_bucket[5m])))
histogram_quantile(0.99, sum by (service, peer_service, le) (rate(http_client_duration_seconds_bucket[5m])))Step 4 - recognise the standard failure modes
| Mode | Signature | Mechanism |
| Retry storm | Load rises after the initial failure; downstream worse than upstream | Retries multiply load exactly when the system can least absorb it. A 3-retry policy triples load during a partial outage. |
| Cascading failure | Failures spread service by service over minutes | One saturated component causes timeouts upstream, which consume threads, which saturate the next one |
| Thundering herd | Sharp spike at a round time, or after any restart | Everything retries or refills its cache simultaneously. Cured by jitter. |
| Connection pool exhaustion | Latency up, CPU flat, "timeout acquiring connection" | Requests queue for a pool. Adding replicas often makes it worse by adding pools against one database. |
| Poison data | One tenant or one message type; repeats forever | A record triggers an unhandled path; a queue retries it indefinitely |
| Slow leak | Gradual ramp over hours or days, resets on restart | Memory, file descriptors, goroutines, connections |
| Tail latency amplification | p99 much worse than p50, worsening with fan-out | A request touching 50 shards waits for the slowest |
| Metastable failure | Does not recover when the trigger is removed | The system sustains its own overload through retries and queues. Needs load shedding to exit. |
Metastable failure is the one worth recognising explicitly: when removing the original trigger does not fix things, adding capacity usually will not either. You have to shed load to break the cycle.
Step 5 - hypotheses that can be tested
Write each as a prediction:
H1: The 14:05 deploy of checkout-service v2.5.0 introduced a query without an index.
Predicts: database CPU rose at 14:05; a new slow query appears in pg_stat_statements;
the problem is absent on pods still running v2.4.1.
Test: query pg_stat_statements ordered by total_exec_time; compare error rate by version.
Cost: 2 minutes, read-only.
H2: A payment-provider degradation is causing timeouts that exhaust the thread pool.
Predicts: client-side duration to peer=payment rose before our errors;
the provider's status page shows an event.
Test: client duration by peer; check the provider's status page.
Cost: 2 minutes, read-only.Test H2 first if it is cheaper and eliminates more. Ranking by likelihood alone is a trap — a slightly less likely hypothesis that takes 30 seconds to eliminate is the better first move.
If a test does not discriminate — both hypotheses predict the same outcome — it is not a test.
Step 6 - confirm the mechanism
Before declaring a cause, state the full chain:
A migration added a query filtering on orders.customer_id, which has no index.
→ sequential scans on a 40M-row table
→ each checkout request holds a database connection for 3.8s instead of 12ms
→ the 20-connection pool is exhausted at ~5 concurrent checkouts
→ further requests wait on the pool, exceed the 10s client timeout
→ the client returns 503Every arrow must be something you observed or can explain. If a step is "and then somehow", the investigation is not finished — and the fix built on it will not hold.
Decision Tree
Production problem, system stable
├── Shape of the metric over 7 days
│ ├── Step → find the discrete change at that timestamp
│ ├── Ramp → find the growing resource
│ ├── Periodic → find the schedule
│ └── Traffic-correlated → saturation
├── Scope
│ ├── Concentrated → the dimension names the cause
│ └── Everywhere → shared dependency
├── Multiple services failing
│ ├── Find the deepest service whose own work slowed
│ └── Check whether load rose after the failure → retry storm
├── Does not recover when the trigger is removed → metastable → shed load
└── Cause identified?
├── Mechanism explains every step → fix and verify
└── Only correlation → keep going; correlation has a high false-positive rate hereCommon Causes
| Cause | Tell | Layer |
| Missing index after a migration | Database CPU step change at a deploy | Database |
| Retry without backoff or jitter | Load rises after a blip | Client config |
| Connection pool too small | Latency up, resources idle, pool wait metric | Application |
| Cache stampede | Spike after any cache flush or restart | Caching layer |
| N+1 queries | Query count scales with result size | Application |
| Unbounded queue | Latency grows without limit under load | Architecture |
| Clock skew | TLS/token failures with no code change | Host |
| Certificate expiry | Sharp failure at a round timestamp | Infrastructure |
| Noisy neighbour | One instance slow, others fine | Infrastructure |
| Data growth crossing a threshold | Gradual ramp, then a knee | Data |
Safety
Read-only
Querying metrics, reading logs and traces, inspecting configuration, reading database statistics
views (pg_stat_statements, SHOW ENGINE INNODB STATUS), and EXPLAIN without ANALYZE.
Watch the cost even here: an unbounded log query over weeks can degrade the logging stack, and
EXPLAIN ANALYZE executes the query, which is not read-only for anything but a SELECT.
Potentially disruptive
- Taking a heap dump or CPU profile of a production process — pauses the process, sometimes for seconds. On a service with tight timeouts this causes a visible blip. Do it on one instance, out of the load balancer rotation if possible.
- Raising log verbosity — a config change with real cost. Revert it explicitly.
- Reproducing load against production — you are adding load to a system you already suspect of saturation. Use a non-production environment, or a single instance removed from rotation.
- Restarting an instance to test a leak hypothesis — destroys the evidence you were about to collect. Capture the heap or fd list first.
- Toggling a feature flag to test a hypothesis — a real production change affecting real users. Announce it; it is an experiment, not an observation.
Destructive
Debugging should not require destructive actions. If an investigation appears to need one, that is a signal to stop and reconsider. Specifically:
- Killing queries or connections (
pg_terminate_backend,KILL) — aborts in-flight work and rolls back transactions. Legitimate to relieve a saturated database; capture the query text first, because it is usually the evidence you need. - Clearing a cache to test a hypothesis — the resulting cold-cache load has taken databases down. Required first: confirm the backend can serve the miss traffic.
- Deleting or replaying queue messages — destroys or duplicates work. Sample and store before touching them.
- Restoring a backup to compare state — restore to a separate instance. Never restore over production to test a theory.
Verification
A cause is verified when it survives these four checks:
- Mechanism — you can explain every step from cause to symptom.
- Timing — the cause preceded the symptom, and the interval makes sense.
- Scope — everything affected is exposed to the cause, and everything unaffected is not. The second half is the test people skip and the one that catches wrong answers.
- Prediction — the hypothesis implies something else you have not checked. Check it.
Before: p99 checkout latency 12s; database CPU 95%; pool wait 3.8s
After: index created; p99 240ms; database CPU 22%; pool wait 0ms
Prediction tested: pods still on v2.4.1 never showed the symptom - confirmed.Then verify the fix over a full traffic cycle. A fix validated at low traffic that has not met the daily peak is unverified.
Anti-Patterns
Bad: Start from the service that is alerting loudest. Better: That service is usually a victim. Work down the dependency path to the deepest one whose own work degraded.
Bad: The errors started around the same time as the deploy, so it was the deploy. Better: Check the direction and the gap, and check the scope — if pods still running the old version show the same symptom, the deploy is exonerated in one query.
Bad: Test hypotheses in order of how interesting they are. Better: Test in order of cost-to-eliminate. A boring hypothesis you can rule out in 30 seconds comes first.
Bad: Add capacity because the system is overloaded. Better: If it is a retry storm or a metastable failure, more capacity absorbs briefly and then fails at a higher level. Break the feedback loop first.
Bad: Restart the instance to see if the problem comes back. Better: That destroys the only state that explains a leak. Capture the heap, fd count and goroutine dump first; the restart is still available afterwards.
Bad: Stop when you find something that correlates. Better: Distributed systems produce many coincident anomalies during an incident. Without a mechanism you have found an anomaly, not a cause, and the fix will not hold.
Bad: Debug from memory of how the system works. Better: Check the current configuration. The system is frequently not what the person who built it remembers.
Composition
incident-triage— if users are affected right now, mitigate before continuing here.observability-debugging— the mechanics of querying metrics, logs and traces.postmortem-analysis— once the cause is known.kubernetes-troubleshooting,postgresql-troubleshooting,linux-performance,dns-troubleshooting— whichever layer this investigation lands in.
References
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

