{"slug": "six-ai-agents-froze-my-production-server-each-one-did-the-right-thing", "title": "Six AI agents froze my production server. Each one did the right thing", "summary": "A developer running Claude Code on a 10 GB production server found that six parallel agents, each correctly installing dependencies, type-checking and building the project, exhausted memory and hung the machine for 17 minutes with no out-of-memory kills in the journal. The kernel thrashed on swap instead of killing processes, and the server hung again three weeks later when a nightly dependency-update job built a Docker image alongside live services. The developer now caps concurrency at (total RAM − in-use − 1 GB reserve) / peak job memory — two jobs in this case — and runs earlyoom with `-s 100` so it acts on low RAM alone, preferring builds and browsers while avoiding postgres and Docker.", "body_md": "*This article was created with the help of AI. The incident, the logs and the numbers are from my own server.*\n\nOn September 25 at 19:01 UTC my server stopped responding. The site, the admin panel and the publishing queue all froze at once. Seventeen minutes later I hard-rebooted it.\n\nThere was no attack and no traffic spike. I had given Claude Code a list of six tasks, and it started six agents in parallel. Each one dutifully installed dependencies, ran the type checker and the tests, and built the project. On the same machine that serves the site.\n\nTake round numbers close to mine. The server has 10 GB of RAM, and the live services use about 3. That leaves 7.\n\nOne typecheck or build of a project this size takes 1.5 to 3 GB. Six at once need 9 to 18. That doesn't fit into 7 however you slice it.\n\nAnyone could have added this up. Nobody did, not me and not the model.\n\nI expected Linux to kill the hungriest process and let the rest carry on. It didn't. The journal has no out-of-memory kills at all.\n\nWhat it does have: system services reporting they were running \"under memory pressure\", and Docker saying it could not send a kill signal to a container process. Then nothing until the reboot.\n\nSwap did it. When RAM runs out, the kernel starts moving pages to disk and back, and that eats all the CPU time. On paper there is still memory, so the kernel sees no reason to kill anything. In practice the machine is busy only with itself. The server didn't crash, it hung, and that's worse. A crashed service restarts on its own. A hung one waits for a human.\n\nFor agents, parallelism is a feature. Six independent tasks go to six workers, each with its own copy of the code in a separate git worktree, nobody in anyone's way. In the code, that held.\n\nWhere they got in each other's way was memory, and nobody had told them about it. A model doesn't know how much RAM the machine has or that a live site runs next to it, unless it checks or someone tells it. And \"finish the job and make sure it builds\" is usually a good habit. Run six times over on a small server, that habit took the server down.\n\nTake total memory, subtract what's already in use, keep a gigabyte in reserve, and divide by the peak of one job. With my round numbers that's (10 - 3 - 1) / 3, so two jobs.\n\nYou don't have to guess the peak. Measure it:\n\n```\nfree -h\n/usr/bin/time -v npm run build 2>&1 | grep 'Maximum resident'\n```\n\nThe first command shows how much memory is free right now. The second runs the build and prints the peak of its largest process, in kilobytes. A build that forks parallel workers uses more than that in total, so round up.\n\nTwo safeguards for when the math lets you down. First, don't build on the production server at all if you have a separate machine or CI. Second, install something like earlyoom, which kills the hungriest process early instead of waiting for the system to drown in swap.\n\nI put in the second one late, and I shouldn't have. Three weeks later the server hung again, this time with no agents involved: a nightly job that checks for dependency updates built a Docker image and started a second copy of a service next to the live ones. Same arithmetic, only nobody was around to do it.\n\nThis is what `/etc/default/earlyoom` looks like on my box now:\n\n```\nEARLYOOM_ARGS=\"-m 5 -s 100 --prefer ^(chrome|chromium|tsc|next-server)$ --avoid ^(postgres|dockerd|containerd|containerd-shim|systemd|sshd|journald)$\"\n```\n\n`-s 100` is the part that matters here. By default earlyoom acts only when both RAM and swap are nearly gone, and my server was already thrashing while swap was still free. With `-s 100` it acts on low RAM alone. Builds and the browser go first, and the database and Docker are never touched.\n\nEach of the six agents did the right thing. The only thing wrong was how many there were.\n\nI collect findings like this about Claude and AI on [Promtime](https://promtime.net/c/en), the news site this server runs.", "url": "https://wpnews.pro/news/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing", "canonical_source": "https://dev.to/alex_iolan/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing-4bo6", "published_at": "2026-10-29 14:07:34+00:00", "updated_at": "2026-10-29 14:18:08.519389+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "mlops", "ai-infrastructure"], "entities": ["Claude Code", "Docker", "earlyoom", "Promtime"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing", "markdown": "https://wpnews.pro/news/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing.md", "text": "https://wpnews.pro/news/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing.txt", "jsonld": "https://wpnews.pro/news/six-ai-agents-froze-my-production-server-each-one-did-the-right-thing.jsonld"}}