[KongchangAI]
· 4 min read· 2,178 words

Keep Claude Code Running After You Close the Terminal: tmux and SSH Solutions

Keep Claude Code Running After You Close the Terminal: tmux and SSH Solutions

Use tmux, remote servers, and CLI resume flags to keep Agents running after terminals close, sleep, or crash.

The article explains how to keep AI coding Agents like Claude Code running when terminals close, SSH drops, laptops sleep, or apps restart. It offers three layers: use tmux with named sessions to decouple processes from windows, deploy Agents to always-on remote machines via `ssh -t ... tmux`, and recover conversations with `claude --resume` or `codex resume` when processes die. It also covers Hermes IDE's equivalent capability and a selection table for choosing the right approach.

Close the terminal tab to tidy up your screen, and Claude Code's ongoing thirty-file module rename task is interrupted right there. Twenty minutes of progress, gone in an instant. SSH connections dropping when the subway enters a tunnel, terminal apps auto-updating and restarting—scenarios like these happen every day.

Conversation history usually survives, but a running process does not. An ordinary claude or codex session lives inside the terminal that launched it—the window is the Agent's life support system.

The solution stacks three layers: let the process live independently of the window, put it on a machine that never sleeps, and if it still dies, use the CLI's built-in flags to resume the conversation.

tmux: Giving the Agent a Home That Doesn't Belong to the Window

tmux runs the shell inside a server process that outlives the terminal. The official manual states it plainly: each session "is persistent, and will survive accidental disconnection." Detach, and the Agent keeps running; attach, and you're back where you left off.

Start a named session and launch Claude Code inside it:

tmux uses a client-server architecture: the first time you run tmux, a tmux server process starts in the background, hosting all sessions, windows, and panes. What you see in the terminal is just a client, connected to the server via a Unix socket. This means the disappearance of the client (closing the tab, quitting the terminal app, SSH dropping) only affects the display—it doesn't affect processes running inside the server. The detach triggered by Ctrl-b d is exactly actively disconnecting the client while keeping the server alive. This also explains why tmux sessions are shared under the same user—attaching from any terminal gives you the same state. The server itself is still an ordinary user process, so it pauses when the machine sleeps and disappears on reboot—that's the boundary of its capability.

The -A in tmux new -A -s name is equivalent to "if the target session already exists, switch to attach-session instead of new-session." Without it, repeated execution errors out on a name conflict; with it, the same command carries both "create" and "reconnect" semantics, making it perfect for a shell alias or history entry you call repeatedly. Combined with the -s naming, switching between multiple sessions requires no PID memorization and no tmux ls lookup before connecting.

# Create a session, or attach if it already exists
tmux new -A -s auth-refactor

# Inside tmux: give the Claude session a name too
claude -n auth-refactor

Press Ctrl-b then d to detach. Close the terminal freely. From any new terminal:

tmux ls                       # List sessions
tmux attach -t auth-refactor  # Return to where you left off

The -A flag is worth remembering. It makes new-session "equivalent to attach-session when the session name already exists," so the same command creates the session the first time and reconnects every time after. Put it in your shell history, and you never have to think about which command to use.

Terminal window closes while the process keeps running inside its protective shell

tmux has one limitation: when the laptop sleeps, it pauses too, and the process only resumes when the machine wakes. That handles closed tabs or terminal app crashes, but it doesn't handle a refactor that needs to keep progressing when you close the lid.

Claude Code now has its own solution. claude --bg "finish the auth refactor" starts a background session and returns immediately, printing a session ID. A separate supervisor process runs it, and per the docs you can "close your shell" while the work continues. Sessions survive sleep, but "shutting down or rebooting the machine will stop running background sessions." Use claude attach <id> to reconnect, claude logs <id> to inspect, and claude agents to list them all. The same page notes two caveats: the agent view is currently a research preview; and sessions that are finished or waiting for your input with no attached process will auto-stop after about an hour, though the conversation stays on disk and resumes the next time you attach or reply.

Put the Agent on a Machine That Never Sleeps

If the task must continue while the laptop lid is closed, the process must live on an always-on machine: a cloud VM, a home server, a workstation under the desk. Install tmux there, and SSH becomes a window you can open and close at will.

ssh -t dev.example.com tmux new -A -s auth-refactor

-t is required because tmux needs a terminal. The SSH manual describes it as "force pseudo-terminal allocation," used for running "screen-based programs" on a remote machine. Run this line, launch claude -n auth-refactor inside, and close the laptop. When the subway tunnel drops your connection, run the exact same command again. -A puts you back into the running session.

Closed laptop connected to a server still running, amber light on

Remember what follows the Agent. The repo, .env files, toolchain, and the Agent's own login state must all exist on the remote machine, because that's where the Agent reads and runs things. Until you push, commits land on that machine's checkout.

The -t in ssh -t means force pseudo-terminal (pty) allocation. By default, SSH only requests a pty when the local side is already a terminal; once you pass a command as an argument to ssh (e.g., ssh host tmux ...), the remote side runs without a terminal. tmux, as a full-screen interactive program, needs a terminal to initialize, otherwise it errors out with something like open terminal failed: not a terminal. -t forces the remote side to allocate a pty so tmux works properly.

This leads to a more robust pattern: use -t twice (-tt) to guarantee allocation even when the local side has no terminal—for example, when calling from a script or CI. Also mind SSH's ServerAliveInterval and ClientAliveInterval settings—they control heartbeat and timeout disconnect behavior, and the more unstable the connection, the more worth tuning them down. Regardless, these parameters only affect the connection itself; what truly keeps the Agent alive is the remote tmux server, because dropping SSH only closes the client.

The Process Still Died: Resume the Conversation

Sometimes nothing saves the process. The machine rebooted, or you forgot to use tmux. The conversation is still on disk.

According to the Claude Code session docs, it "persists sessions to local transcript files" under ~/.claude/projects/. Two commands can resume them:

claude --continue             # Most recent session in current folder
claude --resume auth-refactor # Session with the given name

This is where the earlier -n naming pays off. Without a name, you'd have to pick from a list. A resumed session brings back the full history, including tool calls and results, along with the model and permission mode. What it cannot restore is the work in progress. Tools that were running when the process died "will not complete or re-run on restore." Claude sees the call marked as interrupted and checks whether it already took effect before deciding to re-run it. Background Bash tasks also don't resume. Expect the first turn after resuming to spend some time inspecting repo state.

Codex does the same thing under different names:

codex resume --last        # Most recent chat in current folder
codex resume <SESSION_ID>  # Specific session
codex resume --last --all  # Search beyond the current folder

Per the Codex command reference, --last skips the picker, and --all includes "sessions outside the current working directory." codex fork opens the same picker and also accepts --last or a session ID, used to copy a conversation to try a different approach.

Treat resume as a safety net for the conversation; the twenty minutes the Agent could have been working while you were away is gone regardless.

Claude Code's session transcripts are persisted in JSONL format under ~/.claude/projects/<encoded-path>/, with every message, tool call, and result appended. The session identifier is typically a UUID or the name you specified via -n, and claude --resume reads these files to rebuild context. On resume, the history the model sees includes user messages, assistant replies, tool calls and returns, plus the model choice and permission mode at the time—so its judgment on the next turn is largely consistent with before the interruption.

But this is "conversation state," not "process state." An interrupted tool call usually carries an interruption marker in the transcript, and the model must judge on its own in the next turn whether that tool already produced side effects—e.g., whether a rename executed, whether a file was written. That's why it's wise to have it check repo state first (git status, git diff) before continuing, rather than letting it re-run blindly. Background Bash tasks don't record stdout streams or process handles in the transcript, so they can't be reattached on resume—you can only re-issue them.

How Hermes IDE Handles It

Hermes IDE is a project I'm working on, so read the following with that in mind. Hermes runs each Agent in its own real terminal and treats app windows the way tmux treats terminals. Per the README, on macOS and Linux "Agents keep working when Hermes quits, updates, or crashes, and you come back to where they left off."

If you enable Agent view for Claude, those sessions also return to the screen with their prior conversation after an app restart, and Claude picks up where it left off.

App window fades out while three small Agents keep working under their amber lights

This behavior is explicitly marked as supported on macOS and Linux in the README. On Windows, fall back to the resume flags above.

For remote work, the full New Session window also offers SSH and tmux session types, and since 2.2.9, dropped or slow SSH connections no longer freeze the window. SSH support has separate documentation that lists what currently works and what doesn't—worth reading before a long task.

The truly robust combination is still the one from the previous section. Open an SSH session in Hermes, run tmux new -A -s auth-refactor on the remote end, and launch the Agent there. When the connection drops, the tmux session on the machine keeps running, and the same command puts you back.

Choosing Based on What Kills the Run

What ends the runWhat keeps it going
You close the tab or the terminal crashestmux, claude --bg, or Hermes on macOS/Linux
Laptop sleeps or goes offlinetmux on a remote machine, via ssh -t
Terminal app or Hermes updates or quitsHermes on macOS/Linux, or tmux
Machine rebootsNothing local can save it—use claude --resume or codex resume

Name every long-running session: tmux new -A -s names the process, claude -n names the conversation. Both cost only a few extra keystrokes, and both are the commands you'll type when things go wrong.

When choosing a strategy, think in two dimensions: where the process is and where the state is. Where the process is determines which interruptions it survives: local terminal < local tmux < remote tmux < remote tmux + persistent disk. Where the state is determines how much you can recover: the conversation transcript on disk restores context, but in-progress tool calls and background tasks are not included. The strongest combination names both ends: tmux new -A -s <name> on the remote side, claude -n <name> for the conversation, and let claude logs/claude attach plus tmux attach form a reproducible workflow.

Also, designing smaller "minimal re-entry units" helps. Break the Agent's task into steps that can be completed and committed independently, using git commits as checkpoints—even if the process dies, it can resume from the most recent commit after recovery without rebuilding the entire in-progress work. This is orthogonal to --resume and tmux, and covers the machine-reboot scenario that nothing can save the process from.

One-line Summary

Use tmux, a remote server, and CLI resume flags to keep Claude Code and other Agents working after the terminal closes, sleeps, or crashes.

Paragraph Summary

The article discusses how running AI coding Agents (like Claude Code) get their processes interrupted and progress reset to zero when the terminal closes, SSH drops, the laptop sleeps, or the app restarts. The author offers a three-layer solution: first, use tmux to place the process in a server independent of the window, naming sessions with tmux new -A -s and attaching anytime; Claude Code itself offers claude --bg background sessions, but a machine reboot still terminates them. Second, put the Agent on a never-sleeping remote machine, using ssh -t ... tmux new -A -s as a switchable window. Third, if the process has already died, use claude --continue/--resume and codex resume to recover conversation history, though in-progress tool calls and background tasks cannot be recovered. The author also introduces the equivalent capability of their own Hermes IDE on macOS/Linux and guides selection with a "what kills the run vs. what keeps it going" table, with the core principle being to name every long-running session.

#Claude Code#tmux#SSH#background agent#session resume#long-running tasks
Share:

Related articles