treeru.com
CLAUDE CODE

Tmux + Claude Code — Keep AI Working Even When SSH Drops

2026-03-29
Treeru

There is one problem you will inevitably hit when running Claude Code on a remote server over SSH. When the network drops, your Claude session dies with it.Close your laptop lid, lose Wi-Fi for a second, or accidentally close the Windows Terminal window — and everything you had in progress is gone. Re-launching resets the context from scratch. Adding tmux in between solves this entirely. The session lives on the server independent of the SSH connection, and when you reconnect you pick up exactly where you left off. This post shares the tmux configuration and automation scripts deployed across multiple production servers.

15

Servers deployed

tmux 3.4

Version used

3 panes

Max concurrent Claudes

0 lines

Work lost after reconnect

SSH Drop = Claude Session Gone

The traditional flow is straightforward.

Windows Terminal → SSH → claude → work

In this setup, the SSH connection is tightly coupled to the process lifecycle. The moment the SSH session drops, SIGHUP is sent to every process running inside it — including the claude process. Any in-progress file edits or analysis tasks are cut off mid-way.

Laptop lid closed → SSH drops → Claude session gone

Brief Wi-Fi interruption → SSH timeout → work in progress lost

Terminal window closed by mistake → context and all work reset

The longer the task and the more servers you operate, the more often this happens. For tasks that require Claude to process multiple files in sequence — such as large-scale refactoring or code analysis — an interruption means starting over with fresh instructions.

How tmux Solves This

tmux is a terminal multiplexer. The core idea is simple: it decouples the terminal process from the SSH connection.

Windows Terminal → SSH → tmux session → Claude

A tmux session lives as a server process, not as a child of your SSH connection. When SSH drops, the tmux session remains on the server. Reconnect via SSH and run tmux attach — Claude is right there, exactly where you left it.

tmux session lifecycle

Create: tmux new -s session-name → runs as an independent server process
Detach: Ctrl+b → d or SSH drop → session stays alive
Reattach: tmux attach -t session-name → resume exactly where you left off
Kill: exit or tmux kill-session → session deleted

When to Use tmux vs. Not

tmux is not always necessary. Use it based on the nature of the task.

ModeUse caseExamples
Direct run (instant)Quick one-off tasksEdit a single file, short question
tmux sessionContinuous or long-running workRefactoring, deploy automation, complex analysis
tmux multi-paneParallel independent tasksMultiple Claude instances each working on separate tasks

Separate aliases are used for each mode. c runs Claude Code immediately, cc is for reviewing conversation history.

alias c="command claude --dangerously-skip-permissions"
alias cc="claude-history"

Full .tmux.conf Configuration

Below is the full ~/.tmux.conf deployed across all servers. Every option has a reason. In particular, escape-time is covered in detail in the troubleshooting section below.

set -g default-terminal "xterm-256color"
set -sg escape-time 50
set -g history-limit 100000
set -g set-clipboard on
set -g allow-passthrough off
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -g mouse on
set -g status-left '[#S] '
set -g status-right '%H:%M %Y-%m-%d'
set -g status-style 'bg=colour235,fg=colour250'
setw -g monitor-activity on
set -g visual-activity off

Key option explanations

escape-time 50Time for tmux to process OSC response sequences. Setting to 0 causes color code strings to appear as raw text in the terminal when used with Windows Terminal.
allow-passthrough offBlocks terminal passthrough. Prevents escape sequence noise from OSC 11.
history-limit 100000Large scrollback buffer so you can review long Claude output.
mouse onMouse support for resizing panes and scrolling.
base-index 1Windows start numbering from 1 instead of 0 — aligns naturally with number keys.

tmux-claude Automation Script

Manually creating a session, launching Claude, and splitting panes every time is tedious. Place the script below at /usr/local/bin/tmux-claudeto get your full environment with a single command. The path /usr/local/bin/ is chosen because it is on the system PATH and available even when .bashrc is not sourced during SSH non-interactive execution. (See troubleshooting below.)

#!/bin/bash
SESSION="${1:-ai}"
DIR="${2:-~/ai}"
PANES="${3:-1}"

if tmux has-session -t "$SESSION" 2>/dev/null; then
    tmux attach -t "$SESSION"
else
    tmux new -s "$SESSION" -d -c "$DIR"
    tmux send-keys -t "$SESSION" 'c' Enter
    for ((i=2; i<=PANES; i++)); do
        tmux split-window -h -t "$SESSION" -c "$DIR"
        tmux send-keys -t "$SESSION" 'c' Enter
        tmux select-layout -t "$SESSION" even-horizontal
    done
    tmux attach -t "$SESSION"
fi

How it works

Session already exists → attaches to it (safe to run the same command on reconnect)
Session does not exist → creates it, launches Claude, splits into the requested number of panes
Multiple panes → Claude runs independently in each, with even-horizontal layout applied

Usage examples

# Default (session name: ai, working dir: ~/ai, 1 pane)
tmux-claude

# Custom session name and directory
tmux-claude dev ~/project

# 3-pane split (3 Claude instances simultaneously)
tmux-claude ai ~/ai 3

One-Click Launch from Windows

A batch file in Windows Terminal can handle SSH connection + tmux session entry in one step. Create a bat file per server and double-clicking the icon opens the Claude environment instantly.

Single pane

@echo off
wt nt cmd /k ssh -t main-server "tmux-claude ai ~/ai"

3-pane split (3 Claude instances)

@echo off
wt nt cmd /k ssh -t main-server "tmux-claude ai ~/ai 3"

Note: The -t flag in the SSH command is required. tmux needs a TTY (pseudo-terminal), but SSH commands run in non-interactive mode by default. Without -t, tmux fails to start properly.

Essential Commands Reference

Session management

CommandDescription
tmux new -s nameCreate a new session
tmux attach -t nameReattach to session (after reconnect)
tmux lsList all active sessions
tmux kill-session -t nameKill session including its processes
tmux detachDetach from session (session stays alive)

Inside a session (press Ctrl+b, release, then the key)

KeyAction
dDetach — exit session (session stays alive)
cCreate a new window
n / pNext / previous window
%Vertical split (left/right)
"Horizontal split (top/bottom)
Arrow keysMove between panes

exit vs. detach — the most important distinction

  • exit: Kills the session. Claude and everything inside is deleted. There is no going back.
  • Ctrl+b → d: Detaches. The session stays alive on the server. You can reattach later.

Troubleshooting Notes

Issues encountered during setup are documented here. Most are combination-specific problems that are not easily found by searching, so the root cause can take time to identify.

1. OSC color code strings printed to terminal

Symptom: Entering tmux prints strings like ^[]11;rgb:0c0c/0c0c/0c0c to the terminal

Cause: Windows Terminal responds to background color queries (OSC 11), and tmux displays that response as raw text on screen

Approaches that failed

# Attempt 1: screen-256color + terminal-overrides Tc → failed
set -g default-terminal "screen-256color"

# Attempt 2: tmux-256color + removing focus-events → failed
set -g default-terminal "tmux-256color"

# Attempt 3: removing all terminal-overrides → failed

Final fix

set -g default-terminal "xterm-256color"
set -sg escape-time 50        # critical: must not be 0
set -g allow-passthrough off  # block passthrough

Root cause: With escape-time 0, tmux has no time to process the OSC response sequence before printing it to screen. Setting it to 50ms gives tmux enough time to absorb the sequence without exposing it. Many guides recommend escape-time 0 for responsiveness, but it breaks when combined with Windows Terminal.

2. Claude Code install script: sh vs. bash

Symptom: curl ... | sh errors with Syntax error: (( unexpected

Cause: Ubuntu's /bin/sh is dash, but the Claude Code install script uses bash-specific syntax (((, etc.)

# This fails
curl -fsSL https://claude.ai/install.sh | sh

# Must specify bash explicitly
curl -fsSL https://claude.ai/install.sh | bash

3. Command not found in SSH non-interactive mode

Symptom: ssh server "tmux-claude ..." returns "command not found"

Cause: Running a command directly over SSH opens a non-interactive, non-login shell where .bashrc is not sourced. User PATH entries like ~/.local/bin are missing.

Fix: Place the script in /usr/local/bin/. It is on the system's default PATH and always reachable.

4. Changes to tmux.conf have no effect

Symptom: Editing ~/.tmux.conf does not change tmux behavior

Cause: The existing tmux server process is still running and has not reloaded the config

Fix: Run tmux kill-server to fully stop the server and restart. tmux source-file ~/.tmux.conf only reloads some settings.

5. Old Claude version running after native install

Symptom: Old Claude version runs even after a native install

Cause: A symlink from an npm install (/usr/bin/claude) has higher PATH priority than the native install path (/usr/local/bin/claude)

Fix: Remove or re-point the /usr/bin/claude symlink

6. Session names with special characters

Symptom: tmux new -s my-session-한글 errors

Fix: Use only alphanumeric characters, hyphens (-), and underscores (_) in session names. Keep them short and clear: ai1, dev-01.

Mass Deployment to Multiple Servers

When managing many servers, connecting to each one individually to configure tmux is inefficient. Using scp and ssh inside a loop with background parallel execution completes the full deployment in seconds.

Deploy .tmux.conf

for server in server1 server2 server3; do
  scp -q ~/.tmux.conf ${server}:~/.tmux.conf &
done
wait

Deploy tmux-claude script

for server in server1 server2 server3; do
  scp -q /usr/local/bin/tmux-claude ${server}:/tmp/tmux-claude
  ssh ${server} "sudo cp /tmp/tmux-claude /usr/local/bin/tmux-claude && sudo chmod +x /usr/local/bin/tmux-claude" &
done
wait

Each command is backgrounded with & and wait blocks until all finish. With many servers, the total time is equal to the slowest server because they run in parallel. After deployment, run tmux kill-server on each server to apply the new config.

Wrap-up

The tmux + Claude Code combination is simple to set up and immediately effective. You can hand off long tasks without worrying about SSH drops, and running multiple Claude instances in parallel panes for independent tasks is straightforward.

The most important configuration detail is escape-time. Many guides suggest setting it to 0 for responsiveness, but combining that with Windows Terminal causes OSC response strings to appear as raw text in the terminal. 50ms is the right value.

The biggest change tmux brought is the absence of urgency — there is no pressure to finish right now. When it is time to step away, Ctrl+b → d gets you out. When you return, Claude is waiting in the same place.

Related posts

T

Treeru

Sharing practical insights on web development, IT infrastructure, and AI solutions. Treeru — your partner in digital transformation.

Share

Comments

(4)
4.75/ 5

Log in to leave a comment.

2026-03-29
555.0

Lost Claude sessions multiple times working in unstable SSH environments without tmux. The attach-if-exists logic in tmux-claude is clean.

2026-03-29
555.0

Had no idea escape-time 0 was causing OSC response corruption. Spent a lot of time on that issue — 50ms was the key.

2026-03-29
454.0

Never thought about running 3 Claude instances in a split pane. Processing independent tasks in parallel should make things noticeably faster.

Related Posts

© 2026 TreeRU. All rights reserved.

All content is copyrighted by TreeRU. Unauthorized reproduction without attribution is prohibited.