-
1
One laptop
Builds and tests ran on the machine we were working on, and the tests took it over: the fans, the memory, the afternoon.
-
2
Two laptops
A second machine meant sharing the work by hand: this one runs these tests, that one runs the rest, and someone copies the results.
-
3
Two laptops and two Mac Studios
macOS and iOS work needs Macs, so two Mac Studios joined. Nothing scheduled work across them: each machine was its own island.
-
4
Six servers on Buildbarn
Remote execution with a shared cache was a big step. Builds spread over six servers, and a result computed once was reused everywhere.
-
5
Where that broke
Fixed-size slots
The runner slot had one fixed memory size, 7 GiB. An action that needed more was killed for memory; one that needed less left the slot mostly idle; and some builds fit no slot at all. The numbers we kept from that time:
- 2026-09-28: a survey of heavy compiles found about 120 binaries that each took 10 to 27 minutes and 8 to 16 GiB: none of them fits a 7 GiB slot.
- 2026-09-27: the runner slot was resized from 9 GiB to 7 GiB after a measured peak of 4.98 GiB. Every action booked the whole 7 GiB.
- 2026-09-23 and 2026-09-24: the development machine ran out of memory and the kernel killed processes, both days.
Idle machines next to overloaded ones
Utilization depended on slot sizes chosen ahead of time, so machines could sit idle next to overloaded ones.
No UI, Mac or iOS testing
The farm had no support for UI tests, or for tests that need a real Mac or an iOS device.
Other farms
BuildBuddy solved some of this, but it isn't completely open source.
Why we built it
From one laptop to a farm of our own
kbf came out of what broke as we grew. This is the order it happened in, with the numbers we can show.
Dated facts come from our own notes. Numbers in the panel come from real builds on a kbf test farm. Anything not built yet is tagged specified.
The numbers
One fixed slot against a memory ladder
Here are the memory peaks of real actions, and what the two ways of giving them memory would do with the same peaks.
This is a model applied to real peaks from our farm's builds. It is not a count of past kills. We have no machine-readable record of what the earlier farm killed. The peaks are real: the daemon measures the peak memory of every action, and these are the actions that finished, from builds of a slice of a real project on a kbf test farm. Both schemes place the same peaks.
Buildbarn as it ran: one fixed runner slot of 7 GiB, every action booking all 7 GiB. It was resized from 9 GiB to 7 GiB on 2026-09-27, after a measured peak of 4.98 GiB. kbf uses its default ladder of 4, 16 and 32 GiB (--memory-ladder-gib).
The panel needs scripts. The text above and below holds the same story without it.
Buildbarn as it ran: one 7 GiB slot
The 2026-09-28 survey of heavy compiles found about 120 binaries that each needed 8 to 16 GiB. That is a separate dated measurement, not part of these peaks. Work of that size never fits a 7 GiB slot.
kbf's memory ladder: 4, 16 and 32 GiB
Every action starts on the first rung. One killed for memory is queued again one rung up, and its action key remembers that floor.
Booked memory is what a scheme reserves for an action; idle is booked minus the action's peak. The model counts memory only. The scheduler design has the rules.
Step 6
So we built kbf
One farm that runs the whole build, sizes work as it runs instead of by slots chosen ahead, runs macOS next to Linux, keeps what happened, and is Apache 2.0 licensed.