
One Claude Code session runs fine on your VPS, so you add a second for the tests, a Codex session for the docs and an OpenClaw agent for your chats. Then a build crawls, a session stops without an error, or two agents change the same file. No spec table tells you whether one server can carry them, because most of the load comes from what the agents start. This guide shows how to measure each agent while it works, keep them out of each other's way, and spot the limits that sit with your AI provider. Commands are for Ubuntu 24.04 and Debian 12.
Quick answer: Give every agent its own Linux user, SSH login, tmux session and git checkout, then run a real task on all of them at once. While they work, systemd-cgtop -m user.slice shows memory and CPU per agent; afterwards each user's memory.peak holds its highest memory use and cpu.pressure shows how long its tasks waited. Keep the peaks together under about three quarters of the RAM and check every worktree with du. Plan and API limits are shared by every agent on them, and a second VPS doesn't raise them. Add a second server when agents need separate trust boundaries, or when pressure stays high after you spread out the heavy jobs.
What Each Extra Agent Adds
| Resource | Why it grows with every agent | Where to read it |
|---|---|---|
| Memory | An agent process each, plus the builds, tests and servers it starts | systemd-cgtop, memory.peak |
| CPU | Builds and test runs that overlap | systemd-cgtop, cpu.pressure |
| Disk | A checkout, dependencies and build output per worktree | du, df |
| AI limits | Every agent draws on the same plan or API key | /usage, /status, your provider's console |
Claude Code runs every background session as "its own Claude Code process under the supervisor" (agent view). OpenClaw can run several agents in one Gateway process (multi-agent routing); there you measure the gateway as a whole. Our GPU guide lists what each tool needs for one agent.
Step 1: Give Every Agent Its Own User, Session and Checkout
Create one Linux user per agent, without sudo or the docker group, as our guide to securing an AI agent on a VPS shows. Then log in as that user over SSH and start the agent in a named tmux session, as in our Claude Code guide:
ssh agent1@your-server
cd ~/app
tmux new -s agent1
tmux keeps a socket directory per user, tmux-UID under /tmp (tmux(1)), so tmux ls lists only that user's sessions.
Why SSH and not sudo -iu agent1? A login started by sshd becomes a scope unit "collected under the user-UID.slice" (user@.service(5)), which is how the measurements below tell agents apart. A sudo shell inside your login stays in your session: systemd-logind creates no session for a process "Already running in a session or user slice" (logind source), and a child "is born into the cgroup that the forking process belongs to" (cgroup v2). That agent's usage would count under your user.
One Checkout per Agent
Agents that share one working directory edit the same files and git index; when two git commands overlap, the second stops because "Another git process seems to be running in this repository" (lockfile.c).
- Agents under different users: give each user its own clone and exchange work through branches on your git remote. By default, Git "will refuse to even parse a Git config of a repository owned by someone else" (git-config).
- Several sessions under one user: one worktree each. A worktree shares "everything except per-worktree files such as HEAD, index, etc.", and by default
git worktree addrefuses a branch that another worktree has checked out.
git worktree add ../app-docs -b docs
git worktree list
git worktree remove ../app-docs
remove only takes clean worktrees, without untracked or modified files. Agents can create worktrees too: claude --worktree docs starts Claude Code in .claude/worktrees/docs/ on a new branch worktree-docs (worktree docs), and in a git repository background sessions move into their own worktree before they edit. Codex CLI has /worktree in a chat and codex exec --worktree for runs (CLI reference). A worktree starts without gitignored files such as .env; Claude Code copies the ones that match a .worktreeinclude file into the worktrees it creates.
Step 2: Measure Memory per Agent While They Work
Give every agent a real task that installs dependencies, builds and runs the tests, and start them a few minutes apart so you can see what each adds. Then watch:
systemd-cgtop -m user.slice
systemd-cgtop lists each user's slice with its tasks, CPU and memory, refreshed every second and ordered by memory. Memory and CPU accounting are on by default on both systems (systemd-system.conf(5)); I/O accounting is not, so the I/O columns can stay empty. For one agent's processes, run htop -u agent1 and press F5 for the tree view, or list them by memory, with RSS in kilobytes:
ps -u agent1 -o pid,rss,comm --sort=-rss
When the run is over, read each agent's peak and pressure (use your own user names):
for u in agent1 agent2 agent3; do
d=/sys/fs/cgroup/user.slice/user-$(id -u "$u").slice
echo "$u peak: $(numfmt --to=iec < "$d/memory.peak")"
grep some "$d/memory.pressure" "$d/cpu.pressure"
done
memory.peak is "The max memory usage recorded for the cgroup and its descendants since the creation of the cgroup" (Linux 6.1 docs); the Debian 12 and Ubuntu 24.04 kernels both have it. systemd removes a user's slice when that user's last session ends (pam_systemd(8)), so read it while the agent's tmux session still runs. These paths assume cgroup v2, which you have if /sys/fs/cgroup/cgroup.controllers exists.
The peak counts page cache as well as the memory the processes allocate. While the agents are busy, memory.stat in the same folder splits the current total into anon, the processes' anonymous memory, and file, "memory used to cache filesystem data":
grep -E '^(anon|file) ' /sys/fs/cgroup/user.slice/user-$(id -u agent1).slice/memory.stat
Three things escape this count:
- Containers. With cgroup v2, Docker's default systemd driver puts each container in
/sys/fs/cgroup/system.slice/docker-<longid>.scope/(runtime metrics), outside the agent's slice. Read them withsudo docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}". - Idle sessions. Claude Code's supervisor stops a background session that is finished or waiting and "unattached for about an hour", and stops idle sessions when memory stays low. A session that fails to start on a host short of memory shows
possibly low memory. Measure with the sessions working. - The rest of the server. Your database, web server and the system come on top;
free -hshows them all. Keep the total under about three quarters of the RAM, as our RAM guide explains with swap and OOM checks.
Step 3: Check CPU and Disk When Heavy Jobs Overlap
CPU
The CPU column in systemd-cgtop runs from 0 to 100% times the number of processors, so 400% on four vCores means all four are busy. Use it or htop for the current load; ps reports %CPU as CPU time divided by the time the process has been running (ps(1)), a lifetime average.
The some line of a slice's cpu.pressure gives "the share of time in which at least some tasks are stalled" waiting for the CPU, over 10, 60 and 300 seconds (PSI). If it climbs only when builds overlap, schedule the heavy jobs apart, or give the least urgent agent a lower weight and a memory cap:
sudo systemctl set-property user-$(id -u agent3).slice CPUWeight=50 MemoryHigh=2500M MemoryMax=3G
CPU time "is split up among all units within one slice relative to their CPU time weight", and the kernel default is 100 (systemd.resource-control(5)). Above MemoryHigh, the agent's processes are slowed down and memory is taken back; if usage can't stay under MemoryMax, the OOM killer acts inside that slice. Base both on the peak you measured. systemctl applies the change at once and stores it on disk; for a user who isn't logged in, it takes effect when the slice starts again.
On a Space-Node VPS the RAM is dedicated and the vCores are shared; if agents slow down while your own CPU use is low, check steal time as our shared vCPU guide shows.
Disk
df -h /
df -i /
du -sh ~/app ~/app-docs
Every worktree holds its own checkout, dependencies and build output; the ones Claude Code creates sit inside the repository, so they count toward ~/app. Give all folders to one du command: "If two or more hard links point to the same file, only one of the hard links is counted", and the order of the folders decides which one gets it (GNU du). That matters with pnpm, which installs packages as hard links or copy-on-write clones from one store, "consuming no additional disk space" (pnpm). df -i shows inodes, which thousands of small dependency files use up. For Docker images, containers and volumes, run sudo docker system df.
Step 4: Check the Limits on the AI Side
Anthropic's page on parallel agents warns that "Running several sessions or subagents at once multiplies token usage." The limits on that usage belong to your account, not to the server:
- Claude plans: background sessions use your subscription "the same as interactive sessions, so running ten agents in parallel uses quota roughly ten times as fast as running one" (agent view). A large fanout "can exhaust the weekly allowance before the session window resets" (error reference).
/usageshows your limits and when they reset. Pro, Max and Ultra limits "assume ordinary, individual usage" (legal and compliance). - Codex on a ChatGPT plan: local messages and cloud chats "share your plan's usage allowance", weekly limits may also apply, and
/statusshows what remains during a CLI session (pricing). - API keys: Anthropic sets rate limits "at the organization level", in requests, input tokens and output tokens per minute, and answers a breach with a 429 error (rate limits). Claude Code then shows
API Error: Request rejected (429), and Anthropic's advice includes reducing concurrency. OpenAI's limits apply "at the organization level and at the project level, not user level" (rate limits).
To keep one agent from starving the others, give it its own Anthropic workspace with lower rate and spend limits, or its own OpenAI project with a spend limit. Anthropic adds that "Organization-wide limits always apply, even if Workspace limits add up to more." OpenClaw runs inbound turns in a main lane capped by agents.defaults.maxConcurrent, and its queue docs say serializing "reduces the chance of upstream rate limits".
Which One Fits
- One VPS as it is: the summed peaks stay under about three quarters of the RAM, pressure stays low when builds overlap, and the disk has room for every worktree.
- A bigger plan: memory or CPU runs short only when the agents overlap, and they all belong to you. On Space-Node you move to a bigger plan from the client area; our AI agent VPS page lists the sizes.
- A second VPS: the agents belong to different people or trust levels, one needs root or the docker group, or one agent's builds slow the rest even after weights and scheduling. OpenClaw's trust model prefers "one OS user/host/VPS per boundary", and our several-apps guide compares one server with several.
- Neither: the limit is your plan or API key. Spread the work over time or raise the limit with your provider; another server doesn't change it.
FAQ
How many AI agents can one VPS run?
There is no fixed number: the load comes from what the agents start. Run them together on a real task, read each user's memory.peak, and keep the total, with the rest of the server, under about three quarters of the RAM.
Do agents on one VPS share my usage limits? Yes. Every session signed in to the same Claude or ChatGPT plan draws from the same allowance, and every agent on the same API organization shares its rate limits, wherever the agents run.
Can two agents work in the same git repository? Yes, if each has its own checkout: a clone per Linux user, or a worktree per session under one user. Two agents in one working directory edit the same files and collide on git's lock file.
Why is memory.peak higher than what htop showed?
It holds the highest point since the slice was created, not the current use, and it counts page cache as well as process memory. Compare the anon and file lines in memory.stat while the agents work.
Should every agent have its own Linux user? Yes, to measure and cap them one by one, and for safety: one hijacked agent can't read another agent's files. Sessions of one agent, such as Claude Code background sessions, can share a user with a worktree each.
Sources
All opened on 31 October 2026:
- Anthropic, Claude Code docs: Agent view, Worktrees, Run agents in parallel, Error reference and Legal and compliance
- Anthropic, Claude API: Rate limits
- OpenAI: Rate limits, Codex pricing and usage limits and CLI reference
- OpenClaw docs: Multi-agent routing, Command queue and Security trust model
- Git: git-worktree, git-config (safe.directory), lockfile.c in v2.39.0 and v2.43.0
- systemd: systemd-cgtop(1), user@.service(5), pam_systemd(8), systemctl(1), systemd.resource-control(5), systemd-system.conf(5) for Ubuntu 24.04 and Debian 12, logind-dbus.c in v252 and v255
- Linux kernel: Control Group v2, Control Group v2 for Linux 6.1, Pressure stall information
- Tools: ssh(1), tmux(1), ps(1), htop(1) for Ubuntu 24.04 and Debian 12, id(1), numfmt(1), grep(1), df(1), du(1) and the GNU coreutils manual source
- Docker: docker stats, Runtime metrics and docker system df
- pnpm: Motivation
Claude and Claude Code are made by Anthropic, and Codex by OpenAI. Space-Node is not affiliated with or endorsed by Anthropic, OpenAI or the makers of the other tools named in this guide.