28 Oct 2026 · Docker & Infra
Preventing next build OOM and SIGKILL on 2GB and 4GB VPS Instances
Why next build dies with SIGKILL on Hetzner CX22 and CX23, how swap and NODE_OPTIONS actually help, and when to stop building on the VPS.
next build is a memory hog. On a 2GB or 4GB VPS it often never finishes. The kernel sends SIGKILL. Docker reports exit 137. There is no TypeScript error. The box ran out of RAM.
AgenticPacks OSS is the Next.js app, Compose, and Postgres: Agentic-Packs/agenticpacks-oss. You can reproduce the OOM there on a small node. The production image, swap, and Hetzner path below are what Pro ships. See the standalone Docker Compose layout for the image itself.
What SIGKILL actually is
Node does not throw. The Linux OOM killer picks the fattest process and sends signal 9. next build compiles the App Router, webpack or Turbopack, and type checking in one process. Peak RSS on a Next.js 15 AI app with Prisma generate is often 1.5GB to 2.5GB. A CX22 with 2GB has nothing left after systemd, Docker, and Postgres.
Typical log:
Killed
ELIFECYCLE Command failed with exit code 137.
Inside Compose, the build container dies the same way if you run next build as a service command on that host.
Do not build in the running web container
The production image should already contain .next/standalone. You build in CI or on a larger builder, then copy the standalone output into a slim runner. That split is in the environment variable guide: ARG at build, secrets at runtime.
If you docker compose build on the 2GB VPS, you still pay the RAM on that box. Swap buys you a finish. It does not make the compile fast.
Add a swapfile before the first production build
On Debian or Ubuntu, as root:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
fallocate is faster than dd on ext4. Check with swapon --show and free -h. Two gigabytes of swap is enough for a Next.js 15 standalone build on 2GB RAM. Four gigabytes of RAM plus 2GB swap is comfortable.
Swap is disk. The build will crawl. That is still better than SIGKILL.
Cap Node, stop typecheck twice
export NODE_OPTIONS="--max-old-space-size=1536"
npx next build
On 2GB, 1536MB leaves room for the kernel. On 4GB, 3072 is fine.
next build already typechecks. Skip a separate tsc --noEmit in the same CI job unless you have a reason. Prisma generate before build, not inside a second Node heap.
Dockerfile builder stage:
ENV NODE_OPTIONS="--max-old-space-size=1536"
RUN npx prisma generate && npm run build
Do not raise the heap above physical RAM plus swap. Node will just OOM later and the killer will still fire.
When swap is the wrong fix
If every deploy builds on the VPS, you will fight this forever. Build the image in GitHub Actions on a hosted runner, push to a registry, and pull on the VPS. The node then only runs node server.js, Postgres, and Caddy. Resident RAM for a standalone Next process is a few hundred megabytes, not 2GB.
Pro does that path with Terraform and Compose on Hetzner. AgenticPacks OSS is the app you can still compose build locally on a laptop that has RAM.
Tired of watching next build die on a 4 euro VPS?
The MIT app and Compose file are on GitHub: Agentic-Packs/agenticpacks-oss.
For a Hetzner box that pulls a prebuilt image and never compiles on 2GB RAM, see the prebuilt image workflow in Pro.
Checklist
| Symptom | Cause | Fix |
|---|---|---|
| Exit 137, no stack | OOM killer | 2GB swap, lower heap, or stop building on the VPS |
| Build hangs then dies | Swap thrash | Build in CI, ship the image |
| Prisma generate plus next build | Two heaps | One RUN in the builder |
| Postgres + build on same 2GB | No headroom | Stop Postgres during build, or do not build here |
For the cost of running the app after it actually boots, see self-hosting architecture and cost.
Where to Go From Here
You do not have to keep compiling Next.js on the same 2GB node that serves production.
Option A: Free open-source baseline (MIT)
- GitHub: github.com/Agentic-Packs/agenticpacks-oss
- What is included: standalone Dockerfile, Compose, PostgreSQL 16, Auth.js v5, single-plan ($19/mo) Stripe checkout with webhooks and a credit counter. No Caddy. Build on a machine that has RAM.
- Cost: free, MIT.
Option B: Ship with AgenticPacks Pro ($149 one-time)
If the VPS should only pull and run:
- Automated Hetzner provisioning:
terraform applyfor the node, firewall, Caddy SSL, and Compose. - Production multi-agent core: LangGraph, pgvector RAG, Redis. Image built off-box.
- Usage & Unit Economics: Stripe subscriptions, webhooks, and a token-to-dollar ledger.
