SSD Nodes Learn 🎉 VPS from $4.99/mo
Guides Matt ConnorBy Matt Connor

How much RAM does a coding agent VPS need?

One always-on coding agent runs on 4 GB and 2 vCPU. The builds and language servers it launches are what fill the box, and what makes it hang.

How much RAM does a coding agent VPS need?

Start at 4 GB of RAM and 2 vCPU for one always-on coding agent working in a repository. Move to 8 GB and 4 vCPU as soon as a language server or a Docker build joins the session, which for most repositories happens on day one. The agent process itself is small, so what fills the box is the toolchain the agent drives on your behalf.

ChartThree working VPS configurations for a cloud-model coding agent
The data behind this chart
[
  {
    "plan": "Minimum viable",
    "ram_gb": 4,
    "vcpu": 2,
    "disk_gb": 50
  },
  {
    "plan": "Comfortable",
    "ram_gb": 8,
    "vcpu": 4,
    "disk_gb": 100
  },
  {
    "plan": "Team, 4 sessions",
    "ram_gb": 16,
    "vcpu": 8,
    "disk_gb": 200
  }
]

Every row above assumes the model runs somewhere else, behind an API you call over the network. That assumption decides the whole sizing question, so settle it first.

Are you running the agent, or running the model?

A coding agent that calls a cloud model is a network client with a shell attached. It sends files and a plan to an API, waits for the reply, then edits files and runs commands locally. While it waits it uses almost no CPU. Its own memory is measured in hundreds of megabytes, which is why a modest CPU box is the correct machine.

Running the model yourself is a different product on different hardware. The weights stay in memory for as long as the server is up. A 7 billion parameter model quantised to 4 bits needs roughly 5 GB for the weights alone, before the key/value cache that grows with the length of the context. On CPU only, a shared vCPU produces a few tokens per second, and one agent task can emit thousands of tokens, so work that takes under a minute against an API takes most of an hour locally. If that is what you want, size for VRAM (video memory on the GPU) and read what a VPS with a GPU actually gives you instead of this page.

Everything below assumes the cloud-model case.

What actually uses the memory

ChartTypical resident memory per process on a mid-size repository (MB)
The data behind this chart
[
  {
    "label": "Agent CLI process, idle",
    "typical_mb": 250,
    "peak_mb": 600
  },
  {
    "label": "TypeScript language server",
    "typical_mb": 700,
    "peak_mb": 2000
  },
  {
    "label": "rust-analyzer, large workspace",
    "typical_mb": 1200,
    "peak_mb": 4000
  },
  {
    "label": "Headless Chrome, one tab",
    "typical_mb": 350,
    "peak_mb": 900
  },
  {
    "label": "Node test run, 4 workers",
    "typical_mb": 1600,
    "peak_mb": 3000
  },
  {
    "label": "Docker image build",
    "typical_mb": 800,
    "peak_mb": 2500
  }
]

Those are typical published figures for mid-size projects. Treat them as a shape, not as a promise about your code.

The chart holds 6 rows and the agent is the cheapest one. It sits near 250 MB when idle, because it is holding a conversation and a small file cache and nothing else. A TypeScript language server reaches about 2000 MB while it indexes, because it builds a type graph for every file reachable from your tsconfig.json and then keeps that graph in memory to answer the next request quickly. rust-analyzer on a large workspace commonly passes 4000 MB for the same reason, across every crate in the workspace.

Headless Chrome costs about 350 MB for the browser plus one tab, and every extra tab is another operating system process. A Node test run with four workers is four Node processes, so it peaks near 3000 MB. A Docker image build peaks near 2500 MB, because the build runs your project's own compiler inside the container while the daemon writes layers.

Measure these on your own repository before you buy
sudo apt update && sudo apt install -y time
/usr/bin/time -v -o /tmp/build.rusage npm run build
grep "Maximum resident set size" /tmp/build.rusage

The answer comes back as Maximum resident set size (kbytes): 1842160. Divide by 1024 for MB. GNU time reports the largest single process it waited on, so a build that forks four workers reads low. For those, watch the whole box from a second shell with free -h or systemd-cgtop -m.

Read the available column of free -h, not the free column. Linux spends every spare page on disk cache, so free is small on a perfectly healthy box and tells you nothing. available is what a new process can actually get.

Three configurations that work

Minimum viable: 4 GB RAM, 2 vCPU, 50 GB disk. One agent session, one repository, one language server, and builds you are willing to wait for. This tier works, and it will meet the out-of-memory killer the first time a large test run overlaps with an indexing language server. Add swap and cap your build workers.

Comfortable: 8 GB RAM, 4 vCPU, 100 GB disk. One agent, plus Docker, plus a headless browser for tests, with headroom for one build spike. This is the tier most single developers should buy. Doubling the vCPU count also roughly halves the build wait, and you feel that far more often than you feel memory.

Team: 16 GB RAM, 8 vCPU, 200 GB disk. Four concurrent sessions, each with its own checkout and its own toolchain. Size for the peak, because four idle agents cost almost nothing while four test runs at the same moment cost four times the peak column above.

As of August 2026, the step from the first row to the last is roughly four times the monthly price on annual VPS billing: single digit dollars a month at the bottom, tens of dollars at the top. Check the current listing before you plan, because those numbers move. The server is rarely the expensive part. For anyone driving an agent daily, the model API bill passes the server bill quickly, so cap what the agent is allowed to spend before you shrink the box. For the build itself, the walkthrough for running a coding agent on a VPS covers the account setup and keeping the session alive after you disconnect.

Why you run out of disk before you run out of RAM

ChartWhere the disk goes on a working agent box (GB)
The data behind this chart
[
  {
    "label": "Ubuntu 24.04 base and toolchain",
    "typical_gb": 6
  },
  {
    "label": "One JS monorepo checkout",
    "typical_gb": 3
  },
  {
    "label": "node_modules across 3 branches",
    "typical_gb": 4
  },
  {
    "label": "Docker images and build cache",
    "typical_gb": 20
  },
  {
    "label": "Agent logs and journal, 90 days",
    "typical_gb": 2
  }
]

Add those rows up and a 50 GB disk is nearly full before you have written a line of code. The largest single item is Docker at around 20 GB, because BuildKit keeps every intermediate layer of every build until you tell it to stop.

docker system df
docker builder prune --filter until=168h

docker system df prints reclaimable space per category, so run it before and after. The until=168h filter drops build cache older than a week and keeps this week's, which is the cache that still saves you time. docker image prune -a goes further and removes every image no container is using, so expect the next build to pull again.

Node projects fail in a stranger way. npm install writes hundreds of thousands of tiny files, so the filesystem can run out of inodes while df -h still reports free gigabytes. The write then fails with No space left on device on a disk that looks half empty.

df -h /
df -i /

If IUse% reads 100, delete the node_modules directories of branches you are no longer on, or switch to pnpm, which stores each package version once and hard-links it into every project.

Logs are the quiet one. An always-on agent writes session transcripts, and the systemd journal grows to a share of the disk by default.

sudo journalctl --disk-usage
sudo journalctl --vacuum-size=200M
du -xh --max-depth=1 / 2>/dev/null | sort -h | tail

Set SystemMaxUse=200M in /etc/systemd/journald.conf and run sudo systemctl restart systemd-journald to make that ceiling permanent, because a one-off vacuum only buys back today's space.

Swap: what it buys, and what it hides

Swap is worth adding, because it turns a small overshoot into slow work instead of a dead process. Size it at half of RAM, up to about 4 GB. There is little reason to go further on a build box.

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
swapon --show

swapon --show should now list /swapfile at the size you asked for. Without the /etc/fstab line the swap is gone after the next reboot and the box quietly returns to its old behaviour. If fallocate answers Operation not supported, build the file with sudo dd if=/dev/zero of=/swapfile bs=1M count=4096 and carry on from chmod.

echo 'vm.swappiness = 10' | sudo tee /etc/sysctl.d/99-swappiness.conf
sudo sysctl --system

A low swappiness tells the kernel to reclaim disk cache before it pushes program memory out to disk, which keeps a language server responsive.

Now the part swap hides. When a job genuinely needs more memory than the box has, the kernel spends its time moving pages between RAM and disk instead of running your build. Nothing crashes. Everything crawls, and load average climbs while the CPU sits idle.

vmstat 1 10

Steady non-zero numbers in the si and so columns mean continuous swapping, so the fix is less concurrency or more RAM, and never more swap. On a small box sudo apt install -y zram-tools gives compressed swap held in RAM, tuned in /etc/default/zramswap. It is much faster than a swap file, and it spends RAM to save RAM, so it helps with cold pages and not with a build that needs real working memory.

Why your coding agent looks like it hangs

This is the most misdiagnosed failure on a small agent box. A command returns nothing, the agent waits, and the session looks frozen. The process was killed by the kernel out-of-memory (OOM) killer. It received SIGKILL, so it could not print an error, flush a log, or tell the agent what happened. The agent sees an empty result and no exit message.

The kernel does record it:

sudo dmesg -T | grep -iE "out of memory|killed process"
sudo journalctl -k -b | grep -i oom

A real line looks like this:

[Thu Aug  6 11:02:14 2026] Out of memory: Killed process 4711 (node) total-vm:4210880kB, anon-rss:3820104kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:8236kB oom_score_adj:0

anon-rss is how much that process held when it died. Note which process was chosen: the kernel scores mostly by memory in use, so it often kills the language server or the agent rather than the build that pushed the box over the edge. That is exactly why the symptom reads as "the agent broke".

Inside Docker the same event leaves a cleaner fingerprint. The container exits with code 137, which is 128 plus signal 9.

docker ps -a
docker inspect "$(docker ps -lq)" | grep -i oomkilled

"OOMKilled": true confirms the container hit its memory limit rather than crashing on its own.

The cure is to give the expensive command its own ceiling, so the build dies instead of the agent:

systemd-run --user --scope -p MemoryMax=4G -- npm run build

The build is now killed at 4 GB and the agent survives, which turns a mystery hang into an ordinary failed command with a readable exit code. This needs a systemd user session, so run loginctl enable-linger $USER on a box you only reach over SSH. MemoryHigh= throttles the process at the threshold instead of killing it, which is often the kinder setting for a build you would rather have finish slowly.

Cap it once with Compose memory limits

If the agent's tools run in containers, put the ceiling in the Compose file so it applies on every run.

services:
  agent:
    image: node:22-bookworm
    deploy:
      resources:
        limits:
          memory: 2g
          cpus: "1.5"

Docker Compose v2 applies deploy.resources.limits on a plain docker compose up, so swarm mode is not involved. The older mem_limit: 2g key still works. The full guide to Compose memory limits covers reservations and what happens when a container reaches its ceiling. If Docker is not on the server yet, install Docker on a VPS first.

One trap costs people an afternoon. A container limited to 2 GB still reads the host's /proc/meminfo and the host's CPU count, because neither is namespaced. A test runner that picks its worker count from the CPU count will start eight workers inside a 2 GB container on an eight vCPU host, and then die at 137. Set the numbers by hand:

npx jest --maxWorkers=2
export NODE_OPTIONS=--max-old-space-size=1536

--max-old-space-size is in MB and caps the V8 heap. Set it below the container limit so Node throws an error you can read instead of vanishing:

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

That message is a gift, because it names the limit that was hit and the process that hit it. The OOM killer never does.

Running several agent sessions on one box

Plan per session, not per person. Two sessions on the same repository still means two language servers, two sets of build caches in memory, and two test runs if both agents get busy at the same moment. That is why the team row jumps to 16 GB.

Give each user a hard ceiling so one runaway session cannot take the whole box down:

id -u alice
sudo mkdir -p /etc/systemd/system/user-1001.slice.d
printf '[Slice]\nMemoryMax=6G\n' | sudo tee /etc/systemd/system/user-1001.slice.d/limit.conf
sudo systemctl daemon-reload
systemctl show user-1001.slice -p MemoryMax

Replace 1001 with the UID that id -u printed. systemctl show should echo MemoryMax=6442450944 once the user has logged in. When everything in that user's session passes 6 GB, the kernel kills a process inside her slice and every other session keeps working. For an agent that runs as a service rather than in a terminal, put MemoryMax= in its unit file instead, which is the pattern to follow when you self-host an agent as an always-on service.

FAQ

Is 2 GB of RAM enough for a coding agent?

For the agent process, yes. For the work it does, rarely. The agent sits near 250 MB, but one TypeScript language server can reach 2000 MB on a mid-size repository, and that alone pushes a 2 GB box into swap. 2 GB is fine for editing config files and small scripts. Use 4 GB as the floor for anything that compiles or runs a test suite.

Do I need a GPU to run a coding agent on a VPS?

Not if the agent calls a cloud model over an API. That workload is network-bound, so a plain CPU VPS is the right machine and a GPU sits idle at a much higher price. You need a GPU only when the model itself runs on the same box, and then the question changes from RAM to VRAM and model size.

How much swap should I add to an agent VPS?

Half of RAM, up to about 4 GB. Swap protects you from a short overshoot, because the kernel can move cold pages to disk instead of killing a process. It does not add usable memory. If vmstat 1 shows steady traffic in the si and so columns, the box is thrashing, and the answer is fewer parallel workers or a bigger plan.

Why does my coding agent freeze in the middle of a build?

The build was almost certainly killed by the kernel OOM killer, which sends SIGKILL, so nothing is printed and the agent waits on a pipe that never fills. Run sudo dmesg -T | grep -i "killed process" and look at the process name and its anon-rss value. Fix it by capping the build with systemd-run --user --scope -p MemoryMax=4G and lowering the worker count, or by moving up one RAM tier.

#sizing#coding-agents#ram#vps-specs#always-on