Pick the tool
Four tools do the job. For an agent you talk to, take tmux. For a script or a bot that nobody types into, take systemd.
| nohup | screen | tmux | systemd service | |
|---|---|---|---|---|
| Survives closed SSH | yes | yes | yes | yes |
| You can come back and type | no, only read a log | yes | yes | no, only read the log |
| Survives a reboot | no | no | no | yes |
| Restarts after a crash | no | no | no | yes, with Restart= |
| Good for | A quick script | A habit from older servers | Claude Code, Codex, any interactive agent | A bot, a worker, a headless agent run |
Already use screen? The same idea, other keys: start with screen -S agent, detach with Ctrl+A then D, list with screen -ls, come back with screen -r agent. For a script with no keyboard, nohup ./agent.sh > agent.log 2>&1 & keeps it alive after SSH closes.
Steps
-
Install tmux
On Ubuntu and Debian it is one package. Do this on the server, over SSH.
$ sudo apt install -y tmux -
Start a named session and run the agent in it
The name lets you find the session later. Start your agent as usual inside it.
$ tmux new -s agent $ cd your-project $ claude # or codex, or your own script
-
Detach and close the laptop
Press
Ctrl+B, thenD. tmux prints the session name and returns you to the shell. The agent keeps working. Close SSH and the laptop. -
Come back and attach
List the sessions if you forgot the name, then attach. You see the agent as it is now, with everything it did while you were away.
$ ssh [email protected] $ tmux ls $ tmux attach -t agent
-
For a job that must outlive a reboot: write a service
tmux dies with the server. A systemd service starts at boot and restarts the program when it crashes. Put it in
/etc/systemd/system/agent.service, with the path to your program and your own user.[Unit] Description=My agent After=network-online.target [Service] User=dev WorkingDirectory=/home/dev/your-project EnvironmentFile=/home/dev/your-project/.env ExecStart=/usr/bin/node agent.js Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
Restart=on-failurerestarts the program when it exits with an error.Restart=alwaysrestarts it in every case, even after a clean exit. Then switch it on and watch the log:$ sudo systemctl daemon-reload $ sudo systemctl enable --now agent $ systemctl status agent $ journalctl -u agent -f
-
Stop the connection from dropping while you are there
A quiet SSH window can be cut by a router. Ask your laptop to send a keep-alive every minute. Add this to
~/.ssh/configon the laptop.Host * ServerAliveInterval 60
Check that it works
Run a command that leaves a trace, detach, close the SSH window and open a new one. If the trace keeps growing, the setup works.
$ tmux new -s test $ while true; do date >> ~/alive.log; sleep 5; done # Ctrl+B, then D. Close SSH. Connect again: $ tail -3 ~/alive.log $ tmux kill-session -t test
For the service, run sudo reboot, wait a minute and run systemctl status agent. It should say active (running).
The short way: a computer that does not need tmux
On Uno you skip steps 1–6. Give the agent the task in a chat in Uno Work and close the laptop. On Uno, the agent keeps working when the laptop is closed, and a long job or an agent working overnight keeps it awake. With nothing to do for 10 minutes the computer falls asleep with memory and running programs saved, and the first request wakes it.
Small: $5 a month
What tmux does not do
- It does not survive a reboot of the server. A kernel update or a provider restart ends the session; a systemd service comes back by itself.
- It does not restart a crashed agent. It only keeps the window open, with the error on screen.
- It does not look after the server. A plain server stays on, and updates, disk space and restarts stay yours to handle.
An agent that works alone needs a clean address
Your computer runs in the Netherlands. Its traffic can leave through a static address of a regular internet provider in one of 8 countries. Only your account works from that address.
- From a data-center address
- Sites see a server range shared with thousands of strangers. The agent's browser hits more captchas and blocks.
- From your Clean exit IP
- Sites see a regular internet provider's address in the country you picked. Fewer captchas, and less reason for Claude or ChatGPT to flag your account: nobody else works from it.
Pick the size of the computer your agent lives on
Every plan sleeps when idle and wakes on the first request. Plus has 4 GB and Uno Work in the cloud; move up any time.
Small
A Telegram bot, a VPN, a small backend
$5/ month
- 1 vCPU · 1 GB
- 15 GB disk
- 25 GB cloud storage
- 5 boosts a month
Plus
Agents that work with your laptop closed
$20/ month
- 4 vCPU · 4 GB
- 40 GB disk
- 100 GB cloud storage
- Uno Work in the cloud
Pro
A product in production, a second MacBook
$70/ month
- 16 vCPU · 16 GB
- 120 GB disk
- 300 GB cloud storage
- Speed of a MacBook Air M4
Max
A team and many agents at once
$200/ month
- 32 vCPU · 48 GB
- 300 GB disk
- 1,024 GB cloud storage
- 5 public IPv4
Add Uno AI to any plan: 40 h of AI work a month on Small, 100 h on Plus, unlimited on Max. Today: GLM-5.3 Flash and MiMo v2.6 Pro. Or sign in with your own Claude or ChatGPT.
Common problems
The agent stops when I close SSH
tmux new -s agent first and start the agent inside it. A command typed into a plain SSH window ends with the window."no server running on /tmp/tmux-…" or "can't find session"
I do not know what an old session is called
tmux ls lists them. Attach to one with tmux attach -t NAME, or end it with tmux kill-session -t NAME.My service stops when I log out
systemctl --user. Switch on lingering so the user manager stays after logout: sudo loginctl enable-linger dev. Or put the unit in /etc/systemd/system as above.The service starts and exits at once
journalctl -u agent -n 50. The usual causes are a wrong path in ExecStart=, a missing .env file, or a program that waits for a terminal. Interactive agents such as Claude Code belong in tmux, not in a service.