Worker tuning simulator
This simulator shows how Worker settings affect Task throughput and Task Queue backlog. It models Pollers, Slots, the Workflow cache, and CPU, memory, and I/O capacity on a Worker, and runs entirely in your browser.
The simulator is a teaching tool. It doesn't connect to Temporal, read metrics from your Workers, or recommend production settings. The numbers show relative behavior, so use them to see which limit a Worker hits first, not to size a real deployment.
Press Start continuous to begin generating Workflows, then change a setting while the simulation runs. The page works best on a desktop-width screen.
Worker tuning simulator
Custom settings
Workflow shape
Each Workflow Task schedules one execution phase of Activities. Every Activity in that phase must finish before the next execution phase starts.
Worker capacity
Related docs: Task Pollers, Task Slots, Worker performance options
Worker resources
Related docs: Worker tuning quick reference, Workflow cache tuning
Task resource profiles
Temporal Task Flow
Learn more: How Workers poll and execute Tasks, Task Queues, Sticky Execution and the Workflow cache
Monitoring
Temporal metrics
Related docs: SDK metrics for Worker tuning, Slot metrics, Task Queue backlog
Poller busy ratio
Share of configured Pollers holding a received Task
Slot utilization
Share of execution Slots reserved or occupied
Sync match rate
Rolling 5-second share of Tasks delivered immediately to waiting Pollers
Backlog
Tasks waiting in Workflow and Activity Task Queues
Worker resources
Related docs: Compute, memory, and I/O settings
CPU utilization
Used CPU as a share of allocated Worker CPU
Memory utilization
Used memory as a share of allocated Worker memory
I/O utilization
Used I/O as a share of allocated Worker throughput
Load testing
Related docs: Latency metrics
Task throughput
Rolling 5-second completion rate
Task completion latency
Rolling 5-second mean from Task scheduling through completion
Task statistics
Current-run throughput and schedule-to-completion latency distribution
| Task group | Completed | Tasks/s | Average | P25 | P50 | P75 | P95 | P99 | Max |
|---|---|---|---|---|---|---|---|---|---|
| All Tasks | 0 | 0.00 | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s |
| Workflow Tasks | 0 | 0.00 | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s |
| Activity Tasks | 0 | 0.00 | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s | 0.00s |
Diagnose this on a real Worker: Troubleshoot Worker capacity, Alerting on Worker metricsDiagnostics
{
"simulatedTime": 0,
"queues": {
"workflow": 0,
"activity": 0
},
"workers": [
{
"id": "worker-1",
"displayId": "A",
"status": "active",
"cpuUtilization": 0,
"cpuDemand": 0,
"cpuThrottled": false,
"ioUtilization": 0,
"ioDemand": 0,
"ioThrottled": false,
"workflowPollers": [
{
"id": "workflow-poller-1",
"workerId": "worker-1",
"type": "workflow",
"state": "long-polling"
}
],
"activityPollers": [
{
"id": "activity-poller-1",
"workerId": "worker-1",
"type": "activity",
"state": "long-polling"
},
{
"id": "activity-poller-2",
"workerId": "worker-1",
"type": "activity",
"state": "long-polling"
}
],
"workflowSlots": [
{
"id": "workflow-slot-1",
"workerId": "worker-1",
"type": "workflow",
"state": "available",
"ordinal": 1
},
{
"id": "workflow-slot-2",
"workerId": "worker-1",
"type": "workflow",
"state": "available",
"ordinal": 2
}
],
"activitySlots": [
{
"id": "activity-slot-1",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 1
},
{
"id": "activity-slot-2",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 2
},
{
"id": "activity-slot-3",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 3
},
{
"id": "activity-slot-4",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 4
}
],
"memoryUtilization": 0.15,
"memoryUsedMb": 19.2,
"workflowCache": []
}
],
"aggregateWorkerResources": {
"workflowPollers": [
{
"id": "workflow-poller-1",
"workerId": "worker-1",
"type": "workflow",
"state": "long-polling"
}
],
"activityPollers": [
{
"id": "activity-poller-1",
"workerId": "worker-1",
"type": "activity",
"state": "long-polling"
},
{
"id": "activity-poller-2",
"workerId": "worker-1",
"type": "activity",
"state": "long-polling"
}
],
"workflowSlots": [
{
"id": "workflow-slot-1",
"workerId": "worker-1",
"type": "workflow",
"state": "available",
"ordinal": 1
},
{
"id": "workflow-slot-2",
"workerId": "worker-1",
"type": "workflow",
"state": "available",
"ordinal": 2
}
],
"activitySlots": [
{
"id": "activity-slot-1",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 1
},
{
"id": "activity-slot-2",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 2
},
{
"id": "activity-slot-3",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 3
},
{
"id": "activity-slot-4",
"workerId": "worker-1",
"type": "activity",
"state": "available",
"ordinal": 4
}
],
"cpuUtilization": 0,
"cpuDemand": 0,
"cpuThrottled": false,
"memoryUtilization": 0.15,
"memoryUsedMb": 19.2,
"memoryPressure": false,
"memoryCapacityMb": 128,
"ioUtilization": 0,
"ioDemand": 0,
"ioThrottled": false,
"workflowCache": {
"entries": [],
"cacheSize": 0,
"cacheCapacity": 6,
"cacheHits": 0,
"cacheMisses": 0,
"cacheEvictions": 0,
"cacheHitRate": 0,
"replaysStarted": 0,
"replayCpuSeconds": 0
}
},
"metrics": {
"activityThroughput": 0,
"totalTaskThroughput": 0,
"workflowTaskThroughput": 0,
"activityTaskThroughput": 0,
"workflowCompletions": 0,
"slotResidenceSeconds": 0,
"workflowScheduleToStart": 0,
"activityScheduleToStart": 0
},
"tasks": [],
"recentEvents": []
}
What to try
Use the Preset menu to load a scenario that is limited by one resource, run it until a backlog builds, then open Custom settings and raise the limit the preset names. Each preset causes Task Queue backlog for a different reason:
- Poller constrained: Too few Activity Pollers for the generated Activity Task rate. Add Activity Pollers and watch the backlog. On a real Worker, Poller Autoscaling adjusts the Poller count for you.
- Slot constrained: Few Slots, so Tasks wait even when Pollers are available. Compare adding Slots with adding Pollers.
- CPU constrained and I/O constrained: Tasks that demand more CPU or I/O than the Worker has. The resource charts show when the Worker is throttled.
- Memory constrained: A small Workflow cache on a Worker with little memory. Watch cache hits, evictions, and replays. See Sticky Execution for why the cache matters.
Expand Monitoring to explore common Temporal metrics for Worker capacity, including Poller busy ratio, Slot utilization, Sync Match rate, and Task Queue backlog. Compare these signals with Worker resource utilization, Task throughput, and schedule-to-completion latency.
Learn more
The simulator models behavior you can configure and measure on a real Worker:
- Pollers and Slots: Worker performance concepts, Worker performance options, and Poller Autoscaling.
- Slot suppliers: Worker runtime performance tuning.
- Workflow cache: Workflow cache tuning and Sticky Execution.
- CPU, memory, and I/O: the compute, memory, and I/O settings in the Worker tuning quick reference.
- Task Queues and Tasks: Task Queues, Tasks, and Task Queue performance.
- Metrics: the monitoring charts are the simulator's own versions of Worker signals, so they don't match SDK metric names one to one. For the real metrics, see Metrics reference by resource type, Performance metrics for tuning, and the SDK metrics reference.
- Diagnosing a running system: Troubleshoot Worker capacity, Alerting on Worker metrics, and Worker deployment and performance.