Back to blog
InfraOctober 30, 20255 min read

Why Your Vite Build Keeps Dying on a $6 VPS

Out of memory kills are silent and confusing. Here is how to diagnose them and the swap setup that actually helps.

You push your code, run npm run build, and the process just... stops. No error, no stack trace. Just exits with a non-zero code and nothing useful in the logs. If you are on a cheap VPS with 1GB or 2GB of RAM, there is a good chance the Linux OOM killer just silently executed your build process.

The OOM killer does not write to stdout. It writes to kernel logs. Check them:

bash
dmesg | grep -i "out of memory"
dmesg | grep -i "killed process"

If you see something like "Out of memory: Kill process 12345 (node) score 900 or sacrifice child", that is your answer. Node ate all the available memory during the build and the kernel killed it.

Vite builds with esbuild are generally pretty lean, but as your project grows and you add more dependencies, the memory usage during bundling can spike hard. A medium-sized React app with a bunch of npm dependencies can easily hit 800MB during build.

Adding swap

The permanent fix is adding a swapfile. This is not a performance boost, it just prevents the OOM killer from terminating your build. The build will be slower if it hits swap, but it will finish.

bash
# Create a 4GB swapfile
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Make it permanent
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Reduce swappiness so the kernel prefers RAM
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

The swappiness setting tells the kernel how aggressively to move memory pages to swap. Default is 60, which is too eager for a build server. Setting it to 10 means the kernel will only use swap when RAM is genuinely running out.

Limiting Node memory

You can also cap Node's memory usage explicitly during the build:

bash
NODE_OPTIONS="--max-old-space-size=1536" npm run build

This tells Node to use at most 1.5GB of heap. It will trigger garbage collection more aggressively and the build might be slower, but it makes memory usage more predictable.

Is it always memory?

Not always. A few other things cause silent build failures. Check that you have enough disk space with df -h because a full disk can cause the build to fail without a clear error. Also check if PM2 or another process is fighting for resources during the build. We started scheduling builds during low-traffic hours and that alone reduced failures significantly.

On a 2GB VPS with 4GB swap and swappiness at 10, our full Vite builds with TypeScript, React, and Tailwind run clean every time. Takes about 90 seconds but never crashes.

More articles