Skip to main content

Worker tuning simulator

View Markdown

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

Current run time 0.0s
Workflow generation mode
x
Simulator config
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.

2 Workflow Tasks / Workflow3 Activity Tasks / Workflow
Worker capacity
Worker resources
Task resource profiles
Workflow Task
Activity Task

Temporal Task Flow

CLIENTWorkflow StartTEMPORAL SERVICETemporal Service CoreWorkflow state / historyTask schedulingWORKFLOW LANEACTIVITY LANEWORKER Aworkflow-poller-1 - long-pollingworkflow-slot-1 - availableworkflow-slot-2 - available0 / 6Hit 0% · Replays 0activity-poller-1 - long-pollingactivity-poller-2 - long-pollingactivity-slot-1 - availableactivity-slot-2 - availableactivity-slot-3 - availableactivity-slot-4 - availableMemory colorsBase WorkerActive TasksWorkflow cache0% (0 / 1 CPU)Memory: 19.2 MB base Workers + 0 MB active Tasks + 0 MB Workflow cache = 19.2 MB of 128 MB19.2 MB base Worker memory0 MB active Task memory0 MB Workflow cache memory15% (19.2 / 128 MB)0% (0 / 1 throughput)WorkflowWorkflow TaskActivity TaskCommand / resultRPCCOMMANDS / RESULTS -> TEMPORAL
Monitoring
Temporal metrics

Poller busy ratio

Share of configured Pollers holding a received Task

0%Resource throttlingAuto-pause
MaximumWorkflow TasksActivity Tasks
100%0%0s0.1s0.0s

Slot utilization

Share of execution Slots reserved or occupied

0%Resource throttlingAuto-pause
MaximumWorkflow TasksActivity Tasks
100%0%0s0.1s0.0s

Sync match rate

Rolling 5-second share of Tasks delivered immediately to waiting Pollers

0%Resource throttlingAuto-pause
MaximumWorkflow TasksActivity Tasks
100%0%0s0.1s0.0s

Backlog

Tasks waiting in Workflow and Activity Task Queues

0 TasksResource throttlingAuto-pause
TotalWorkflow TasksActivity Tasks
100s0.1s0.0s
Worker resources

CPU utilization

Used CPU as a share of allocated Worker CPU

0%Resource throttlingAuto-pause
100%0%0s0.1s0.0s

Memory utilization

Used memory as a share of allocated Worker memory

15%Resource throttlingAuto-pause
100%0%0s0.1s0.0s

I/O utilization

Used I/O as a share of allocated Worker throughput

0%Resource throttlingAuto-pause
100%0%0s0.1s0.0s
Load testing

Task throughput

Rolling 5-second completion rate

0.00 Tasks/sResource throttlingAuto-pause
Total TasksWorkflow TasksActivity Tasks
1.00/s0/s0s0.1s0.0s

Task completion latency

Rolling 5-second mean from Task scheduling through completion

0.00sResource throttlingAuto-pause
OverallWorkflow TasksActivity Tasks
1.00s0s0s0.1s0.0s

Task statistics

Current-run throughput and schedule-to-completion latency distribution

Task groupCompletedTasks/sAverageP25P50P75P95P99Max
All Tasks00.000.00s0.00s0.00s0.00s0.00s0.00s0.00s
Workflow Tasks00.000.00s0.00s0.00s0.00s0.00s0.00s0.00s
Activity Tasks00.000.00s0.00s0.00s0.00s0.00s0.00s0.00s
Diagnostics
{
  "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: