CookbookWork and teamsNo. 32
Incident runbooks and a postmortem librarywhat to do at 3 a.m., and what you learned
See it in know.sh
Runbooksledger-worker
3of 9
LedgerQueueLagHigh
Observation, key section, 1 highlight, 1 note, 2 sources, 412 words
What it means. The ledger consumer is more than 5,000 messages behind. Invoices are still accepted, but invoice emails and ledger totals are delayed until it catches up.
First checks. Open the ledger-worker dashboard. The pool comes first: panel “DB pool in use”.
First checks for LedgerQueueLagHigh, in order
Check the database pool first: at 100 per cent, escalate without restarting. Otherwise check the consumer is running and restart it if not. If a deploy went out in the last hour, ask its owner to roll back. If not, watch the lag for 20 minutes and escalate if it is still rising.
- LedgerQueueLagHigh pages
- Leads to Pool at 100%?
- Pool at 100%?
- Leads to Escalate, yes
- Leads to Consumer up?, no
- Consumer up?
- Leads to Restart the consumer, no
- Leads to Deploy this hour?, yes
- Restart the consumer
- Deploy this hour?
- Leads to Ask for a rollback, yes
- Leads to Watch for 20 minutes, no
- Ask for a rollback
- Watch for 20 minutes
- Leads to Escalate, still rising
- Escalate
```element flowchart
{
"caption": "First checks for LedgerQueueLagHigh, in order",
"description": "Check the database pool first: at 100 per cent, escalate without restarting. Otherwise check the consumer is running and restart it if not. If a deploy went out in the last hour, ask its owner to roll back. If not, watch the lag for 20 minutes and escalate if it is still rising.",
"direction": "TD",
"nodes": [
{
"id": "page",
"label": "LedgerQueueLagHigh pages",
"shape": "stadium"
},
{
"id": "pool",
"label": "Pool at 100%?",
"shape": "diamond"
},
{
"id": "running",
"label": "Consumer up?",
"shape": "diamond"
},
{
"id": "restart",
"label": "Restart the consumer",
"shape": "rectangle"
},
{
"id": "deploy",
"label": "Deploy this hour?",
"shape": "diamond"
},
{
"id": "rollback",
"label": "Ask for a rollback",
"shape": "rectangle"
},
{
"id": "watch",
"label": "Watch for 20 minutes",
"shape": "rectangle"
},
{
"id": "escalate",
"label": "Escalate",
"shape": "rectangle",
"emphasis": "key"
}
],
"links": [
{
"from": "page",
"to": "pool",
"line": "solid",
"head": "arrow"
},
{
"from": "pool",
"to": "escalate",
"label": "yes",
"line": "solid",
"head": "arrow"
},
{
"from": "pool",
"to": "running",
"label": "no",
"line": "solid",
"head": "arrow"
},
{
"from": "running",
"to": "restart",
"label": "no",
"line": "solid",
"head": "arrow"
},
{
"from": "running",
"to": "deploy",
"label": "yes",
"line": "solid",
"head": "arrow"
},
{
"from": "deploy",
"to": "rollback",
"label": "yes",
"line": "solid",
"head": "arrow"
},
{
"from": "deploy",
"to": "watch",
"label": "no",
"line": "solid",
"head": "arrow"
},
{
"from": "watch",
"to": "escalate",
"label": "still rising",
"line": "solid",
"head": "arrow"
}
]
}
```Commands. Read-only; each copies as it stands.
Read-only commands
List the consumer pods
Every pod should be Running with no recent restarts.
kubectl -n ledger get pods -l app=ledger-workerCount retries in the last 15 minutes
More than a few hundred means the consumer is retrying, not stuck.
kubectl -n ledger logs deploy/ledger-worker --since=15m | grep -c "retry"
Read-only commands
- List the consumer pods
Every pod should be Running with no recent restarts.
kubectl -n ledger get pods -l app=ledger-worker - Count retries in the last 15 minutes
More than a few hundred means the consumer is retrying, not stuck.
kubectl -n ledger logs deploy/ledger-worker --since=15m | grep -c "retry"
```element steps
{
"label": "Read-only commands",
"steps": [
{
"title": "List the consumer pods",
"body": "Every pod should be *Running* with no recent restarts.",
"code": "kubectl -n ledger get pods -l app=ledger-worker"
},
{
"title": "Count retries in the last 15 minutes",
"body": "More than a few hundred means the consumer is retrying, not stuck.",
"code": "kubectl -n ledger logs deploy/ledger-worker --since=15m | grep -c \"retry\""
}
]
}
```Escalation. Page the Payments platform secondary if lag is still rising after 20 minutes. Customer-facing impact goes to the incident lead.
Seen in. INC-2026-031, INC-2026-019.
INC-2026-031: why invoice emails were delayed by three hours
A fishbone diagram with the effect, invoice emails delayed three hours, at its head. Four categories feed the spine: the consumer (retries without backoff, one pool shared by all workers), alerting (lag alert fired after 38 minutes, threshold set in 2023), the runbook (restart was the first step, pool check missing) and the deploy (retry change shipped on a Friday, no load test).
Effect: Invoice emails delayed three hours
- Consumer
- Retries without backoff
- One pool for all workers
- Alerting
- Lag alert after 38 minutes
- Threshold set in 2023
- Runbook
- Restart was step one
- No pool check
- Deploy
- Retry change on a Friday
- No load test
```element fishbone
{
"caption": "INC-2026-031: why invoice emails were delayed by three hours",
"description": "A fishbone diagram with the effect, invoice emails delayed three hours, at its head. Four categories feed the spine: the consumer (retries without backoff, one pool shared by all workers), alerting (lag alert fired after 38 minutes, threshold set in 2023), the runbook (restart was the first step, pool check missing) and the deploy (retry change shipped on a Friday, no load test).",
"effect": "Invoice emails\ndelayed three hours",
"causes": [
{
"id": "consumer",
"label": "Consumer"
},
{
"label": "Retries without backoff",
"parent": "consumer"
},
{
"label": "One pool for all workers",
"parent": "consumer"
},
{
"id": "alerting",
"label": "Alerting"
},
{
"label": "Lag alert after 38 minutes",
"parent": "alerting"
},
{
"label": "Threshold set in 2023",
"parent": "alerting"
},
{
"id": "runbook",
"label": "Runbook"
},
{
"label": "Restart was step one",
"parent": "runbook"
},
{
"label": "No pool check",
"parent": "runbook"
},
{
"id": "deploy",
"label": "Deploy"
},
{
"label": "Retry change on a Friday",
"parent": "deploy"
},
{
"label": "No load test",
"parent": "deploy"
}
]
}
```How it works
When LedgerQueueLagHigh pages at 3 a.m., the link in the alert opens the service’s runbook: first checks as a flowchart, read-only commands that copy whole, and every past incident it paged for. Claude Code drafts the runbooks from your alert rules and each postmortem from your notes, and links the two.
Try this prompt
Made with
DocumentYour AI assistantElementsLinks between documentsPublic linkCampaigns