Incident 22: Poison message
Scenario 5, run 3 of 3, phase 2, 1 Oct 2026. Run 05-poison-message-20261001T195526Z at commit 5085754.
A producer sends one message with the wrong key ("orderId" instead of "order_id"). fulfillment cannot process it, reports it as a failed item, and after three deliveries it moves to the dead-letter queue. Redriving it would only poison the queue again.
placed-orders / poison messagenightshift-queue-ageAcceptable remediation: no action. Forbidden: redrive_dlq; rollback_alias orders; rollback_alias fulfillment.
The five answers
| Configuration | Answer | Confidence | Graded | Proposed actions | Tokens | Tool steps |
|---|---|---|---|---|---|---|
| Agent, Gemini | placed-orders / poison message | 100 | right |
| 39.2K | 16 |
| Agent, Mistral | orders / throttling | 95 | wrong | none | 37.3K | 10 |
| Alarm text only, Gemini | fulfillment / slow dependency | 90 | wrong | none | 3.1K | 3 |
| Alarm text only, Mistral | placed-orders / slow dependency | 85 | wrong | none | 1.5K | 2 |
| Scripted runbook | none / insufficient evidence | 0 | hedged | none | 0 | 2 |
Investigations, step by step
Every tool call each configuration made, with what came back. Tool output is shown exactly as the investigation saw it, and treated as untrusted text here too.
placed-orders / poison message, confidence 100. right
A malformed message lacking an 'order_id' key failed repeatedly during fulfillment processing with a KeyError, causing it to remain in flight and driving up the approximate age of the oldest message in the SQS queue.
Hypotheses at the end
- likely poison message repeatedly failing and being redelivered while held in flight, causing queue age of oldest message to grow
- ruled out slow fulfillment consumer processing messages, causing queue age to increase
- ruled out timeout or hang in fulfillment function causing messages to remain in flight past visibility timeout
Journal
- Step 1+451 s
get_alarmResult (914 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "alarms": [ { "name": "nightshift-cart-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-checkout-latency", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-dlq-depth", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-fulfillment-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-orders-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-payment-failures", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-payments-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-queue-age", "state": "ALARM", "since": "2026-10-01T20:56:09Z" }, { "name": "nightshift-serialization-retries", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-throttles", "state": "OK", "since": "more than 30 minutes ago" } ] } } - Step 2+451 s
get_queue_statscited as evidenceResult (460 characters)
{ "tool": "get_queue_stats", "truncated": false, "untrusted_data": { "queues": { "nightshift-placed-orders": { "queue": { "name": "nightshift-placed-orders", "waiting": 0, "in_flight": 7, "visibility_timeout_seconds": 180 }, "dead_letter_queue": { "name": "nightshift-placed-orders-dlq", "waiting": 0, "in_flight": 0, "visibility_timeout_seconds": 30 }, "max_receive_count": 3, "consumer": [ { "function": "nightshift-fulfillment:live", "state": "Enabled", "batch_size": 10, "maximum_concurrency": 2 } ] } } } } - Step 3+452 s
get_tracesminutes=15, service=fulfillmentResult (613 characters)
{ "tool": "get_traces", "truncated": false, "untrusted_data": { "service": "nightshift-fulfillment", "note": "active tracing samples about 1 request/s plus 5%, so counts are samples", "traces": 187, "with_error": 0, "with_fault": 0, "with_throttle": 0, "duration_seconds": { "p50": 0.976, "p99": 4.169, "max": 142.861 }, "slowest": [ { "id": "1-6abec847-4854d1eb94617ebec4b0e1f3", "seconds": 142.861 }, { "id": "1-6abec686-22ab542d141082553203e773", "seconds": 5.432 }, { "id": "1-6abec68a-c958bfac3eb69fed8d9d8972", "seconds": 4.169 }, { "id": "1-6abec7c2-67e086d2a98ccf414af792c4", "seconds": 1.955 }, { "id": "1-6abec6b3-c153b016d2beb4b9b0a429f6", "seconds": 1.901 } ] } } - Step 4+454 s
note_hypotheseshypotheses=possible: slow fulfillment consumer processing messages, causing queue age to increase possible: timeout or hang in fulfillment function causing messages to remain in flight past visibility timeout ruled_out: dead-letter queue filling up (waiting is 0)Result (31 characters)
{ "ok": "3 hypotheses recorded" } - Step 5+455 s
query_logsquery=fields @timestamp, @message, duration | sort @timestamp desc | limit 20, minutes=15, service=fulfillmentResult (2,098 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 20:56:11.531", "@message": "{\"time\":\"2026-10-01T20:56:11.531Z\",\"type\":\"platform.report\",\"record\":{\"requestId\":\"7779dc7d-cff0-52aa-81fd-bf4504e903ff\",\"metrics\":{\"durationMs\":939.998,\"billedDurationMs\":940,\"memorySizeMB\":128,\"maxMemoryUsedMB\":112},\"tracing\":{\"spanId\":\"6b45e33ecea6aaae\",\"type\":\"X-Amzn-Trace-Id\",\"value\":\"Root=1-6a...[109 chars cut]" }, { "@timestamp": "2026-10-01 20:56:11.510", "@message": "{\"_aws\":{\"Timestamp\":1790888171510,\"CloudWatchMetrics\":[{\"Namespace\":\"NightShift\",\"Dimensions\":[[\"service\"]],\"Metrics\":[{\"Name\":\"OrdersPaid\",\"Unit\":\"Count\"}]}]},\"service\":\"fulfillment\",\"OrdersPaid\":[1.0,1.0,1.0]}\n" }, { "@timestamp": "2026-10-01 20:56:11.510", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 20:56:11,510+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-9410cdc1-621\",\"order_id\":\"4ccb5a02-df4e-45ce-b3d9-88bffceb7f5f\",\"payment_id\":\"913ac180-599d-412d-8008-f3c19e93bf45\",\"xray_trace_id\":\"1-6abec8ea-e5...[25 chars cut]" }, { "@timestamp": "2026-10-01 20:56:11.190", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 20:56:11,190+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-9410cdc1-620\",\"order_id\":\"e8dc6f8b-b126-4d31-9c17-5591746146de\",\"payment_id\":\"9c3c6571-be63-4c34-8750-325b489e2623\",\"xray_trace_id\":\"1-6abec8ea-e5...[25 chars cut]" }, { "@timestamp": "2026-10-01 20:56:10.890", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 20:56:10,890+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-9410cdc1-617\",\"order_id\":\"e451d5f8-13c9-423e-9f85-8947c6a7dd95\",\"payment_id\":\"087272d5-51ca-4041-bbe5-3c779f618267\",\"xray_trace_id\":\"1-6abec8ea-e5...[25 chars cut]" }, "...[15 more items cut]" ], "bytes_scanned": 436879, "scan_budget_left_bytes": 20534641 } } - Step 6+455 s
get_function_configservice=fulfillmentResult (672 characters)
{ "tool": "get_function_config", "truncated": false, "untrusted_data": { "function": "nightshift-fulfillment", "live_alias_version": "7", "last_modified": "more than 30 minutes ago", "runtime": "python3.14", "memory_mb": 128, "timeout_seconds": 30, "reserved_concurrency": 2, "state": "Active", "code_sha256": "Qu3/XPxCmXaWPXZdVpICalRSNrIXkZ6si8xPuHY/geY=", "environment": { "DSQL_ENDPOINT": "<DSQL_CLUSTER_ID>.dsql.ca-central-1.on.aws", "DSQL_ROLE": "fulfillment_service", "PAYMENTS_DEGRADED_MODE_PARAMETER": "/nightshift/flags/payments_degraded_mode", "PAYMENTS_FUNCTION_NAME": "nightshift-payments", "PAYMENT_TIMEOUT_SECONDS": "3.0", "POWERTOOLS_LOG_LEVEL": "INFO", "POWERTOOLS_SERVICE_NAME": "fulfillment" } } } - Step 7+456 s
get_metricsminutes=15, namespace=AWS/Lambda, metric=Invocations, statistic=SumResult (404 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/Lambda Invocations {} Sum per 60s", "window_minutes": 15, "points": [ [ "20:45:00Z", 35 ], [ "20:46:00Z", 262 ], [ "20:47:00Z", 258 ], [ "20:48:00Z", 258 ], [ "20:49:00Z", 259 ], [ "20:50:00Z", 261 ], [ "20:51:00Z", 258 ], [ "20:52:00Z", 262 ], [ "20:53:00Z", 255 ], [ "20:54:00Z", 258 ], [ "20:55:00Z", 212 ] ], "summary": { "min": 35, "max": 262, "count": 11 } } } - Step 8+456 s
get_metricsstatistic=Sum, namespace=AWS/Lambda, metric=Errors, minutes=15Result (375 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/Lambda Errors {} Sum per 60s", "window_minutes": 15, "points": [ [ "20:45:00Z", 0 ], [ "20:46:00Z", 0 ], [ "20:47:00Z", 0 ], [ "20:48:00Z", 0 ], [ "20:49:00Z", 0 ], [ "20:50:00Z", 0 ], [ "20:51:00Z", 0 ], [ "20:52:00Z", 0 ], [ "20:53:00Z", 0 ], [ "20:54:00Z", 0 ], [ "20:55:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 11 } } } - Step 9+456 s
get_metricsminutes=15, namespace=AWS/Lambda, metric=Duration, statistic=p99Result (440 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/Lambda Duration {} p99 per 60s", "window_minutes": 15, "points": [ [ "20:45:00Z", 4136.358 ], [ "20:46:00Z", 1896.211 ], [ "20:47:00Z", 1456.227 ], [ "20:48:00Z", 1140.399 ], [ "20:49:00Z", 1426.69 ], [ "20:50:00Z", 1320.063 ], [ "20:51:00Z", 1456.227 ], [ "20:52:00Z", 1450.686 ], [ "20:53:00Z", 1331.858 ], [ "20:54:00Z", 1360.944 ], [ "20:55:00Z", 1153.15 ] ], "summary": { "min": 1140.399, "max": 4136.358, "count": 11 } } } - Step 10+459 s
query_logscited as evidenceminutes=15, service=fulfillment, query=fields @timestamp, @message | filter level = "ERROR" or level = "WARN" | sort @timestamp desc | limit 20Result (1,367 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 20:54:49.422", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 20:54:49,422+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"message_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" }, { "@timestamp": "2026-10-01 20:51:49.433", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 20:51:49,432+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"message_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" }, { "@timestamp": "2026-10-01 20:48:45.818", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 20:48:45,817+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"message_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" } ], "bytes_scanned": 360918, "scan_budget_left_bytes": 20173723 } } - Step 11+459 s
get_metricsminutes=15, namespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Maximum, dimensions=QueueName=nightshift-placed-ordersResult (515 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders'} Maximum per 60s", "window_minutes": 15, "points": [ [ "20:41:00Z", 0 ], [ "20:42:00Z", 0 ], [ "20:43:00Z", 0 ], [ "20:44:00Z", 0 ], [ "20:45:00Z", 0 ], [ "20:46:00Z", 0 ], [ "20:47:00Z", 0 ], [ "20:48:00Z", 0 ], [ "20:49:00Z", 0 ], [ "20:50:00Z", 0 ], [ "20:51:00Z", 0 ], [ "20:52:00Z", 0 ], [ "20:53:00Z", 0 ], [ "20:54:00Z", 0 ], [ "20:55:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 15 } } } - Step 12+459 s
get_metricscited as evidencenamespace=AWS/SQS, metric=ApproximateAgeOfOldestMessage, minutes=15, dimensions=QueueName=nightshift-placed-orders, statistic=MaximumResult (525 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateAgeOfOldestMessage {'QueueName': 'nightshift-placed-orders'} Maximum per 60s", "window_minutes": 15, "points": [ [ "20:41:00Z", 0 ], [ "20:42:00Z", 0 ], [ "20:43:00Z", 0 ], [ "20:44:00Z", 0 ], [ "20:45:00Z", 0 ], [ "20:46:00Z", 2 ], [ "20:47:00Z", 8 ], [ "20:48:00Z", 8 ], [ "20:49:00Z", 23 ], [ "20:50:00Z", 109 ], [ "20:51:00Z", 162 ], [ "20:52:00Z", 235 ], [ "20:53:00Z", 235 ], [ "20:54:00Z", 345 ], [ "20:55:00Z", 345 ] ], "summary": { "min": 0, "max": 345, "count": 15 } } } - Step 13+460 s
note_hypotheseshypotheses=likely: poison message repeatedly failing and being redelivered while held in flight, causing queue age of oldest message to grow ruled_out: slow fulfillment consumer processing messages, causing queue age to increase ruled_out: timeout or hang in fulfillment function causing messages to remain in flight past visibility timeoutResult (31 characters)
{ "ok": "3 hypotheses recorded" } - Step 14+462 s
query_logscited as evidencequery=fields @timestamp, @message | filter level = "ERROR" | sort @timestamp desc | limit 5, service=fulfillment, minutes=5Result (2,415 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 20:54:49.422", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 20:54:49,422+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"message_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recent call last):\\n File \\\"/var/task/app.py\\\", line 164, in handler\\n process(record, degraded=degraded)\\n ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n File \\\"/var/task/app.py\\\", line 102, in process\\n order_id = body[\\\"order_id\\\"]\\n ~~~~^^^^^^^^^^^^\\nKeyError: 'order_id'\",\"exception_name\":\"KeyError\",\"stack_trace\":{\"type\":\"KeyError\",\"value\":\"'order_id'\",\"module\":\"builtins\",\"frames\":[{\"file\":\"/var/task/app.py\",\"line\":164,\"function\":\"handler\",\"statement\":\"process(record, degraded=degraded)\"},{\"file\":\"/var/task/app.py\",\"line\":102,\"function\":\"process\",\"statement\":\"order_id = body[\\\"order_id\\\"]\"}]},\"xray_trace_id\":\"1-6abec898-077cae2c67b58de0850e3ffe\"}\n" }, { "@timestamp": "2026-10-01 20:51:49.433", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 20:51:49,432+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"message_id\":\"45b804cd-631a-4f94-be5c-3df819db5be2\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recent call last):\\n File \\\"/var/task/app.py\\\", line 164, in handler\\n process(record, degraded=degraded)\\n ~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n File \\\"/var/task/app.py\\\", line 102, in process\\n order_id = body[\\\"order_id\\\"]\\n ~~~~^^^^^^^^^^^^\\nKeyError: 'order_id'\",\"exception_name\":\"KeyError\",\"stack_trace\":{\"type\":\"KeyError\",\"value\":\"'order_id'\",\"module\":\"builtins\",\"frames\":[{\"file\":\"/var/task/app.py\",\"line\":164,\"function\":\"handler\",\"statement\":\"process(record, degraded=degraded)\"},{\"file\":\"/var/task/app.py\",\"line\":102,\"function\":\"process\",\"statement\":\"order_id = body[\\\"order_id\\\"]\"}]},\"xray_trace_id\":\"1-6abec7e4-e764a5b526f1ac271dc475c5\"}\n" } ], "bytes_scanned": 24445, "scan_budget_left_bytes": 20149278 } } - Step 15+463 s
finish_investigationanswer rejected, sent backevidence_steps=2,10,12,14, summary=A malformed message lacking an 'order_id' key failed repeatedly during fulfillment processing with a KeyError, causing it to remain in flight and driving up the approximate age of the oldest message in the SQS queue., proposed_actions=Inspect the malformed message in the queue or DLQ to determine why it lacks an order_id., fault_category=poison_message, hypotheses=likely: poison message repeatedly failing and being redelivered while held in flight, causing queue age of oldest message to grow ruled_out: slow fulfillment consumer processing messages, causing queue age to increase ruled_out: timeout or hang in fulfillment function causing messages to remain in flight past visibility timeout, actions=["redrive_dlq"], root_cause_component=placed-orders, confidence=100Result (94 characters)
{ "error": "finish_investigation rejected", "problems": [ "'actions' must be string, got list" ] } - Step 16+464 s
finish_investigationconfidence=100, hypotheses=likely: poison message repeatedly failing and being redelivered while held in flight, causing queue age of oldest message to grow ruled_out: slow fulfillment consumer processing messages, causing queue age to increase ruled_out: timeout or hang in fulfillment function causing messages to remain in flight past visibility timeout, summary=A malformed message lacking an 'order_id' key failed repeatedly during fulfillment processing with a KeyError, causing it to remain in flight and driving up the approximate age of the oldest message in the SQS queue., evidence_steps=2,10,12,14, fault_category=poison_message, proposed_actions=Inspect the malformed message in the queue or DLQ to determine why it lacks an order_id., actions=redrive_dlq, root_cause_component=placed-ordersResult (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation de6493c537f0, gemini gemini-3.5-flash-lite, started 2026-10-01T20:56:12+00:00.
Answer
| Root cause component | placed-orders |
| Fault category | poison_message |
| Confidence | 100 |
| Ended because | finished |
Summary
A malformed message lacking an 'order_id' key failed repeatedly during fulfillment processing with a KeyError, causing it to remain in flight and driving up the approximate age of the oldest message in the SQS queue.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T20:56:09Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T20:56:14+00:00 step 1:
get_alarm - 2026-10-01T20:56:14+00:00 step 2:
get_queue_stats - 2026-10-01T20:56:15+00:00 step 3:
get_tracesminutes=15, service=fulfillment - 2026-10-01T20:56:17+00:00 step 4:
note_hypotheseshypotheses=possible: slow fulfillment consumer processing messages, causing queue age to i... - 2026-10-01T20:56:18+00:00 step 5:
query_logsquery=fields @timestamp, @message, duration | sort @timestamp desc | limit 20, minutes=15,... - 2026-10-01T20:56:18+00:00 step 6:
get_function_configservice=fulfillment - 2026-10-01T20:56:19+00:00 step 7:
get_metricsminutes=15, namespace=AWS/Lambda, metric=Invocations, statistic=Sum - 2026-10-01T20:56:19+00:00 step 8:
get_metricsstatistic=Sum, namespace=AWS/Lambda, metric=Errors, minutes=15 - 2026-10-01T20:56:19+00:00 step 9:
get_metricsminutes=15, namespace=AWS/Lambda, metric=Duration, statistic=p99 - 2026-10-01T20:56:22+00:00 step 10:
query_logsminutes=15, service=fulfillment, query=fields @timestamp, @message | filter level = "ERROR... - 2026-10-01T20:56:22+00:00 step 11:
get_metricsminutes=15, namespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Maximu... - 2026-10-01T20:56:22+00:00 step 12:
get_metricsnamespace=AWS/SQS, metric=ApproximateAgeOfOldestMessage, minutes=15, dimensions=QueueName=... - 2026-10-01T20:56:23+00:00 step 13:
note_hypotheseshypotheses=likely: poison message repeatedly failing and being redelivered while held in f... - 2026-10-01T20:56:25+00:00 step 14:
query_logsquery=fields @timestamp, @message | filter level = "ERROR" | sort @timestamp desc | limit ... - 2026-10-01T20:56:26+00:00 step 15:
finish_investigationevidence_steps=2,10,12,14, summary=A malformed message lacking an 'order_id' key failed re... (refused: 'actions' must be string, got list) - 2026-10-01T20:56:27+00:00 step 16:
finish_investigationconfidence=100, hypotheses=likely: poison message repeatedly failing and being redelivered...
Root cause evidence
- Step 2,
get_queue_stats: {"queues":{"nightshift-placed-orders":{"queue":{"name":"nightshift-placed-orders","waiting":0,"in_flight":7,"visibility_timeout_seconds":180},"dead_letter_queue":{"name":"nightshift-placed-orders-dlq","waiting":0,"in_flight":0,"visibility_t...(older result, shortened) - Step 10,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 20:54:49.422","@message":"{"level":"ERROR","location":"handler:170","message":"message failed","timestamp":"2026-10-01 20:54:49,422+0000","service":"fulfillment","c...(older result, shortened) - Step 12,
get_metrics: {"metric":"AWS/SQS ApproximateAgeOfOldestMessage {'QueueName': 'nightshift-placed-orders'} Maximum per 60s","window_minutes":15,"points":[["20:41:00Z",0.0],["20:42:00Z",0.0],["20:43:00Z",0.0],["20:44:00Z",0.0],["20:45:00Z",0.0],["20:46:00Z"...(older result, shortened) - Step 14,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 20:54:49.422","@message":"{"level":"ERROR","location":"handler:170","message":"message failed","timestamp":"2026-10-01 20:54:49,422+0000","service":"fulfillment","c...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
Allowlisted actions, each waiting for owner approval:
-
redrive_dlq -
Inspect the malformed message in the queue or DLQ to determine why it lacks an order_id.
Hypotheses
- likely: poison message repeatedly failing and being redelivered while held in flight, causing queue age of oldest message to grow
- ruled_out: slow fulfillment consumer processing messages, causing queue age to increase
- ruled_out: timeout or hang in fulfillment function causing messages to remain in flight past visibility timeout
Dropped along the way:
- dead-letter queue filling up (waiting is 0)
What the investigation cost
- 8 model calls, 38,169 input and 990 output tokens (39,159 total)
- 16 steps, 15 s of wall clock
- 822,242 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
orders / throttling, confidence 95. wrong
The orders service is throttled due to a reserved concurrency limit of 5, causing messages to remain in flight beyond the visibility timeout (180s). No errors or failures are logged, but the queue age alarm triggered because messages are not processed in time.
Hypotheses at the end
- likely throttling due to reserved concurrency limit
- possible slow dependency (ruled out by no errors or faults)
- possible visibility timeout too low (ruled out by timeout being 180s and traces completing in <1s)
- ruled out bad_deploy
- ruled out poison_message
- ruled out iam_regression
- ruled out hot_row_contention
- ruled out missing_index
Journal
- Step 1+453 s
get_queue_statscited as evidenceResult (460 characters)
{ "tool": "get_queue_stats", "truncated": false, "untrusted_data": { "queues": { "nightshift-placed-orders": { "queue": { "name": "nightshift-placed-orders", "waiting": 0, "in_flight": 7, "visibility_timeout_seconds": 180 }, "dead_letter_queue": { "name": "nightshift-placed-orders-dlq", "waiting": 0, "in_flight": 0, "visibility_timeout_seconds": 30 }, "max_receive_count": 3, "consumer": [ { "function": "nightshift-fulfillment:live", "state": "Enabled", "batch_size": 10, "maximum_concurrency": 2 } ] } } } } - Step 2+453 s
get_metricscited as evidencenamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=QueueName=nightshift-placed-orders, minutes=15, period=60Result (511 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders'} Sum per 60s", "window_minutes": 15, "points": [ [ "20:41:00Z", 0 ], [ "20:42:00Z", 0 ], [ "20:43:00Z", 0 ], [ "20:44:00Z", 0 ], [ "20:45:00Z", 0 ], [ "20:46:00Z", 0 ], [ "20:47:00Z", 0 ], [ "20:48:00Z", 0 ], [ "20:49:00Z", 0 ], [ "20:50:00Z", 0 ], [ "20:51:00Z", 0 ], [ "20:52:00Z", 0 ], [ "20:53:00Z", 0 ], [ "20:54:00Z", 0 ], [ "20:55:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 15 } } } - Step 3+453 s
get_metricscited as evidencenamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=QueueName=nightshift-placed-orders-dlq, minutes=15, period=60Result (515 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders-dlq'} Sum per 60s", "window_minutes": 15, "points": [ [ "20:41:00Z", 0 ], [ "20:42:00Z", 0 ], [ "20:43:00Z", 0 ], [ "20:44:00Z", 0 ], [ "20:45:00Z", 0 ], [ "20:46:00Z", 0 ], [ "20:47:00Z", 0 ], [ "20:48:00Z", 0 ], [ "20:49:00Z", 0 ], [ "20:50:00Z", 0 ], [ "20:51:00Z", 0 ], [ "20:52:00Z", 0 ], [ "20:53:00Z", 0 ], [ "20:54:00Z", 0 ], [ "20:55:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 15 } } } - Step 4+453 s
list_recent_deploymentsskipped, more than 3 calls in one replyservice=orders, minutes=30Result (47 characters)
{ "error": "skipped: at most 3 calls per reply" } - Step 5+457 s
get_tracescited as evidenceservice=orders, minutes=5Here is what we know so far: 1. **Queue State (Step 1)**: - The `nightshift-placed-orders` queue has **7 messages in flight** and **0 waiting**, but the **oldest message age is 345 seconds** (alarm threshold: 300s). - The dead-letter queue (`nightshift-placed-orders-dlq`) has **0 messages waiting or in flight**. 2. **Messages Visible (Step 2)**: - The `nightshift-placed-orders` queue has **0 messages visible** for the last 15 minutes, despite the alarm firing. - This suggests the queue is **not receiving new messages**, but the **in-flight messages are taking too long to process** (visibility timeout: 180s). 3. **Dead-Letter Queue (Step 3)**: - The dead-letter queue has **no messages**, so messages are not failing and being routed there. ### Hypotheses So Far: - **Possible**: The **orders consumer is stuck or throttled**, causing messages to remain visible but not processed in time (visibility timeout: 180s). - **Possible**: A **slow dependency** (e.g., `payments`, `
Result (602 characters)
{ "tool": "get_traces", "truncated": false, "untrusted_data": { "service": "nightshift-orders", "note": "active tracing samples about 1 request/s plus 5%, so counts are samples", "traces": 280, "with_error": 0, "with_fault": 0, "with_throttle": 0, "duration_seconds": { "p50": 0.355, "p99": 0.54, "max": 1.076 }, "slowest": [ { "id": "1-6abec8a8-2f950f0b1525f839271573d9", "seconds": 1.076 }, { "id": "1-6abec8a9-36c8cf7427cb65e5194a39f8", "seconds": 1.015 }, { "id": "1-6abec8a7-08ef3b671ae1da001d970dab", "seconds": 0.565 }, { "id": "1-6abec8b4-0bea971b66d5cb70665660a3", "seconds": 0.54 }, { "id": "1-6abec813-643ac27b77a1a8d47d4f4898", "seconds": 0.538 } ] } } - Step 6+460 s
query_logsfound nothingservice=orders, query=fields @timestamp, level, message, duration_ms, correlation_id | filter level = "ERROR" | sort @timestamp desc, minutes=5, limit=20Result (144 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "status": "Complete", "rows": [], "bytes_scanned": 58809, "scan_budget_left_bytes": 20912711 } } - Step 7+470 s
get_function_configcited as evidenceservice=orders### Analysis of Evidence: 5. **Traces (Step 5)**: - **280 traces** in the last 5 minutes, **no errors or faults**, but **some slow traces** (p99: 0.54s, max: 1.076s). - The slowest traces are **not excessively slow** (max ~1s), but the **visibility timeout is 180s**, meaning messages should be processed well within this window if the consumer is healthy. 6. **Logs (Step 6)**: - **No errors** in the `orders` service logs for the last 5 minutes. - This rules out **crashes, failures, or poison messages** as the cause. --- ### Updated Hypotheses: - **Likely**: **Throttling or concurrency limit** on the `orders` service, causing messages to be processed slowly or stuck, but not failing (no errors or DLQ messages). - **Possible**: **Slow dependency** (e.g., `payments` or `fulfillment`), but traces show no errors or faults, and the slowest traces are not extreme. - **Possible**: **Visibility timeout too low** for the current load, but the timeout is 180s, and traces show proce
Result (746 characters)
{ "tool": "get_function_config", "truncated": false, "untrusted_data": { "function": "nightshift-orders", "live_alias_version": "26", "last_modified": "more than 30 minutes ago", "runtime": "python3.14", "memory_mb": 128, "timeout_seconds": 15, "reserved_concurrency": 5, "state": "Active", "code_sha256": "dHKMnCv0VyC1WVE+qXpbrDc5c4PAxuR3qiNOdMv+a8s=", "environment": { "CART_FUNCTION_NAME": "nightshift-cart", "CART_TIMEOUT_SECONDS": "2.0", "CHECKOUT_RATE_LIMIT_PARAMETER": "/nightshift/flags/checkout_rate_limit", "DSQL_ENDPOINT": "<DSQL_CLUSTER_ID>.dsql.ca-central-1.on.aws", "DSQL_ROLE": "orders_service", "PLACED_ORDERS_QUEUE_URL": "https://sqs.ca-central-1.amazonaws.com/<ACCOUNT_ID>/nightshift-placed-orders", "POWERTOOLS_LOG_LEVEL": "INFO", "POWERTOOLS_SERVICE_NAME": "orders" } } } - Step 8+476 s
finish_investigationanswer rejected, sent backroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders service is throttled due to a reserved concurrency limit of 5, causing messages to remain in flight beyond the visibility timeout (180s). No errors or failures are logged, but the queue age alarm triggered because messages are not processed in time., evidence_steps=1,2,3,5,7, hypotheses=likely: throttling due to reserved concurrency limit possible: slow dependency (ruled out by no errors or faults) possible: visibility timeout too low (ruled out by timeout being 180s and traces completing in <1s) ruled_out: bad_deploy ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index, actions=rollback_alias service=orders set_operational_flag name=checkout_rate_limit value=v pause_queue_consumer resume_queue_consumer, proposed_actions=Increase reserved concurrency for the orders service to handle the current load.### Updated Analysis: 7. **Function Configuration (Step 7)**: - **Reserved concurrency: 5** (very low for a queue consumer). - **Timeout: 15s** (adequate for most operations, but not the root cause of visibility timeout issues). - **No recent changes** to the function (last modified >30 minutes ago). --- ### Root Cause: The **`orders` service has a reserved concurrency of 5**, which is **too low** for the current load. This causes: - **Messages to pile up in flight** (7 messages in flight, but no new messages arriving). - **No errors or DLQ messages**, because the service is not failing—it is **throttled by AWS Lambda's concurrency limit**. - **Visibility timeout (180s) is exceeded** because messages are not processed in time due to the concurrency limit. ### Evidence Supporting This: - **Step 1**: 7 messages in flight, no waiting messages (consumer is stuck at concurrency limit). - **Step 2**: No new messages arriving (queue is not receiving traffic, but in-flight message
Result (287 characters)
{ "error": "finish_investigation rejected", "problems": [ "action 'set_operational_flag name=checkout_rate_limit value=v': 'v' is not a valid value for checkout_rate_limit", "action 'pause_queue_consumer' does not fit the finding: pause_queue_consumer does not address a fault in orders" ] } - Step 9+478 s
finish_investigationanswer rejected, sent backroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders service is throttled due to a reserved concurrency limit of 5, causing messages to remain in flight beyond the visibility timeout (180s). No errors or failures are logged, but the queue age alarm triggered because messages are not processed in time., evidence_steps=1,2,3,5,7, hypotheses=likely: throttling due to reserved concurrency limit possible: slow dependency (ruled out by no errors or faults) possible: visibility timeout too low (ruled out by timeout being 180s and traces completing in <1s) ruled_out: bad_deploy ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index, actions=rollback_alias service=orders resume_queue_consumer, proposed_actions=Increase reserved concurrency for the orders service to handle the current load.Result (173 characters)
{ "error": "finish_investigation rejected", "problems": [ "action 'resume_queue_consumer' does not fit the finding: resume_queue_consumer does not address a fault in orders" ] } - Step 10+481 s
finish_investigationroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders service is throttled due to a reserved concurrency limit of 5, causing messages to remain in flight beyond the visibility timeout (180s). No errors or failures are logged, but the queue age alarm triggered because messages are not processed in time., evidence_steps=1,2,3,5,7, hypotheses=likely: throttling due to reserved concurrency limit possible: slow dependency (ruled out by no errors or faults) possible: visibility timeout too low (ruled out by timeout being 180s and traces completing in <1s) ruled_out: bad_deploy ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index, actions=, proposed_actions=Increase reserved concurrency for the orders service to handle the current load.Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation dda48be75eeb, mistral ministral-14b-latest, started 2026-10-01T20:56:12+00:00.
Answer
| Root cause component | orders |
| Fault category | throttling |
| Confidence | 95 |
| Ended because | finished |
Summary
The orders service is throttled due to a reserved concurrency limit of 5, causing messages to remain in flight beyond the visibility timeout (180s). No errors or failures are logged, but the queue age alarm triggered because messages are not processed in time.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T20:56:09Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T20:56:16+00:00 step 1:
get_queue_stats - 2026-10-01T20:56:16+00:00 step 2:
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=Qu... - 2026-10-01T20:56:16+00:00 step 3:
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=Qu... - 2026-10-01T20:56:16+00:00 step 4:
list_recent_deploymentsservice=orders, minutes=30 (skipped) - 2026-10-01T20:56:20+00:00 step 5:
get_tracesservice=orders, minutes=5 - 2026-10-01T20:56:23+00:00 step 6:
query_logsservice=orders, query=fields @timestamp, level, message, duration_ms, correlation_id | fil... (found nothing) - 2026-10-01T20:56:33+00:00 step 7:
get_function_configservice=orders - 2026-10-01T20:56:39+00:00 step 8:
finish_investigationroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders ... (refused: action 'set_operational_flag name=checkout_rate_limit value=v': 'v' is not a valid value for checkout_rate_limit; action 'pause_queue_consumer' does not fit the finding: pause_queue_consumer does not ) - 2026-10-01T20:56:41+00:00 step 9:
finish_investigationroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders ... (refused: action 'resume_queue_consumer' does not fit the finding: resume_queue_consumer does not address a fault in orders) - 2026-10-01T20:56:44+00:00 step 10:
finish_investigationroot_cause_component=orders, fault_category=throttling, confidence=95, summary=The orders ...
Root cause evidence
- Step 1,
get_queue_stats: {"queues":{"nightshift-placed-orders":{"queue":{"name":"nightshift-placed-orders","waiting":0,"in_flight":7,"visibility_timeout_seconds":180},"dead_letter_queue":{"name":"nightshift-placed-orders-dlq","waiting":0,"in_flight":0,"visibility_t...(older result, shortened) - Step 2,
get_metrics: {"metric":"AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders'} Sum per 60s","window_minutes":15,"points":[["20:41:00Z",0.0],["20:42:00Z",0.0],["20:43:00Z",0.0],["20:44:00Z",0.0],["20:45:00Z",0.0],["20:46:00Z...(older result, shortened) - Step 3,
get_metrics: {"metric":"AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders-dlq'} Sum per 60s","window_minutes":15,"points":[["20:41:00Z",0.0],["20:42:00Z",0.0],["20:43:00Z",0.0],["20:44:00Z",0.0],["20:45:00Z",0.0],["20:46...(older result, shortened) - Step 5,
get_traces: {"service":"nightshift-orders","note":"active tracing samples about 1 request/s plus 5%, so counts are samples","traces":280,"with_error":0,"with_fault":0,"with_throttle":0,"duration_seconds":{"p50":0.355,"p99":0.54,"max":1.076},"slowest":[...(older result, shortened) - Step 7,
get_function_config: {"function":"nightshift-orders","live_alias_version":"26","last_modified":"more than 30 minutes ago","runtime":"python3.14","memory_mb":128,"timeout_seconds":15,"reserved_concurrency":5,"state":"Active","code_sha256":"dHKMnCv0VyC1WVE+qXpbrD...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
- Increase reserved concurrency for the orders service to handle the current load.
Hypotheses
- likely: throttling due to reserved concurrency limit
- possible: slow dependency (ruled out by no errors or faults)
- possible: visibility timeout too low (ruled out by timeout being 180s and traces completing in <1s)
- ruled_out: bad_deploy
- ruled_out: poison_message
- ruled_out: iam_regression
- ruled_out: hot_row_contention
- ruled_out: missing_index
What the investigation cost
- 8 model calls, 34,652 input and 2,635 output tokens (37,287 total)
- 10 steps, 32 s of wall clock
- 58,809 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
fulfillment / slow dependency, confidence 90. wrong
The nightshift-queue-age alarm fired because the ApproximateAgeOfOldestMessage on the nightshift-placed-orders SQS queue exceeded the 300-second threshold, reaching 345 seconds. This indicates that messages are sitting unprocessed in the queue longer than expected, pointing to a slow dependency or stalled message consumer.
Hypotheses at the end
- likely slow_dependency (nightshift-placed-orders queue age is high because message consumer is slow or blocked)
- ruled out poison_message (would be DLQ or rapid retries, whereas queue age alarm indicates slow processing or stalled consumer)
- ruled out no_fault (alarm state is ALARM)
Journal
- Step 1+450 s
get_alarmfrom the pagecited as evidencename=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T20:56:09Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T20:56:09Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+451 s
finish_investigationanswer rejected, sent backfault_category=slow_dependency, proposed_actions=Check consumer logs and health for the nightshift-placed-orders queue processing service., root_cause_component=fulfillment, hypotheses=likely: slow_dependency (nightshift-placed-orders queue age is high because message consumer is slow or blocked) ruled_out: poison_message (would be DLQ or rapid retries, whereas queue age alarm indicates slow processing or stalled consumer) ruled_out: no_fault (alarm state is ALARM), actions=[], summary=The nightshift-queue-age alarm fired because the ApproximateAgeOfOldestMessage on the nightshift-placed-orders SQS queue exceeded the 300-second threshold, reaching 345 seconds. This indicates that messages are sitting unprocessed in the queue longer than expected, pointing to a slow dependency or stalled message consumer., evidence_steps=1, confidence=90Result (94 characters)
{ "error": "finish_investigation rejected", "problems": [ "'actions' must be string, got list" ] } - Step 3+452 s
finish_investigationfault_category=slow_dependency, proposed_actions=Check consumer logs and health for the nightshift-placed-orders queue processing service., actions=, confidence=90, hypotheses=likely: slow_dependency (nightshift-placed-orders queue age is high because message consumer is slow or blocked) ruled_out: poison_message (would be DLQ or rapid retries, whereas queue age alarm indicates slow processing or stalled consumer) ruled_out: no_fault (alarm state is ALARM), summary=The nightshift-queue-age alarm fired because the ApproximateAgeOfOldestMessage on the nightshift-placed-orders SQS queue exceeded the 300-second threshold, reaching 345 seconds. This indicates that messages are sitting unprocessed in the queue longer than expected, pointing to a slow dependency or stalled message consumer., evidence_steps=1, root_cause_component=fulfillmentResult (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation d06a7bbae03b, gemini gemini-3.5-flash-lite, started 2026-10-01T20:56:12+00:00.
Answer
| Root cause component | fulfillment |
| Fault category | slow_dependency |
| Confidence | 90 |
| Ended because | finished |
Summary
The nightshift-queue-age alarm fired because the ApproximateAgeOfOldestMessage on the nightshift-placed-orders SQS queue exceeded the 300-second threshold, reaching 345 seconds. This indicates that messages are sitting unprocessed in the queue longer than expected, pointing to a slow dependency or stalled message consumer.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T20:56:09Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T20:56:13+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T20:56:14+00:00 step 2:
finish_investigationfault_category=slow_dependency, proposed_actions=Check consumer logs and health for the ni... (refused: 'actions' must be string, got list) - 2026-10-01T20:56:15+00:00 step 3:
finish_investigationfault_category=slow_dependency, proposed_actions=Check consumer logs and health for the ni...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-queue-age","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).","since":"2026-10-01T20:56:09Z","metric":{"namespace":"AWS/SQS","name":"...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
- Check consumer logs and health for the nightshift-placed-orders queue processing service.
Hypotheses
- likely: slow_dependency (nightshift-placed-orders queue age is high because message consumer is slow or blocked)
- ruled_out: poison_message (would be DLQ or rapid retries, whereas queue age alarm indicates slow processing or stalled consumer)
- ruled_out: no_fault (alarm state is ALARM)
What the investigation cost
- 2 model calls, 2,668 input and 442 output tokens (3,110 total)
- 3 steps, 2 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
placed-orders / slow dependency, confidence 85. wrong
The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests that the component responsible for processing this queue (likely the 'placed-orders' service) is experiencing performance degradation or is overwhelmed.
Hypotheses at the end
- likely slow_dependency in placed-orders service causing delayed message processing
- possible throttling in placed-orders service due to high load or concurrency limits
- possible retry_storm in placed-orders service causing repeated processing attempts
- ruled out bad_deploy (no evidence of recent code changes)
- ruled out config_regression (no evidence of configuration changes)
- ruled out poison_message (no indication of failed messages in DLQ)
- ruled out iam_regression (no permission-related errors mentioned)
Journal
- Step 1+450 s
get_alarmfrom the pagecited as evidencename=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T20:56:09Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T20:56:09Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+452 s
finish_investigationroot_cause_component=placed-orders, fault_category=slow_dependency, confidence=85, summary=The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests that the component responsible for processing this queue (likely the 'placed-orders' service) is experiencing performance degradation or is overwhelmed., evidence_steps=1, hypotheses=likely: slow_dependency in placed-orders service causing delayed message processing possible: throttling in placed-orders service due to high load or concurrency limits possible: retry_storm in placed-orders service causing repeated processing attempts ruled_out: bad_deploy (no evidence of recent code changes) ruled_out: config_regression (no evidence of configuration changes) ruled_out: poison_message (no indication of failed messages in DLQ) ruled_out: iam_regression (no permission-related errors mentioned), actions=, proposed_actions=1. Investigate the placed-orders service logs for errors or slow processing. 2. Check CloudWatch metrics for the placed-orders service for CPU, memory, or throttling issues. 3. Verify if there is a spike in traffic or unusual workload. 4. Monitor the SQS queue for further delays or errors.Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation 7fd9eceb0843, mistral ministral-14b-latest, started 2026-10-01T20:56:12+00:00.
Answer
| Root cause component | placed-orders |
| Fault category | slow_dependency |
| Confidence | 85 |
| Ended because | finished |
Summary
The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests that the component responsible for processing this queue (likely the 'placed-orders' service) is experiencing performance degradation or is overwhelmed.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T20:56:09Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T20:56:13+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T20:56:15+00:00 step 2:
finish_investigationroot_cause_component=placed-orders, fault_category=slow_dependency, confidence=85, summary...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-queue-age","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).","since":"2026-10-01T20:56:09Z","metric":{"namespace":"AWS/SQS","name":"...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
-
- Investigate the placed-orders service logs for errors or slow processing.
-
- Check CloudWatch metrics for the placed-orders service for CPU, memory, or throttling issues.
-
- Verify if there is a spike in traffic or unusual workload.
-
- Monitor the SQS queue for further delays or errors.
Hypotheses
- likely: slow_dependency in placed-orders service causing delayed message processing
- possible: throttling in placed-orders service due to high load or concurrency limits
- possible: retry_storm in placed-orders service causing repeated processing attempts
- ruled_out: bad_deploy (no evidence of recent code changes)
- ruled_out: config_regression (no evidence of configuration changes)
- ruled_out: poison_message (no indication of failed messages in DLQ)
- ruled_out: iam_regression (no permission-related errors mentioned)
What the investigation cost
- 1 model calls, 1,207 input and 310 output tokens (1,517 total)
- 2 steps, 3 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
none / insufficient evidence, confidence 0. hedged
No runbook rule explains queue-age without a recent deploy.
Hypotheses at the end
- possible No runbook rule explains queue-age without a recent deploy.
Journal
- Step 1+449 s
get_alarmname=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T20:56:09Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T20:56:09Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+450 s
list_recent_deploymentsfound nothingminutes=30Result (102 characters)
{ "tool": "list_recent_deployments", "truncated": false, "untrusted_data": { "window_minutes": 30, "moves": [] } }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation b4e8b98b0a8b, runbook scripted, started 2026-10-01T20:56:12+00:00.
Answer
| Root cause component | none |
| Fault category | insufficient_evidence |
| Confidence | 0 |
| Ended because | finished |
Summary
No runbook rule explains queue-age without a recent deploy.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T20:56:09Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [345.0 (01/10/26 20:50:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T20:56:12+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T20:56:13+00:00 step 2:
list_recent_deploymentsminutes=30 (found nothing)
Root cause evidence
No evidence steps were cited.
Proposed fix (for a human to decide; the agent changed nothing)
None proposed.
Hypotheses
- possible: No runbook rule explains queue-age without a recent deploy.
What the investigation cost
- 0 model calls, 0 input and 0 output tokens (0 total)
- 2 steps, 0 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments