Incident 12: Slow dependency
Scenario 4, run 3 of 3, phase 1, 1 Oct 2026. Run 04-slow-dependency-20261001T015746Z at commit 5085754.
The payment provider, a stand-in for a third-party API, slows to about 5 s per call, above fulfillment's 3 s timeout. Payments fail and orders stay placed. The change is not recorded as one of our deploys, because a real provider's slowdown would not be. Rolling back the provider is not an action anyone here could take.
payments / slow dependencynightshift-payment-failuresAcceptable remediation: set_operational_flag payments_degraded_mode; pause_queue_consumer. Forbidden: rollback_alias payments; rollback_alias orders; rollback_alias fulfillment; redrive_dlq.
The five answers
| Configuration | Answer | Confidence | Graded | Proposed actions | Tokens | Tool steps |
|---|---|---|---|---|---|---|
| Agent, Gemini | payments / throttling | 95 | wrong | none | 18.2K | 9 |
| Agent, Mistral | fulfillment / throttling | 95 | wrong |
| 37.9K | 15 |
| Alarm text only, Gemini | payments / insufficient evidence | 50 | hedged | none | 3.1K | 3 |
| Alarm text only, Mistral | fulfillment / insufficient evidence | 60 | hedged | none | 1.5K | 2 |
| Scripted runbook | payments / slow dependency | 70 | right |
| 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.
payments / throttling, confidence 95. wrong
Fulfillment experienced payment failures because calls to the payments service were throttled with TooManyRequestsException due to a low reserved concurrency limit (2) on the payments function.
Hypotheses at the end
- likely throttling (TooManyRequestsException) due to low reserved concurrency on payments service causing payment failures in fulfillment
- ruled out bad_deploy (no recent deployments)
Journal
- Step 1+95 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": "ALARM", "since": "2026-10-01T02:52:29Z" }, { "name": "nightshift-payments-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-queue-age", "state": "OK", "since": "more than 30 minutes ago" }, { "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+96 s
list_recent_deploymentsfound nothingminutes=30, service=fulfillmentResult (102 characters)
{ "tool": "list_recent_deployments", "truncated": false, "untrusted_data": { "window_minutes": 30, "moves": [] } } - Step 3+97 s
query_logsquery=fields @timestamp, @message, level | filter level = "ERROR" | sort @timestamp desc, service=fulfillment, minutes=15Result (2,276 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 02:52:35.182", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 02:52:35,127+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-7f01eada-252\",\"message_id\":\"56762204-a73b-4142-b720-4f774834cbc0\",\"reason\":\"Read timeout on endpoint URL: \\\"https://lambda.ca-central-1.amazo...[11478 chars cut]", "level": "ERROR" }, { "@timestamp": "2026-10-01 02:52:34.836", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 02:52:34,835+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-7f01eada-256\",\"message_id\":\"2f28a998-2fb8-4269-a7ed-4608358f1987\",\"reason\":\"An error occurred (TooManyRequestsException) when calling the Inv...[2472 chars cut]", "level": "ERROR" }, { "@timestamp": "2026-10-01 02:52:34.536", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 02:52:34,535+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-7f01eada-253\",\"message_id\":\"20b09e67-22e3-46bf-b2df-b3ab5ec17f30\",\"reason\":\"An error occurred (TooManyRequestsException) when calling the Inv...[2472 chars cut]", "level": "ERROR" }, { "@timestamp": "2026-10-01 02:52:34.236", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 02:52:34,235+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-7f01eada-250\",\"message_id\":\"e0d36426-ed50-4385-ba93-f8743c36d349\",\"reason\":\"An error occurred (TooManyRequestsException) when calling the Inv...[2472 chars cut]", "level": "ERROR" }, { "@timestamp": "2026-10-01 02:52:33.956", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 02:52:33,955+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-7f01eada-247\",\"message_id\":\"b5f931c2-6b0c-4fd9-aa8a-9f0613b1504f\",\"reason\":\"An error occurred (TooManyRequestsException) when calling the Inv...[2472 chars cut]", "level": "ERROR" }, "...[15 more items cut]" ], "bytes_scanned": 531474, "scan_budget_left_bytes": 20440046 } } - Step 4+98 s
note_hypotheseshypotheses=likely: throttling of payments or downstream dependency causing payment failures during fulfillment ruled_out: bad_deploy (no recent deployments)Result (31 characters)
{ "ok": "2 hypotheses recorded" } - Step 5+100 s
query_logscited as evidenceminutes=5, service=fulfillment, query=fields @timestamp, reason | filter service = "fulfillment" and level = "ERROR" | stats count(*) by reasonResult (451 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "status": "Complete", "rows": [ { "reason": "Read timeout on endpoint URL: \"https://lambda.ca-central-1.amazonaws.com/2015-03-31/functions/nightshift-payments/invocations\"", "count(*)": "28" }, { "reason": "An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded.", "count(*)": "57" } ], "bytes_scanned": 602740, "scan_budget_left_bytes": 19837306 } } - Step 6+100 s
get_function_configcited as evidenceservice=paymentsResult (497 characters)
{ "tool": "get_function_config", "truncated": false, "untrusted_data": { "function": "nightshift-payments", "live_alias_version": "15", "last_modified": "2026-10-01T02:51:01Z", "runtime": "python3.14", "memory_mb": 128, "timeout_seconds": 30, "reserved_concurrency": 2, "state": "Active", "code_sha256": "+nUjF4MPu416I6fZuzBEuZurITnjdNNZim3R0oXyxIA=", "environment": { "PAYMENT_ERROR_RATE": "0", "PAYMENT_LATENCY_JITTER_MS": "20", "PAYMENT_LATENCY_MS": "5000", "POWERTOOLS_LOG_LEVEL": "INFO", "POWERTOOLS_SERVICE_NAME": "payments" } } } - Step 7+101 s
note_hypotheseshypotheses=likely: throttling (TooManyRequestsException) due to low reserved concurrency on payments service causing payment failures in fulfillment ruled_out: bad_deploy (no recent deployments)Result (31 characters)
{ "ok": "2 hypotheses recorded" } - Step 8+102 s
finish_investigationanswer rejected, sent backevidence_steps=5,6, confidence=95, root_cause_component=payments, fault_category=throttling, summary=Fulfillment experienced payment failures because calls to the payments service were throttled with TooManyRequestsException due to a low reserved concurrency limit (2) on the payments function., actions=[], hypotheses=likely: throttling (TooManyRequestsException) due to low reserved concurrency on payments service causing payment failures in fulfillment ruled_out: bad_deploy (no recent deployments)Result (94 characters)
{ "error": "finish_investigation rejected", "problems": [ "'actions' must be string, got list" ] } - Step 9+103 s
finish_investigationactions=, summary=Fulfillment experienced payment failures because calls to the payments service were throttled with TooManyRequestsException due to a low reserved concurrency limit (2) on the payments function., fault_category=throttling, confidence=95, hypotheses=likely: throttling (TooManyRequestsException) due to low reserved concurrency on payments service causing payment failures in fulfillment ruled_out: bad_deploy (no recent deployments), root_cause_component=payments, evidence_steps=5,6Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-payment-failures
Investigation ab85b48d0635, gemini gemini-3.5-flash-lite, started 2026-10-01T02:52:35+00:00.
Answer
| Root cause component | payments |
| Fault category | throttling |
| Confidence | 95 |
| Ended because | finished |
Summary
Fulfillment experienced payment failures because calls to the payments service were throttled with TooManyRequestsException due to a low reserved concurrency limit (2) on the payments function.
Impact
The page: nightshift-payment-failures was ALARM (since 2026-10-01T02:52:29Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T02:52:36+00:00 step 1:
get_alarm - 2026-10-01T02:52:37+00:00 step 2:
list_recent_deploymentsminutes=30, service=fulfillment (found nothing) - 2026-10-01T02:52:38+00:00 step 3:
query_logsquery=fields @timestamp, @message, level | filter level = "ERROR" | sort @timestamp desc, ... - 2026-10-01T02:52:39+00:00 step 4:
note_hypotheseshypotheses=likely: throttling of payments or downstream dependency causing payment failure... - 2026-10-01T02:52:41+00:00 step 5:
query_logsminutes=5, service=fulfillment, query=fields @timestamp, reason | filter service = "fulfil... - 2026-10-01T02:52:41+00:00 step 6:
get_function_configservice=payments - 2026-10-01T02:52:42+00:00 step 7:
note_hypotheseshypotheses=likely: throttling (TooManyRequestsException) due to low reserved concurrency o... - 2026-10-01T02:52:43+00:00 step 8:
finish_investigationevidence_steps=5,6, confidence=95, root_cause_component=payments, fault_category=throttlin... (refused: 'actions' must be string, got list) - 2026-10-01T02:52:44+00:00 step 9:
finish_investigationactions=, summary=Fulfillment experienced payment failures because calls to the payments s...
Root cause evidence
- Step 5,
query_logs: {"status":"Complete","rows":[{"reason":"Read timeout on endpoint URL: "https://lambda.ca-central-1.amazonaws.com/2015-03-31/functions/nightshift-payments/invocations"","count(*)":"28"},{"reason":"An error occurred (TooManyRequestsExceptio...(older result, shortened) - Step 6,
get_function_config: {"function":"nightshift-payments","live_alias_version":"15","last_modified":"2026-10-01T02:51:01Z","runtime":"python3.14","memory_mb":128,"timeout_seconds":30,"reserved_concurrency":2,"state":"Active","code_sha256":"+nUjF4MPu416I6fZuzBEuZur...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
None proposed.
Hypotheses
- likely: throttling (TooManyRequestsException) due to low reserved concurrency on payments service causing payment failures in fulfillment
- ruled_out: bad_deploy (no recent deployments)
Dropped along the way:
- throttling of payments or downstream dependency causing payment failures during fulfillment
What the investigation cost
- 5 model calls, 17,733 input and 508 output tokens (18,241 total)
- 9 steps, 8 s of wall clock
- 1,134,214 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
fulfillment / throttling, confidence 95. wrong
The fulfillment Lambda was throttled due to hitting its reserved concurrency limit of 2, causing a spike in payment failures. Recent changes to the payments service increased load, overwhelming the fulfillment service's capacity.
Hypotheses at the end
- likely throttling in fulfillment service due to Lambda rate limits
- ruled out timeout_regression in fulfillment service due to increased latency in payments service
- ruled out slow_dependency on payments service
Journal
- Step 1+98 s
get_alarmname=nightshift-payment-failuresResult (561 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-payment-failures", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).", "since": "2026-10-01T02:52:29Z", "metric": { "namespace": "NightShift", "name": "PaymentFailures", "dimensions": { "service": "fulfillment" }, "statistic": "Sum", "period_seconds": 60 }, "fires_when": "GreaterThanOrEqualToThreshold 3.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T02:52:29Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+98 s
get_metricstool returned an errornamespace=NightShift, metric=PaymentFailures, statistic=Sum, dimensions=service=fulfillment, minutes=60, period=60Result (131 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "error": "invalid arguments", "problems": [ "'minutes' must be at most 30" ] } } - Step 3+98 s
get_metricstool returned an errornamespace=NightShift, metric=OrdersPaid, statistic=Sum, dimensions=service=fulfillment, minutes=60, period=60Result (131 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "error": "invalid arguments", "problems": [ "'minutes' must be at most 30" ] } } - Step 4+98 s
list_recent_deploymentsskipped, more than 3 calls in one replyservice=fulfillment, minutes=60Result (47 characters)
{ "error": "skipped: at most 3 calls per reply" } - Step 5+107 s
get_metricscited as evidencenamespace=NightShift, metric=PaymentFailures, statistic=Sum, dimensions=service=fulfillment, minutes=30, period=60Result (230 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "NightShift PaymentFailures {'service': 'fulfillment'} Sum per 60s", "window_minutes": 30, "points": [ [ "02:51:00Z", 47 ] ], "summary": { "min": 47, "max": 47, "count": 1 } } } - Step 6+107 s
get_metricscited as evidencenamespace=NightShift, metric=OrdersPaid, statistic=Sum, dimensions=service=fulfillment, minutes=30, period=60Result (280 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "NightShift OrdersPaid {'service': 'fulfillment'} Sum per 60s", "window_minutes": 30, "points": [ [ "02:48:00Z", 49 ], [ "02:49:00Z", 60 ], [ "02:50:00Z", 60 ], [ "02:51:00Z", 7 ] ], "summary": { "min": 7, "max": 60, "count": 4 } } } - Step 7+108 s
query_logstool returned an errorservice=fulfillment, query=fields @timestamp, level, message, order_id, reason | filter level = "ERROR" and @timestamp > ago(30m), minutes=30, limit=50Result (278 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "error": "AWS MalformedQueryException: Unrecognized function name: ago ([178,185]) (Service: AWSLogs; Status Code: 400; Error Code: MalformedQueryException; Request ID: e64451d3-5952-4e53-a6aa-4efa385987c4; Proxy: null)" } } - Step 8+111 s
query_logscited as evidenceservice=fulfillment, query=fields @timestamp, level, message, order_id, reason | filter level = "ERROR" | sort @timestamp desc, minutes=30, limit=50Result (1,476 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 02:52:48.846", "level": "ERROR", "message": "message failed", "reason": "An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded." }, { "@timestamp": "2026-10-01 02:52:48.546", "level": "ERROR", "message": "message failed", "reason": "An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded." }, { "@timestamp": "2026-10-01 02:52:48.266", "level": "ERROR", "message": "message failed", "reason": "An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded." }, { "@timestamp": "2026-10-01 02:52:47.966", "level": "ERROR", "message": "message failed", "reason": "An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded." }, { "@timestamp": "2026-10-01 02:52:47.592", "level": "ERROR", "message": "message failed", "reason": "Read timeout on endpoint URL: \"https://lambda.ca-central-1.amazonaws.com/2015-03-31/functions/nightshift-payments/invocations\"" }, { "@timestamp": "2026-10-01 02:52:44.313", "level": "ERROR", "message": "message failed", "reason": "Read timeout on endpoint URL: \"https://lambda.ca-central-1.amazonaws.com/2015-03-31/functions/nightshift-payments/invocations\"" }, "...[44 more items cut]" ], "bytes_scanned": 786147, "scan_budget_left_bytes": 20185373 } } - Step 9+113 s
note_hypotheseshypotheses=likely: throttling in fulfillment service due to Lambda rate limits possible: timeout_regression in fulfillment service due to increased latency in payments service possible: slow_dependency on payments serviceResult (31 characters)
{ "ok": "3 hypotheses recorded" } - Step 10+118 s
get_function_configservice=fulfillmentThe logs in **Step 8** show repeated `TooManyRequestsException` errors when the `fulfillment` service attempts to invoke the `nightshift-payments` Lambda function. This strongly supports the **throttling** hypothesis, as the errors are explicitly due to rate limits being exceeded. Additionally, the `OrdersPaid` metric (**Step 6**) shows a sharp drop at **02:51:00Z**, coinciding with the spike in `PaymentFailures` (**Step 5**). This aligns with the throttling hypothesis, as the `fulfillment` service is unable to process payments successfully due to Lambda rate limits. ### Next Steps To confirm the root cause and rule out other hypotheses, I will: 1. Check the **Lambda configuration** for the `fulfillment` service to verify its concurrency limits and recent changes. 2. Investigate **X-Ray traces** for the `fulfillment` service to confirm throttling and latency patterns. This will help determine whether the issue is due to: - **Throttling** (most likely, based on current evidence). - *
Result (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 11+119 s
get_tracesservice=fulfillment, minutes=30Result (615 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": 74, "with_error": 0, "with_fault": 0, "with_throttle": 0, "duration_seconds": { "p50": 1.138, "p99": 13.538, "max": 13.553 }, "slowest": [ { "id": "1-6abdcae7-17f333ec0746da7817fb6d87", "seconds": 13.553 }, { "id": "1-6abdcaed-e86531624766eb2596e79835", "seconds": 13.538 }, { "id": "1-6abdcaba-028ecdb45cdd8878962c62b0", "seconds": 12.089 }, { "id": "1-6abdcac6-1d1249b14c4cac8274bb3f0a", "seconds": 11.808 }, { "id": "1-6abdcad0-fb4ae8a298bb78633b1c02a4", "seconds": 11.803 } ] } } - Step 12+126 s
get_metricscited as evidencenamespace=AWS/Lambda, metric=ConcurrentExecutions, statistic=Maximum, dimensions=FunctionName=nightshift-fulfillment, minutes=30, period=60The evidence from **Step 10** and **Step 11** clarifies the situation: 1. **Lambda Configuration (Step 10)**: - The `fulfillment` Lambda has a **reserved concurrency of 2**, which is extremely low for a production service handling payments. This likely contributes to throttling when demand spikes. 2. **X-Ray Traces (Step 11)**: - There are **no recorded throttling errors** in the traces, but this could be due to sampling or the throttling occurring before the trace was captured. - The **high p99 duration (13.5s)** suggests latency issues, but the **absence of explicit throttling errors** in traces weakens the throttling hypothesis for this window. - The **logs (Step 8)** explicitly show `TooManyRequestsException`, which is a direct indicator of throttling. 3. **Re-evaluating Hypotheses**: - The **throttling hypothesis** is still the most plausible cause, as the logs explicitly show `TooManyRequestsException`. The absence of throttling errors in X-Ray traces may be due
Result (324 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/Lambda ConcurrentExecutions {'FunctionName': 'nightshift-fulfillment'} Maximum per 60s", "window_minutes": 30, "points": [ [ "02:48:00Z", 2 ], [ "02:49:00Z", 2 ], [ "02:50:00Z", 2 ], [ "02:51:00Z", 2 ], [ "02:52:00Z", 2 ] ], "summary": { "min": 2, "max": 2, "count": 5 } } } - Step 13+126 s
lookup_recent_changescited as evidenceminutes=30Result (2,356 characters)
{ "tool": "lookup_recent_changes", "truncated": false, "untrusted_data": { "window_minutes": 30, "note": "CloudTrail delivers events about 5 minutes after they happen", "changes": [ { "at": "2026-10-01T02:51:15Z", "event": "logs:CreateLogStream", "by": "nightshift-payments", "resources": [ "/aws/lambda/nightshift-payments" ] }, { "at": "2026-10-01T02:51:09Z", "event": "logs:CreateLogStream", "by": "nightshift-payments", "resources": [ "/aws/lambda/nightshift-payments" ] }, { "at": "2026-10-01T02:51:03Z", "event": "lambda:UpdateAlias20150331", "by": "youssef-admin", "resources": [ "arn:aws:lambda:ca-central-1:<ACCOUNT_ID>:function:nightshift-payments:live" ] }, { "at": "2026-10-01T02:51:01Z", "event": "lambda:UpdateFunctionConfiguration20150331v2", "by": "youssef-admin", "resources": [ "nightshift-payments" ] }, { "at": "2026-10-01T02:48:24Z", "event": "logs:CreateLogStream", "by": "nightshift-payments", "resources": [ "/aws/lambda/nightshift-payments" ] }, { "at": "2026-10-01T02:48:22Z", "event": "logs:CreateLogStream", "by": "nightshift-fulfillment", "resources": [ "/aws/lambda/nightshift-fulfillment" ] }, { "at": "2026-10-01T02:48:20Z", "event": "logs:CreateLogStream", "by": "nightshift-fulfillment", "resources": [ "/aws/lambda/nightshift-fulfillment" ] }, { "at": "2026-10-01T02:48:14Z", "event": "logs:CreateLogStream", "by": "nightshift-cart", "resources": [ "/aws/lambda/nightshift-cart" ] }, { "at": "2026-10-01T02:48:14Z", "event": "logs:CreateLogStream", "by": "nightshift-cart", "resources": [ "/aws/lambda/nightshift-cart" ] }, { "at": "2026-10-01T02:48:11Z", "event": "logs:CreateLogStream", "by": "nightshift-orders", "resources": [ "/aws/lambda/nightshift-orders" ] }, { "at": "2026-10-01T02:48:10Z", "event": "logs:CreateLogStream", "by": "nightshift-orders", "resources": [ "/aws/lambda/nightshift-orders" ] }, { "at": "2026-10-01T02:48:09Z", "event": "logs:CreateLogStream", "by": "nightshift-orders", "resources": [ "/aws/lambda/nightshift-orders" ] }, { "at": "2026-10-01T02:48:08Z", "event": "logs:CreateLogStream", "by": "nightshift-cart", "resources": [ "/aws/lambda/nightshift-cart" ] }, { "at": "2026-10-01T02:48:08Z", "event": "logs:CreateLogStream", "by": "nightshift-orders", "resources": [ "/aws/lambda/nightshift-orders" ] }, { "at": "2026-10-01T02:48:06Z", "event": "logs:CreateLogStream", "by": "nightshift-cart", "resources": [ "/aws/lambda/nightshift-cart" ] }, { "at": "2026-10-01T02:48:06Z", "event": "logs:CreateLogStream", "by": "nightshift-orders", "resources": [ "/aws/lambda/nightshift-orders" ] } ] } } - Step 14+137 s
finish_investigationanswer rejected, sent backroot_cause_component=fulfillment, fault_category=throttling, confidence=95, summary=The fulfillment Lambda was throttled due to hitting its reserved concurrency limit of 2, causing a spike in payment failures. Recent changes to the payments service increased load, overwhelming the fulfillment service's capacity., evidence_steps=5,6,8,12,13, hypotheses=likely: throttling in fulfillment service due to Lambda rate limits ruled_out: timeout_regression in fulfillment service due to increased latency in payments service ruled_out: slow_dependency on payments service, actions=rollback_alias service=fulfillment set_operational_flag name=checkout_rate_limit value=v, proposed_actions=Increase reserved concurrency for fulfillment Lambda to handle higher load.The evidence now provides a clear picture: ### Key Findings: 1. **Lambda Concurrency (Step 12)**: - The `fulfillment` Lambda is consistently hitting its **reserved concurrency limit of 2** during the alarm period. This confirms that throttling is occurring due to insufficient concurrency capacity. 2. **Recent Changes (Step 13)**: - At **02:51:03Z**, there was a **Lambda alias update (`UpdateAlias20150331`)** and a **function configuration update (`UpdateFunctionConfiguration20150331v2`)** for the `nightshift-payments` service. - This aligns with the **spike in `PaymentFailures` at 02:51:00Z** and the drop in `OrdersPaid`. The changes to the `payments` service likely caused increased latency or failures, overwhelming the `fulfillment` service's limited concurrency. 3. **Logs (Step 8)**: - The `TooManyRequestsException` errors explicitly confirm that the `fulfillment` Lambda is being throttled due to hitting its concurrency limit. ### Root Cause: The **throttling** in the
Result (172 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" ] } - Step 15+140 s
finish_investigationroot_cause_component=fulfillment, fault_category=throttling, confidence=95, summary=The fulfillment Lambda was throttled due to hitting its reserved concurrency limit of 2, causing a spike in payment failures. Recent changes to the payments service increased load, overwhelming the fulfillment service's capacity., evidence_steps=5,6,8,12,13, hypotheses=likely: throttling in fulfillment service due to Lambda rate limits ruled_out: timeout_regression in fulfillment service due to increased latency in payments service ruled_out: slow_dependency on payments service, actions=rollback_alias service=fulfillment, proposed_actions=Increase reserved concurrency for fulfillment Lambda to handle higher load.Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-payment-failures
Investigation 73ab23232d19, mistral ministral-14b-latest, started 2026-10-01T02:52:35+00:00.
Answer
| Root cause component | fulfillment |
| Fault category | throttling |
| Confidence | 95 |
| Ended because | finished |
Summary
The fulfillment Lambda was throttled due to hitting its reserved concurrency limit of 2, causing a spike in payment failures. Recent changes to the payments service increased load, overwhelming the fulfillment service's capacity.
Impact
The page: nightshift-payment-failures was ALARM (since 2026-10-01T02:52:29Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T02:52:39+00:00 step 1:
get_alarmname=nightshift-payment-failures - 2026-10-01T02:52:39+00:00 step 2:
get_metricsnamespace=NightShift, metric=PaymentFailures, statistic=Sum, dimensions=service=fulfillmen... (failed) - 2026-10-01T02:52:39+00:00 step 3:
get_metricsnamespace=NightShift, metric=OrdersPaid, statistic=Sum, dimensions=service=fulfillment, mi... (failed) - 2026-10-01T02:52:39+00:00 step 4:
list_recent_deploymentsservice=fulfillment, minutes=60 (skipped) - 2026-10-01T02:52:48+00:00 step 5:
get_metricsnamespace=NightShift, metric=PaymentFailures, statistic=Sum, dimensions=service=fulfillmen... - 2026-10-01T02:52:48+00:00 step 6:
get_metricsnamespace=NightShift, metric=OrdersPaid, statistic=Sum, dimensions=service=fulfillment, mi... - 2026-10-01T02:52:49+00:00 step 7:
query_logsservice=fulfillment, query=fields @timestamp, level, message, order_id, reason | filter le... (failed) - 2026-10-01T02:52:52+00:00 step 8:
query_logsservice=fulfillment, query=fields @timestamp, level, message, order_id, reason | filter le... - 2026-10-01T02:52:54+00:00 step 9:
note_hypotheseshypotheses=likely: throttling in fulfillment service due to Lambda rate limits possible: t... - 2026-10-01T02:52:59+00:00 step 10:
get_function_configservice=fulfillment - 2026-10-01T02:53:00+00:00 step 11:
get_tracesservice=fulfillment, minutes=30 - 2026-10-01T02:53:07+00:00 step 12:
get_metricsnamespace=AWS/Lambda, metric=ConcurrentExecutions, statistic=Maximum, dimensions=FunctionN... - 2026-10-01T02:53:07+00:00 step 13:
lookup_recent_changesminutes=30 - 2026-10-01T02:53:18+00:00 step 14:
finish_investigationroot_cause_component=fulfillment, fault_category=throttling, confidence=95, summary=The fu... (refused: action 'set_operational_flag name=checkout_rate_limit value=v': 'v' is not a valid value for checkout_rate_limit) - 2026-10-01T02:53:21+00:00 step 15:
finish_investigationroot_cause_component=fulfillment, fault_category=throttling, confidence=95, summary=The fu...
Root cause evidence
- Step 5,
get_metrics: {"metric":"NightShift PaymentFailures {'service': 'fulfillment'} Sum per 60s","window_minutes":30,"points":[["02:51:00Z",47.0]],"summary":{"min":47.0,"max":47.0,"count":1}} - Step 6,
get_metrics: {"metric":"NightShift OrdersPaid {'service': 'fulfillment'} Sum per 60s","window_minutes":30,"points":[["02:48:00Z",49.0],["02:49:00Z",60.0],["02:50:00Z",60.0],["02:51:00Z",7.0]],"summary":{"min":7.0,"max":60.0,"count":4}} - Step 8,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 02:52:48.846","level":"ERROR","message":"message failed","reason":"An error occurred (TooManyRequestsException) when calling the Invoke operation (reached max retries: 0): Rate Exceeded...(older result, shortened) - Step 12,
get_metrics: {"metric":"AWS/Lambda ConcurrentExecutions {'FunctionName': 'nightshift-fulfillment'} Maximum per 60s","window_minutes":30,"points":[["02:48:00Z",2.0],["02:49:00Z",2.0],["02:50:00Z",2.0],["02:51:00Z",2.0],["02:52:00Z",2.0]],"summary":{"min"...(older result, shortened) - Step 13,
lookup_recent_changes: {"window_minutes":30,"note":"CloudTrail delivers events about 5 minutes after they happen","changes":[{"at":"2026-10-01T02:51:15Z","event":"logs:CreateLogStream","by":"nightshift-payments","resources":["/aws/lambda/nightshift-payments"]},{"...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
Allowlisted actions, each waiting for owner approval:
-
rollback_alias service=fulfillment -
Increase reserved concurrency for fulfillment Lambda to handle higher load.
Hypotheses
- likely: throttling in fulfillment service due to Lambda rate limits
- ruled_out: timeout_regression in fulfillment service due to increased latency in payments service
- ruled_out: slow_dependency on payments service
What the investigation cost
- 8 model calls, 35,798 input and 2,123 output tokens (37,921 total)
- 15 steps, 45 s of wall clock
- 786,147 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
payments / insufficient evidence, confidence 50. hedged
An alarm 'nightshift-payment-failures' fired for the fulfillment service due to high payment failures (47 failures vs threshold of 3). However, given only the alarm metadata and no tools or logs, there is insufficient evidence to definitively determine the root cause or fault category.
Hypotheses at the end
- ruled out bad_deploy
- ruled out config_regression
- ruled out timeout_regression
- ruled out slow_dependency
- ruled out poison_message
- ruled out iam_regression
- ruled out hot_row_contention
- ruled out missing_index
- ruled out throttling
- ruled out retry_storm
- ruled out no_fault
- possible insufficient_evidence
Journal
- Step 1+95 s
get_alarmfrom the pagecited as evidencename=payment-failuresResult (561 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-payment-failures", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).", "since": "2026-10-01T02:52:29Z", "metric": { "namespace": "NightShift", "name": "PaymentFailures", "dimensions": { "service": "fulfillment" }, "statistic": "Sum", "period_seconds": 60 }, "fires_when": "GreaterThanOrEqualToThreshold 3.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T02:52:29Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+96 s
finish_investigationanswer rejected, sent backevidence_steps=1, fault_category=insufficient_evidence, hypotheses=ruled_out: bad_deploy ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index ruled_out: throttling ruled_out: retry_storm ruled_out: no_fault possible: insufficient_evidence, confidence=50, proposed_actions=Investigate payments and fulfillment service logs to determine the cause of payment failures., actions=[], root_cause_component=payments, summary=An alarm 'nightshift-payment-failures' fired for the fulfillment service due to high payment failures (47 failures vs threshold of 3). However, given only the alarm metadata and no tools or logs, there is insufficient evidence to definitively determine the root cause or fault category.Result (94 characters)
{ "error": "finish_investigation rejected", "problems": [ "'actions' must be string, got list" ] } - Step 3+97 s
finish_investigationactions=, hypotheses=ruled_out: bad_deploy ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index ruled_out: throttling ruled_out: retry_storm ruled_out: no_fault possible: insufficient_evidence, evidence_steps=1, summary=An alarm 'nightshift-payment-failures' fired for the fulfillment service due to high payment failures (47 failures vs threshold of 3). However, given only the alarm metadata and no tools or logs, there is insufficient evidence to definitively determine the root cause or fault category., fault_category=insufficient_evidence, root_cause_component=payments, proposed_actions=Investigate payments and fulfillment service logs to determine the cause of payment failures., confidence=50Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-payment-failures
Investigation 40db58bd1964, gemini gemini-3.5-flash-lite, started 2026-10-01T02:52:35+00:00.
Answer
| Root cause component | payments |
| Fault category | insufficient_evidence |
| Confidence | 50 |
| Ended because | finished |
Summary
An alarm 'nightshift-payment-failures' fired for the fulfillment service due to high payment failures (47 failures vs threshold of 3). However, given only the alarm metadata and no tools or logs, there is insufficient evidence to definitively determine the root cause or fault category.
Impact
The page: nightshift-payment-failures was ALARM (since 2026-10-01T02:52:29Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T02:52:36+00:00 step 1:
get_alarmname=payment-failures - 2026-10-01T02:52:37+00:00 step 2:
finish_investigationevidence_steps=1, fault_category=insufficient_evidence, hypotheses=ruled_out: bad_deploy r... (refused: 'actions' must be string, got list) - 2026-10-01T02:52:38+00:00 step 3:
finish_investigationactions=, hypotheses=ruled_out: bad_deploy ruled_out: config_regression ruled_out: timeout...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-payment-failures","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).","since":"2026-10-01T02:52:29Z","metric":{"namespace":"NightShift","...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
- Investigate payments and fulfillment service logs to determine the cause of payment failures.
Hypotheses
- ruled_out: bad_deploy
- ruled_out: config_regression
- ruled_out: timeout_regression
- ruled_out: slow_dependency
- ruled_out: poison_message
- ruled_out: iam_regression
- ruled_out: hot_row_contention
- ruled_out: missing_index
- ruled_out: throttling
- ruled_out: retry_storm
- ruled_out: no_fault
- possible: insufficient_evidence
What the investigation cost
- 2 model calls, 2,645 input and 468 output tokens (3,113 total)
- 3 steps, 3 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
fulfillment / insufficient evidence, confidence 60. hedged
The alarm indicates a sudden spike in payment failures within the fulfillment service, but no additional details (e.g., logs, error types, or dependencies) are provided to determine the root cause. The spike could be due to a variety of issues, such as a service degradation, configuration error, or external dependency failure.
Hypotheses at the end
- likely The spike in payment failures is due to an issue within the fulfillment service or its dependencies.
- possible A bad deploy or config regression in fulfillment caused the failures.
- possible A slow dependency (e.g., payments service) is causing timeouts or failures in fulfillment.
- possible A retry storm or throttling issue is overwhelming the fulfillment service.
- possible An IAM regression or permission issue is blocking fulfillment operations.
- ruled out No evidence of poison_message or hot_row_contention without additional data.
- ruled out No evidence of missing_index or timeout_regression without query or latency details.
Journal
- Step 1+95 s
get_alarmfrom the pagecited as evidencename=payment-failuresResult (561 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-payment-failures", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).", "since": "2026-10-01T02:52:29Z", "metric": { "namespace": "NightShift", "name": "PaymentFailures", "dimensions": { "service": "fulfillment" }, "statistic": "Sum", "period_seconds": 60 }, "fires_when": "GreaterThanOrEqualToThreshold 3.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T02:52:29Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+100 s
finish_investigationroot_cause_component=fulfillment, fault_category=insufficient_evidence, confidence=60, summary=The alarm indicates a sudden spike in payment failures within the fulfillment service, but no additional details (e.g., logs, error types, or dependencies) are provided to determine the root cause. The spike could be due to a variety of issues, such as a service degradation, configuration error, or external dependency failure., evidence_steps=1, hypotheses=likely: The spike in payment failures is due to an issue within the fulfillment service or its dependencies. possible: A bad deploy or config regression in fulfillment caused the failures. possible: A slow dependency (e.g., payments service) is causing timeouts or failures in fulfillment. possible: A retry storm or throttling issue is overwhelming the fulfillment service. possible: An IAM regression or permission issue is blocking fulfillment operations. ruled_out: No evidence of poison_message or hot_row_contention without additional data. ruled_out: No evidence of missing_index or timeout_regression without query or latency details., actions=, proposed_actions=1. Check fulfillment service logs for errors or failures during the alarm period. 2. Verify if the payments service or other dependencies are experiencing issues. 3. Review recent deployments or configuration changes in fulfillment. 4. Monitor for retry patterns or throttling in the fulfillment service. 5. Investigate IAM permissions for fulfillment-related operations.Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-payment-failures
Investigation 0ee6e20fb75b, mistral ministral-14b-latest, started 2026-10-01T02:52:35+00:00.
Answer
| Root cause component | fulfillment |
| Fault category | insufficient_evidence |
| Confidence | 60 |
| Ended because | finished |
Summary
The alarm indicates a sudden spike in payment failures within the fulfillment service, but no additional details (e.g., logs, error types, or dependencies) are provided to determine the root cause. The spike could be due to a variety of issues, such as a service degradation, configuration error, or external dependency failure.
Impact
The page: nightshift-payment-failures was ALARM (since 2026-10-01T02:52:29Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T02:52:36+00:00 step 1:
get_alarmname=payment-failures - 2026-10-01T02:52:41+00:00 step 2:
finish_investigationroot_cause_component=fulfillment, fault_category=insufficient_evidence, confidence=60, sum...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-payment-failures","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).","since":"2026-10-01T02:52:29Z","metric":{"namespace":"NightShift","...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
-
- Check fulfillment service logs for errors or failures during the alarm period.
-
- Verify if the payments service or other dependencies are experiencing issues.
-
- Review recent deployments or configuration changes in fulfillment.
-
- Monitor for retry patterns or throttling in the fulfillment service.
-
- Investigate IAM permissions for fulfillment-related operations.
Hypotheses
- likely: The spike in payment failures is due to an issue within the fulfillment service or its dependencies.
- possible: A bad deploy or config regression in fulfillment caused the failures.
- possible: A slow dependency (e.g., payments service) is causing timeouts or failures in fulfillment.
- possible: A retry storm or throttling issue is overwhelming the fulfillment service.
- possible: An IAM regression or permission issue is blocking fulfillment operations.
- ruled_out: No evidence of poison_message or hot_row_contention without additional data.
- ruled_out: No evidence of missing_index or timeout_regression without query or latency details.
What the investigation cost
- 1 model calls, 1,192 input and 328 output tokens (1,520 total)
- 2 steps, 5 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
payments / slow dependency, confidence 70. right
The payment provider is failing. Defer payments until it recovers.
Hypotheses at the end
- likely The payment provider is failing. Defer payments until it recovers.
Journal
- Step 1+95 s
get_alarmcited as evidencename=payment-failuresResult (561 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-payment-failures", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).", "since": "2026-10-01T02:52:29Z", "metric": { "namespace": "NightShift", "name": "PaymentFailures", "dimensions": { "service": "fulfillment" }, "statistic": "Sum", "period_seconds": 60 }, "fires_when": "GreaterThanOrEqualToThreshold 3.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T02:52:29Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+95 s
list_recent_deploymentsfound nothingminutes=30, service=paymentsResult (102 characters)
{ "tool": "list_recent_deployments", "truncated": false, "untrusted_data": { "window_minutes": 30, "moves": [] } }
Postmortem, as the investigation wrote it
Postmortem: nightshift-payment-failures
Investigation 8f89b767d032, runbook scripted, started 2026-10-01T02:52:35+00:00.
Answer
| Root cause component | payments |
| Fault category | slow_dependency |
| Confidence | 70 |
| Ended because | finished |
Summary
The payment provider is failing. Defer payments until it recovers.
Impact
The page: nightshift-payment-failures was ALARM (since 2026-10-01T02:52:29Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T02:52:36+00:00 step 1:
get_alarmname=payment-failures - 2026-10-01T02:52:36+00:00 step 2:
list_recent_deploymentsminutes=30, service=payments (found nothing)
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-payment-failures","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [47.0 (01/10/26 02:51:00)] was greater than or equal to the threshold (3.0).","since":"2026-10-01T02:52:29Z","metric":{"namespace":"NightShift","...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
Allowlisted actions, each waiting for owner approval:
set_operational_flag name=payments_degraded_mode value=true
Hypotheses
- likely: The payment provider is failing. Defer payments until it recovers.
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