Container resource caps: memory, CPU and PIDs

Container resource caps limit the memory, CPU and processes one container may use; DevFlow caps each test, build and agent container at 4 GB of memory, 4 CPUs and 512 processes by default.

Why cap containers

Without limits, one heavy test suite can exhaust the RAM of the whole host and take other tasks down with it. A cap turns that into the failure of a single run.

The defaults

Every container DevFlow starts for tests, builds and installs, and in container mode for coding agents, gets the same flags:

  • --memory 4g;
  • --memory-swap 6g, which allows 2 GB of swap on top;
  • --cpus 4;
  • --pids-limit 512, which stops a runaway fork loop.

Why the swap ceiling is higher

--memory-swap is the combined ceiling of RAM and swap. Setting it above --memory is deliberate: a large build spills into swap and slows down instead of being killed at the limit, while an equal value would leave no headroom at all.

Non-root by default

The same flag set runs each container as the API's own non-root user, with HOME set to /tmp and corepack's cache under it. Files written into the bind-mounted worktree therefore keep the right owner.

Commands must not assume root as a consequence: no sudo, no apt-get, no global npm installs, and pnpm or Yarn are called through corepack rather than enabled system-wide.

When a limit is hit

A container killed for lack of RAM exits with code 137. DevFlow classifies that as a build environment error, not a code defect, and skips the rework loop, because the implementer cannot fix a resource limit from inside the worktree. A permission denial caused by the non-root user is classified as a build environment error too.

The error message names the active caps and the settings to raise, so the fix lands where it belongs: in the host configuration, the image or the repository's build command. For a coding agent's own run, an uncancelled exit 137 counts as an agent environment error instead, with the same result: no rework, and a failure card that links to the repository settings.

A worked example

Suppose a repository's test suite starts a database and a browser in one container and peaks at 5 GB. The first 4 GB come from RAM and the next gigabyte from swap, so the run is slower but finishes. A suite that needs more than 6 GB in total is stopped, and the task reports the caps instead of asking an agent to rewrite tests.

Older commands

Test commands stored before these caps existed carry a full docker run wrapper. DevFlow injects the missing flags into such rows when they run, checking each flag on its own, so a row never gets the same flag twice.

FAQ

Can an operator change DevFlow's container resource caps?

Yes. DOCKER_MEMORY_LIMIT, DOCKER_MEMORY_SWAP_LIMIT, DOCKER_CPU_LIMIT and DOCKER_PIDS_LIMIT set DevFlow's container resource caps, whose defaults are 4g, 6g, 4 and 512.

How many DevFlow test containers can run at the same time?

DevFlow's scheduler caps concurrent Docker runs with DOCKER_MAX_CONCURRENT, by default a quarter of the host's CPU count and at least 1, so extra work waits for a free slot.