Skip to content

[Bug] workflow cache size can grow and crash worker processes with memory error #2227

Description

@millerick

What are you really trying to do?

Our production system uses a workflow worker to run about 100 distinct workflow_types. We use zod schemas to validate inputs and outputs to workflows and activities. Many of these are defined at the top level of files, all of which appear to be instantiated and have their own allocation in memory for each workflow that is in the cache. We want our production system to be able to survive bursts of workflows starting without the workers crashing.

Describe the bug

The workflow cache size can grow and crash the process with an out of memory error. This can be achieved with the default workflow cache settings. Our production workers use a 6GB memory request/JS heap size and would regularly see crashes due to exhausting memory as the cache size grew. It is particularly noticeable if we received a large burst of new workflows since those would all start around the same time and crashes would happen before the workflows would have a chance to complete--occasionally resulting in all workers crashing and ending up in a crash loop backoff--preventing our system from continuing to process workflows until someone manually scaled up the number of workers to ensure that the average number of workflows per worker was low enough.

These crashes stopped when we explicitly capped the size of the workflow cache to 60 workflows. Eventually this number will need to be lowered as our codebase grows larger. I don't want to have to manually tune and tweak this value every few months. The workflow cache should be safely evicted from if it begins to get to the size where the process could crash as a result. I believe that when the cache grows too large, instead of crashing, old workflows should be evicted from the cache--particularly if the user has not changed the size of the cache themselves.

Minimal Reproduction

https://github.com/millerick/temporal-worker-crash-reproduction reproduces the issue

Follow the instructions in the README and a crash will happen in the worker

2026-07-21T18:26:14.282Z [ERROR] Worker failed {
  sdkComponent: 'worker',
  taskQueue: 'crash-repro',
  error: UnexpectedError: Workflow Worker Thread exited prematurely: Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
      at Worker.<anonymous> (/System/Volumes/Data/src/temporal-crash-reproduction/node_modules/@temporalio/worker/lib/workflow/threaded-vm.js:68:30)
      at Worker.emit (node:events:518:28)
      at [kOnExit] (node:internal/worker:313:12)
      at Worker.<computed>.onexit (node:internal/worker:229:20)
      at Worker.callbackTrampoline (node:internal/async_hooks:130:17) {
    cause: Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
        at [kOnExit] (node:internal/worker:313:26)
        at Worker.<computed>.onexit (node:internal/worker:229:20)
        at Worker.callbackTrampoline (node:internal/async_hooks:130:17) {
      code: 'ERR_WORKER_OUT_OF_MEMORY'
    }
  }
}
2026-07-21T18:26:14.282Z [INFO] Worker state changed { sdkComponent: 'worker', taskQueue: 'crash-repro', state: 'FAILED' }
[worker] FATAL — worker crashed: UnexpectedError: Workflow Worker Thread exited prematurely: Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
    at Worker.<anonymous> (/System/Volumes/Data/src/temporal-crash-reproduction/node_modules/@temporalio/worker/lib/workflow/threaded-vm.js:68:30)
    at Worker.emit (node:events:518:28)
    at [kOnExit] (node:internal/worker:313:12)
    at Worker.<computed>.onexit (node:internal/worker:229:20)
    at Worker.callbackTrampoline (node:internal/async_hooks:130:17) {
  cause: Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
      at [kOnExit] (node:internal/worker:313:26)
      at Worker.<computed>.onexit (node:internal/worker:229:20)
      at Worker.callbackTrampoline (node:internal/async_hooks:130:17) {
    code: 'ERR_WORKER_OUT_OF_MEMORY'
  }
}
[worker][crash] rss=956MB (peak 2236MB, -1280MB) mainHeapUsed=209MB external=28MB

Environment/Versions

  • OS and processor: observed on Mac and Linux
  • Temporal Version: 1.17

Additional context

see above

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions