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
What are you really trying to do?
Our production system uses a workflow worker to run about 100 distinct
workflow_types. We usezodschemas 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
Environment/Versions
Additional context
see above