You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
OOM Crashes are still happening in the worker #905
the last payload is about 5mb on disk pretty-printed. So not big I'd say.
I think the worker blew up around 1gb of memory, but I'm not good at understanding the stack trace
I don't think the worker is under particularly high load
I suspect this has more to do with the main worker thread processing many smaller events, than being blown up by one big event. But I'm really not sure.
Perhaps more than anything I'd really really like a way to notify us and the app about these OOM kills. But the nature of it means we can't do much: IIRC we do get a callback hook but it's strictly synchronous.
the inner worker thread has created/downloaded a payload too large
somewhere on transferring that to the main thread, the main thread has blown up
I believe it's possible for this to occur naturally, just with a big payload, but a worker under load, or that has been running for a longer time, will have less main thread heap available and so be more likely to see this issue. I've had to limit the memory quite extensively here.
Ok I'm about convinced that there's no magic here. It all depends on the numbers.
The above example is fine if state is always redacted from events, or if you set --payload-memory to a really low value. Suddenly it all works fine.
So nothing is wrong, exactly. If you send a payload to the main process, and the main process runs out of memory while processing it, then the process will blow up.
So what we're looking at is simply too much memory being used in the main process. If the main process is full then event a simple js object will be enough to cause a blow up.
That gives me two places to go:
There's clearly a memory leak in production. If every run adds 1mb to the main process heap, then after enough runs a big payload will kill us. But if I can track this down I should be able to restore parity.
Is there any way we can isolate any risky areas of processing? Compilation, autoinstall and event handling are all places where we could have memory problems. Worker threads aren't isolated, they share memory - so if a worker thread blows the heap, the whole process goes down (90% sure this is true but worth verifying again). The best defence I think I can see is the push the websocket connection down into the child process. Now all payload processing is shared by the child process, and any issues belonging to the run will be caught there.
This means opening up #544 - an old issue where I put a lot of thought into this. It's quite a big deal, a lot of code needs rearranging.
The main worker thread has a memory limit coming from somewhere. Seems to be about 1.2gb. Might be a node default, might come from the docker, who knows
The limit itself is quite reasonable
We get heap errors because a memory leak is ticking up the main process memory until it hits that limit
Then node crashes
This is why we get heap errors at 50% pod memory capacity. The pod may have memory, but the node process does not.
Activity
josephjclark commentedon Mar 14, 2025
Perhaps more than anything I'd really really like a way to notify us and the app about these OOM kills. But the nature of it means we can't do much: IIRC we do get a callback hook but it's strictly synchronous.
josephjclark commentedon Sep 15, 2025
So I finally have a repro for this:
Start the worker with a limited heap:
That's a 50mb main thread limit. Node's own debugging tells me the heap is around double that
(question: if the main parent has this limit, do the children also have it? That's driven by config in the worker itself right?)
Now run a workflow with this step:
I see this error locally:
I think this has reproduced the case where:
I believe it's possible for this to occur naturally, just with a big payload, but a worker under load, or that has been running for a longer time, will have less main thread heap available and so be more likely to see this issue. I've had to limit the memory quite extensively here.
josephjclark commentedon Sep 15, 2025
nodejs: Understanding and Tuning Memory
josephjclark commentedon Sep 15, 2025
Setting
--run-memorygives me akilledstatus on the run and the worker survives, as expectedjosephjclark commentedon Sep 15, 2025
Ok I'm about convinced that there's no magic here. It all depends on the numbers.
The above example is fine if state is always redacted from events, or if you set
--payload-memoryto a really low value. Suddenly it all works fine.So nothing is wrong, exactly. If you send a payload to the main process, and the main process runs out of memory while processing it, then the process will blow up.
So what we're looking at is simply too much memory being used in the main process. If the main process is full then event a simple js object will be enough to cause a blow up.
That gives me two places to go:
This means opening up #544 - an old issue where I put a lot of thought into this. It's quite a big deal, a lot of code needs rearranging.
josephjclark commentedon Oct 29, 2025
Whats basically happening here is:
The memory leak in #1099 seems to have fixed this