Skip to content

Commit c365b13

Browse files
austonliclaudeDuncanma
authored
Make it obvious each troubleshooting section is a recommended alert (#5046)
Reading a section on its own, nothing said it corresponded to an alert. It opened with a bare "Metric:" line, so the threshold, for duration, and severity existed only in the tables on the alerting page. Anyone arriving from a firing alert's runbook_url or from search had no way to know what condition was supposed to have triggered it. All 20 sections now open with the full alert definition: **Recommended alert:** temporal_workflow_task_execution_failed with failure_reason=NonDeterminismError Fires on any occurrence, held for 1m. Routed Critical by default. Tune the threshold. Two sections cover more than one alert, and say so: UNIMPLEMENTED and INTERNAL are separate alerts on the same metric, and Workflow Task schedule-to-start has two thresholds. Each of the three pages also opens by saying every section on it is one of the recommended alerts, and that if you arrived from a firing alert, the section you landed on is its runbook. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Duncan Mackenzie <duncanma@duncanmackenzie.net>
1 parent 022cfcb commit c365b13

3 files changed

Lines changed: 52 additions & 23 deletions

File tree

docs/troubleshooting/execution-failures.mdx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ tags:
1919
This guide covers failures that happen while your Workflow and Activity code is running on a Worker: replay mismatches, oversized responses, unhandled exceptions, and Local Activities that outrun the Workflow Task heartbeat timeout.
2020
It applies to Workers connected to Temporal Cloud and to a self-hosted Temporal Service.
2121

22-
For alert thresholds and `for` durations, see [Worker alerting](/best-practices/worker-alerting).
22+
Every section on this page is one of the recommended alerts in [Worker alerting](/best-practices/worker-alerting).
23+
Each one opens with the alert definition, explains what the condition costs you, then walks through triage.
24+
If you got here from a firing alert, the section you landed on is the runbook for it.
25+
2326
For metric definitions, see the [Temporal SDK metrics reference](/references/sdk-metrics).
2427

2528
[`temporal_workflow_task_execution_failed`](/references/sdk-metrics#workflow_task_execution_failed) carries a `failure_reason` tag along with `namespace`, `task_queue`, and `workflow_type`.
@@ -28,7 +31,8 @@ Alert on each `failure_reason` separately.
2831

2932
## Non-determinism error {/* #non-determinism-error */}
3033

31-
**Metric:** `temporal_workflow_task_execution_failed` with `failure_reason=NonDeterminismError`
34+
**Recommended alert:** `temporal_workflow_task_execution_failed` with `failure_reason=NonDeterminismError`
35+
Fires on any occurrence, held for 1m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
3236

3337
Replay produced a different sequence of commands than the one recorded in Event History.
3438
The Worker noticed that the Workflow code it is running no longer matches what the Execution has already done.
@@ -51,7 +55,8 @@ This will not clear up on its own.
5155

5256
## gRPC message too large {/* #grpc-message-too-large */}
5357

54-
**Metric:** `temporal_workflow_task_execution_failed` with `failure_reason=GrpcMessageTooLarge`
58+
**Recommended alert:** `temporal_workflow_task_execution_failed` with `failure_reason=GrpcMessageTooLarge`
59+
Fires on any occurrence, held for 1m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
5560

5661
The Workflow Task response was bigger than the gRPC message size limit.
5762
The Worker tried `RespondWorkflowTaskCompleted` and something rejected it: the gRPC library on the SDK side, a proxy or load balancer in the path, or the gRPC library on the Temporal Service side when it went to receive.
@@ -84,7 +89,8 @@ Check the Workflow terminate rate on your server dashboard. A spike alongside th
8489

8590
## Workflow Task execution failures elevated {/* #workflow-task-execution-failures-elevated */}
8691

87-
**Metric:** `temporal_workflow_task_execution_failed` with `failure_reason=WorkflowError`
92+
**Recommended alert:** `temporal_workflow_task_execution_failed` with `failure_reason=WorkflowError`
93+
Fires when the rate goes above 10/s, held for 2m. Routed Warning by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
8894

8995
Workflow Tasks are failing steadily from unhandled exceptions and panics in Workflow code that the SDK catches and reports.
9096
`WorkflowError` is the catch-all reason. It covers thread pool exhaustion, unhandled exceptions thrown inside the Workflow function, and Data Converter errors.
@@ -108,7 +114,8 @@ Unlike `GrpcMessageTooLarge`, the Temporal Service won't terminate the Execution
108114

109115
## Workflow Task execution latency high {/* #workflow-task-execution-latency-high */}
110116

111-
**Metric:** [`temporal_workflow_task_execution_latency`](/references/sdk-metrics#workflow_task_execution_latency), tagged `namespace`, `task_queue`, and `workflow_type`
117+
**Recommended alert:** [`temporal_workflow_task_execution_latency`](/references/sdk-metrics#workflow_task_execution_latency), tagged `namespace`, `task_queue`, and `workflow_type`
118+
Fires when p99 goes above 10s, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
112119

113120
Workflow Tasks are taking too long to execute on the Worker.
114121
The default Workflow Task timeout is 10 seconds, so at or above that value the Temporal Service is actively timing out Workflow Tasks.
@@ -135,7 +142,8 @@ At scale this compounds: more timeouts cause more cold replays, cold replays dri
135142

136143
## Activity execution failures elevated {/* #activity-execution-failures-elevated */}
137144

138-
**Metric:** [`temporal_activity_execution_failed`](/references/sdk-metrics#activity_execution_failed), tagged `activity_type`
145+
**Recommended alert:** [`temporal_activity_execution_failed`](/references/sdk-metrics#activity_execution_failed), tagged `activity_type`
146+
Fires when the rate goes above 10/s, held for 2m. Routed Warning by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
139147

140148
Activities are failing outright at a sustained rate: returning failures, not timing out.
141149

@@ -158,7 +166,8 @@ One caveat: internal failures increment this counter no matter what category you
158166

159167
## Unregistered Activity invocation {/* #unregistered-activity-invocation */}
160168

161-
**Metric:** [`temporal_unregistered_activity_invocation`](/references/sdk-metrics#unregistered_activity_invocation), tagged `activity_type`, `task_queue`, and `workflow_type`
169+
**Recommended alert:** [`temporal_unregistered_activity_invocation`](/references/sdk-metrics#unregistered_activity_invocation), tagged `activity_type`, `task_queue`, and `workflow_type`
170+
Fires on any occurrence, held for 1m. Routed Critical by default. Go SDK only. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
162171

163172
A Workflow scheduled an Activity that the Worker polling that Task Queue has no registered implementation for.
164173

@@ -178,7 +187,8 @@ This is nearly always a deployment mistake rather than a runtime condition: Work
178187

179188
## Local Activity latency exceeds the heartbeat timeout {/* #local-activity-latency-exceeds-the-heartbeat-timeout */}
180189

181-
**Metric:** [`temporal_local_activity_execution_latency`](/references/sdk-metrics#local_activity_execution_latency), tagged `activity_type`
190+
**Recommended alert:** [`temporal_local_activity_execution_latency`](/references/sdk-metrics#local_activity_execution_latency), tagged `activity_type`
191+
Fires when p99 goes above 30m, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#execution-failures).
182192

183193
A [Local Activity](/local-activity) is running past the Workflow Task heartbeat timeout, which defaults to 30 minutes.
184194

docs/troubleshooting/request-failures.mdx

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ tags:
1919
This guide covers gRPC failures and slow requests between your Temporal SDK Workers or Clients and the Temporal Service.
2020
It applies to Workers connected to Temporal Cloud and to a self-hosted Temporal Service.
2121

22-
For alert thresholds and `for` durations, see [Worker alerting](/best-practices/worker-alerting).
22+
Every section on this page is one of the recommended alerts in [Worker alerting](/best-practices/worker-alerting).
23+
Each one opens with the alert definition, explains what the condition costs you, then walks through triage.
24+
If you got here from a firing alert, the section you landed on is the runbook for it.
25+
2326
For metric definitions, see the [Temporal SDK metrics reference](/references/sdk-metrics).
2427

2528
[`temporal_request_failure`](/references/sdk-metrics#request_failure) increments when the Temporal Service returns a non-OK gRPC status code on a standard operation.
@@ -37,7 +40,8 @@ And `status_code` values are `UPPER_SNAKE_CASE` in every SDK, matching the gRPC
3740

3841
## NOT_FOUND on respond operations {/* #not_found-on-respond-operations */}
3942

40-
**Metric:** `temporal_request_failure` with `status_code=NOT_FOUND` on `RespondWorkflowTaskCompleted`, `RespondWorkflowTaskFailed`, `RespondActivityTaskCompleted`, or `RespondActivityTaskFailed`
43+
**Recommended alert:** `temporal_request_failure` with `status_code=NOT_FOUND` on `RespondWorkflowTaskCompleted`, `RespondWorkflowTaskFailed`, `RespondActivityTaskCompleted`, or `RespondActivityTaskFailed`
44+
Fires on any occurrence, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
4145

4246
A Worker finished a Workflow Task or Activity Task and reported the result, and the Temporal Service replied that the task no longer exists.
4347
There are three causes:
@@ -77,7 +81,8 @@ If SDK-side metrics look normal and the Execution was not terminated or timed ou
7781

7882
## NOT_FOUND on Activity heartbeat {/* #not_found-on-activity-heartbeat */}
7983

80-
**Metric:** `temporal_request_failure` with `status_code=NOT_FOUND` on `RecordActivityTaskHeartbeat`
84+
**Recommended alert:** `temporal_request_failure` with `status_code=NOT_FOUND` on `RecordActivityTaskHeartbeat`
85+
Fires on any occurrence, held for 5m. Routed Warning by default, though see the caveat below. [Tune the threshold](/best-practices/worker-alerting#request-failures).
8186

8287
A Worker heartbeated a running Activity and the Temporal Service replied that the task no longer exists.
8388
The Service has already cancelled the in-flight Activity Task: either the `heartbeatTimeout` fired before the next heartbeat call arrived, the `startToClose` timeout expired while the Activity was still executing, or the Workflow Execution is no longer running.
@@ -102,7 +107,8 @@ The Activity will time out on every attempt until you fix the cause, holding Tas
102107

103108
## RESOURCE_EXHAUSTED on user-facing operations {/* #resource_exhausted-on-user-facing-operations */}
104109

105-
**Metric:** `temporal_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `StartWorkflowExecution`, `SignalWithStartWorkflowExecution`, `SignalWorkflowExecution`, `UpdateWorkflowExecution`, or `ExecuteMultiOperation`
110+
**Recommended alert:** `temporal_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `StartWorkflowExecution`, `SignalWithStartWorkflowExecution`, `SignalWorkflowExecution`, `UpdateWorkflowExecution`, or `ExecuteMultiOperation`
111+
Fires on any occurrence, held for 1m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
106112

107113
The Temporal Service is throttling the operations your application code uses to start Workflows and deliver Signals and Updates.
108114
The SDK retries these automatically for up to 60 seconds.
@@ -139,7 +145,8 @@ If the cause is system overload or an open circuit breaker, the Temporal Service
139145

140146
## RESOURCE_EXHAUSTED on respond operations {/* #resource_exhausted-on-respond-operations */}
141147

142-
**Metric:** `temporal_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `RespondWorkflowTaskCompleted`, `RespondWorkflowTaskFailed`, `RespondActivityTaskCompleted`, or `RespondActivityTaskFailed`
148+
**Recommended alert:** `temporal_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `RespondWorkflowTaskCompleted`, `RespondWorkflowTaskFailed`, `RespondActivityTaskCompleted`, or `RespondActivityTaskFailed`
149+
Fires on any occurrence, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
143150

144151
The Temporal Service is throttling Workers reporting task results.
145152
The SDK retries automatically, but a delayed respond call has a compounding cost: the Worker holds the Task slot until the call succeeds, and the Service-side task stays in-flight until the response lands.
@@ -165,7 +172,8 @@ Check persistence latency filtered to `UpdateWorkflowExecution`. Slow persistenc
165172

166173
## RESOURCE_EXHAUSTED on poll operations {/* #resource_exhausted-on-poll-operations */}
167174

168-
**Metric:** `temporal_long_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `PollWorkflowTaskQueue` or `PollActivityTaskQueue`
175+
**Recommended alert:** `temporal_long_request_failure` with `status_code=RESOURCE_EXHAUSTED` on `PollWorkflowTaskQueue` or `PollActivityTaskQueue`
176+
Fires on any occurrence, held for 5m. Routed Warning by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
169177

170178
The Temporal Service is throttling Worker poll calls.
171179
Poll operations are long-poll requests, so they increment `temporal_long_request_failure` rather than `temporal_request_failure`.
@@ -193,7 +201,8 @@ Scale Worker capacity first if schedule-to-start latency is the real problem.
193201

194202
## UNIMPLEMENTED or INTERNAL from the Temporal Service {/* #unimplemented-or-internal-from-the-temporal-service */}
195203

196-
**Metric:** `temporal_request_failure` with `status_code=UNIMPLEMENTED` or `status_code=INTERNAL`, on any operation
204+
**Recommended alert:** `temporal_request_failure` with `status_code=UNIMPLEMENTED` or `status_code=INTERNAL`, on any operation
205+
Two alerts, one per status code. Each fires on any occurrence, held for 2m, routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
197206

198207
These two status codes point at the Temporal Service rather than at your application, and they behave differently in the SDK.
199208
Alert on them separately.
@@ -224,7 +233,8 @@ For UNIMPLEMENTED, check that every Frontend, History, and Matching pod is runni
224233

225234
## Request latency high on user-facing operations {/* #request-latency-high-on-user-facing-operations */}
226235

227-
**Metric:** [`temporal_request_latency`](/references/sdk-metrics#request_latency) on `StartWorkflowExecution`, `SignalWithStartWorkflowExecution`, `SignalWorkflowExecution`, or `ExecuteMultiOperation`
236+
**Recommended alert:** [`temporal_request_latency`](/references/sdk-metrics#request_latency) on `StartWorkflowExecution`, `SignalWithStartWorkflowExecution`, `SignalWorkflowExecution`, or `ExecuteMultiOperation`
237+
Fires when p99 goes above 2s, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#request-failures).
228238

229239
p99 latency on the operations your application calls synchronously has risen above your threshold.
230240

docs/troubleshooting/worker-capacity.mdx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ tags:
2121
This guide covers what to do when your Workers stop keeping up with their Task Queues: slots that never free up, pollers that quit polling, Tasks sitting in the queue, and a [Sticky Execution](/sticky-execution) cache that isn't earning its keep.
2222
It applies to Workers connected to Temporal Cloud and to a self-hosted Temporal Service.
2323

24-
For alert thresholds and `for` durations, see [Worker alerting](/best-practices/worker-alerting).
24+
Every section on this page is one of the recommended alerts in [Worker alerting](/best-practices/worker-alerting).
25+
Each one opens with the alert definition, explains what the condition costs you, then walks through triage.
26+
If you got here from a firing alert, the section you landed on is the runbook for it.
27+
2528
For Worker sizing and tuning, see [Worker performance](/develop/worker-performance) and [Worker deployment and performance](/best-practices/worker).
2629

2730
These failure modes are chained together.
@@ -30,7 +33,8 @@ When several fire at once, don't treat them as separate problems. Work backward
3033

3134
## Worker Task slots exhausted {/* #worker-task-slots-exhausted */}
3235

33-
**Metric:** [`temporal_worker_task_slots_available`](/references/sdk-metrics#worker_task_slots_available) reaching 0, tagged `worker_type`
36+
**Recommended alert:** [`temporal_worker_task_slots_available`](/references/sdk-metrics#worker_task_slots_available), tagged `worker_type`
37+
Fires when the gauge reaches 0, held for 2m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
3438

3539
Every Task execution slot for this `worker_type` and Task Queue is occupied, so no new Tasks can be picked up.
3640
The SDK blocks before issuing its next poll until a slot is released.
@@ -80,7 +84,8 @@ If that goes on past the Workflow Task heartbeat timeout, 30 minutes by default,
8084

8185
## All pollers disconnected {/* #all-pollers-disconnected */}
8286

83-
**Metric:** [`temporal_num_pollers`](/references/sdk-metrics#num_pollers) reaching 0, tagged `poller_type` and `task_queue`
87+
**Recommended alert:** [`temporal_num_pollers`](/references/sdk-metrics#num_pollers), tagged `poller_type` and `task_queue`
88+
Fires when the gauge reaches 0, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
8489

8590
No active pollers remain for this poller type and Task Queue.
8691
Workers have stopped polling entirely and Tasks are accumulating with nothing to process them.
@@ -117,7 +122,8 @@ A non-zero authorization system failure count means the auth plugin itself is br
117122

118123
## Task completions dropped to zero {/* #task-completions-dropped-to-zero */}
119124

120-
**Metric:** [`temporal_request`](/references/sdk-metrics#request) rate reaching 0 on `RespondWorkflowTaskCompleted` or `RespondActivityTaskCompleted`
125+
**Recommended alert:** [`temporal_request`](/references/sdk-metrics#request) on `RespondWorkflowTaskCompleted` or `RespondActivityTaskCompleted`
126+
Fires when the rate reaches 0 while the Task Queue still has demand, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
121127

122128
The SDK only bumps this counter after a response succeeds, so a zero rate means nothing is landing.
123129

@@ -153,7 +159,8 @@ Check overall cluster health: service errors by Namespace, persistence availabil
153159

154160
## Workflow Task schedule-to-start latency elevated {/* #workflow-task-schedule-to-start-latency-elevated */}
155161

156-
**Metric:** [`temporal_workflow_task_schedule_to_start_latency`](/references/sdk-metrics#workflow_task_schedule_to_start_latency), tagged `namespace` and `task_queue`
162+
**Recommended alert:** [`temporal_workflow_task_schedule_to_start_latency`](/references/sdk-metrics#workflow_task_schedule_to_start_latency), tagged `namespace` and `task_queue`
163+
Two alerts at different thresholds. One fires when p99 goes above 5s, the other above 30m. Both held for 5m and routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
157164

158165
Workflow Tasks are sitting in the queue before a Worker picks them up.
159166
Alert at two levels: a lower threshold that catches meaningful delay, and a much higher one that catches a stalled Task Queue.
@@ -189,7 +196,8 @@ Then check the server-side concurrent poller count for this Task Queue to see wh
189196

190197
## Activity schedule-to-start latency elevated {/* #activity-schedule-to-start-latency-elevated */}
191198

192-
**Metric:** [`temporal_activity_schedule_to_start_latency`](/references/sdk-metrics#activity_schedule_to_start_latency), tagged `namespace` and `task_queue`
199+
**Recommended alert:** [`temporal_activity_schedule_to_start_latency`](/references/sdk-metrics#activity_schedule_to_start_latency), tagged `namespace` and `task_queue`
200+
Fires when p99 goes above 30m, held for 5m. Routed Critical by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
193201

194202
Activity Tasks are sitting in the queue before a Worker picks them up.
195203

@@ -216,7 +224,8 @@ Check the approximate Task backlog and the server-side concurrent poller count f
216224

217225
## Sticky cache holding zero entries under load {/* #sticky-cache-holding-zero-entries-under-load */}
218226

219-
**Metric:** [`temporal_sticky_cache_size`](/references/sdk-metrics#sticky_cache_size) reaching 0 while the Worker is processing Workflow Tasks
227+
**Recommended alert:** [`temporal_sticky_cache_size`](/references/sdk-metrics#sticky_cache_size)
228+
Fires when the gauge reaches 0 while the Worker is processing Workflow Tasks, held for 15m. Routed Warning by default. [Tune the threshold](/best-practices/worker-alerting#worker-capacity).
220229

221230
This gauge tells you how many Workflow Executions the Worker is holding in its [Sticky Execution](/sticky-execution) cache right now.
222231
It is not the configured cache size.

0 commit comments

Comments
 (0)