Skip to content

Why we wrote our own scheduler instead of using a queue

8 min readPlaceholder Author, Engineering

The default architecture for a workflow engine looks like this: an API writes a job to a queue, workers poll the queue, each step round-trips through the broker. It works, and it is why a ten-step flow takes four seconds on tools you have used.

When we profiled that architecture, the steps themselves were rarely the cost. The cost was the space between steps: serialization, broker hops, polling intervals, and worker wake-ups. A flow spends most of its life waiting for its own infrastructure.

So GoRunner's engine schedules steps in-process. A run is a goroutine, a step transition is a function call, and the queue only appears at the edges where durability demands it. Steps that need external IO yield; everything else proceeds at memory speed.

The trade-offs are real: in-process scheduling means we own backpressure, fairness, and crash recovery ourselves rather than delegating to a broker. The post below walks through how we handle each, and where the design stops being clever and starts being careful.

This is the first post in a series on the engine's internals. The numbers we publish here will always come with a methodology and a way to reproduce them.

Author attribution is a placeholder until the team page goes live with real names. The engineering content stands either way.

Ready when you say go.

Build your first flow in minutes. Free plan, no card, and the canvas is yours.

Free plan · 1,000 runs a month · self-host or cloud