taking your Zellij workspace to a distant server: disconnect-tolerant attach and detach, mosh for slow connections, jump hosts and bastions, remote sessions 0.44 for cross-machine attach, plus remote development best practices.

In episode 18 you mastered managing many sessions on a single machine. Now we remove the machine boundary: episode 19 covers Remote Development & SSH Workflow — bringing your Zellij workspace to a distant server and making it a permanent place to work, no matter how bad the connection between you is.
This is the episode that tests the classic reason people use a multiplexer: surviving SSH disconnects. When you work directly in a terminal without a multiplexer and the connection drops, foreground processes die with it — a build loses context, an editor closes forcefully, and ten minutes of work evaporates. With Zellij on the server, processes keep running behind the scenes, and you simply reconnect then attach back to exactly where you left off. This isn't convenience — it's a baseline requirement for serious server operations.
We'll cover the complete workflow: running Zellij on a remote server, disconnect-tolerant attach and detach behavior, mosh for slow connections and network roaming, jump hosts or bastions for layered networks, the 0.44 remote sessions feature that enables cross-machine attach without SSH, and best practices that keep the whole flow safe and smooth. By the end of the episode, you'll be comfortable working on any server as if it were on your laptop.
The first principle to understand: Zellij runs where its binary is. You run Zellij on the server, not on your laptop — the server holds the processes, and the laptop is just a window onto them. So the first step is installing Zellij on the server (the installation methods from episode 0 apply), then starting a session through SSH.
Before you begin, make sure Zellij is installed and working on the server. Verify once with zellij --version on the server, then run zellij setup --check to confirm the server's terminal environment supports the features you need. This short verification step saves you from a confusing debugging session in the middle of production server work.
Note one important detail: use the -t flag on SSH to force pseudo-terminal allocation, because Zellij is an interactive application that needs a TTY. The most common pattern is attach-or-create:
ssh deploy@db01 -t "zellij attach -c dev"The command above logs into the server db01, then runs zellij attach -c dev there. If the dev session doesn't exist, it's created; if it exists, you attach right to it. The same -c from episode 18 — the "create if absent" pattern that makes this command safe to run repeatedly.
You can also bring per-project layouts to the remote. If layouts are stored in the server's ~/.config/zellij/layouts/, invoking them is exactly like on a local machine:
ssh admin@app1 -t "zellij -s ops -l server-admin"Once a layout is stored on the server, remote sessions can be resurrected using the episode 17 mechanism — everything runs server-side, independent of your machine.
One note: make sure the server runs the same Zellij version as your local machine, or at least the same major version. Zellij client and server exchange data continuously; large version differences can make attach fail or produce unexpected behavior. If you manage Zellij configuration via dotfiles (a pattern we'll discuss in episode 27), sync the binary version too so the server experience matches local.
Once a session is running on the server, you attach to it over SSH as usual. When you press Ctrl+o then d to detach, or even when the connection suddenly dies before you can detach, the same thing happens: the Zellij client disconnects from the server, but the server and all processes inside the session stay alive on the server. This is the heart of remote development with Zellij.
Returning to work is just two steps: SSH again, then attach:
ssh deploy@db01
zellij attach devAfter attaching, you're exactly where you stopped: the same pane, the same tab, and processes that kept running while you were away. No state is lost on the application side — if you were running tail -f on a log, new lines kept flowing even while your screen was gone.
Note
Distinguish two conditions with different outcomes: explicit detach (Ctrl+o then d) and a dropped connection. On explicit detach, you cleanly disconnect the client; on a dropped connection, your SSH client dies but the remote Zellij server detects the lost client and keeps living. Both are safe for processes — but explicit detach is more predictable, especially when you want to make sure no output is lost while the client responds to network signals.
To make the SSH connection more resilient, repeat the lesson from episode 0: enable ControlMaster and ServerAliveInterval in ~/.ssh/config so handshakes aren't repeated and dead connections are detected fast. A solid SSH underneath and a persistent Zellij on top is the ideal pair for remote development.
SSH is the default choice, but on slow, unstable, or frequently roaming networks (like cellular hotspots), SSH can feel painful. This is where mosh (mobile shell) shines. Mosh is designed for bad connections: it syncs the screen incrementally, survives IP changes (roaming), and stays responsive even at high latency. Zellij runs perfectly inside mosh, because mosh only provides the terminal transport, and Zellij manages the session on top.
mosh deploy@db01
zellij attach devMosh installation varies by distro — here's the comparison:
sudo apt install moshNote that the server you connect to also needs mosh installed (the mosh-server package). Mosh communicates over UDP in the port range 60000 to 61000 — make sure the firewall allows it.
The smoothest working pattern is: mosh to the server, then start Zellij inside. Whenever the connection breaks — moving from WiFi to a hotspot, entering an elevator, or just locking your laptop — mosh holds the session on the client side, and when the connection recovers, you're straight back on the same screen, even with intact scrollback history. Because Zellij runs on the server, the work session truly doesn't depend on the client's network stability.
Important
Mosh isn't a substitute for SSH in every case. It doesn't support port forwarding or TCP tunnels the way SSH does, so for accessing a web server or database behind a server, still use SSH. For those of you using Zellij as the session layer (as we do), mosh is a very comfortable transport partner: Zellij handles session persistence, mosh handles flaky connections. For truly critical and secure connections, combine both — SSH for tunnels, mosh for the interactive terminal.
Many production infrastructures don't expose application servers directly to the internet. Servers can only be reached through a single entry point called a bastion or jump host. On such networks, you SSH to the bastion first, then to the target server. Zellij keeps working without changes — because really, you just need a TTY on the target server.
The modern way to hop through a bastion is ProxyJump (-J). The following command reaches server-db01 through bastion.example.com in a single hop:
ssh -J bastion.example.com deploy@server-db01 -t "zellij attach -c ops"For long-term convenience, save this configuration in ~/.ssh/config instead of typing it every time:
Host db01
HostName server-db01.example.com
User deploy
ProxyJump bastion.example.com
ControlMaster auto
ControlPath ~/.ssh/controlmasters/%r@%h:%p
ControlPersist 10m
ServerAliveInterval 60
ServerAliveCountMax 3With this configuration, the command ssh db01 -t "zellij attach -c ops" is all you need — SSH handles the whole hop chain. An important note: run Zellij on the target server, not on the bastion. The bastion should be only a traffic path, not a place where processes run.
Tip
When traversing several hops, watch key authentication. If your key only exists on your laptop, use agent forwarding (ssh -A) so the bastion doesn't need to store a private key. But don't turn -A on globally — enable it only for hosts you actually trust, because agent forwarding means every process on that server can borrow your SSH identity. This is the classic balance between convenience and security on layered networks.
Since version 0.44, Zellij offers a new approach to remote access: terminal-to-terminal attach over HTTPS. This isn't SSH — it leverages Zellij's built-in web server (introduced in 0.43) so a session on a server can be attached from a terminal on another machine just via a URL, complete with token authentication.
The flow: on the server, start the Zellij web server with zellij web, share a session, and create a login token. From the laptop, attach directly to the remote session using its URL:
zellij attach https://zellij.internal:8443/ops --token ops-token-123If you only want to observe without being able to send input, use read-only mode:
zellij watch opszellij watch attaches to the session in read-only mode — output is visible, input can't be sent. This feature is popular for demonstrations, screencasts, and inspecting production incidents without risking changes to the server state.
Token management is done via the zellij web CLI: create a token with --create-token, create a read-only token with --create-read-only-token, list tokens with --list-tokens, and revoke with --revoke-token. Tokens are only shown once at creation — store them in a safe place, because if lost, you must revoke and recreate. Most of these operations can also be done from the share plugin, which we'll dissect fully in episode 20.
Warning
Remote sessions open the server's terminal to the network — that means opening a dangerous door if configured carelessly. The Zellij web server requires HTTPS when serving non-localhost, and tokens must be guarded like server keys. Recommended practices: never expose the web server port directly to the internet without a reverse proxy and firewall, rotate tokens periodically with zellij web --revoke-token, and limit to only the sessions that truly need sharing. For most cases, SSH remains the safest route — use remote sessions when SSH isn't practical, for example across tight network boundaries.
To make the whole remote flow feel professional, apply the following practices consistently:
| Practice | Reason |
|---|---|
| Zellij on the server, not the laptop | Processes stick to the server; the laptop can die anytime |
| Consistent session names per server | zellij attach -c name becomes idempotent and easy to remember |
ControlMaster + ServerAliveInterval | No repeated handshakes, disconnects detected fast |
| mosh for unstable networks | Roaming and high responsiveness on bad latency |
| Bastion for traffic only | Don't run processes on the jump host |
| SSH for tunnels, Zellij for sessions | Each tool does what it does best |
Additionally, make a habit of checking server state before attaching: zellij ls on the server gives a picture of running and resurrectable sessions — a combination of the lessons from episodes 17 and 18, now working in a remote context. If you work across many servers, consider keybinding remaps (episode 9) to distinguish local and remote contexts.
The combination of practices above makes remote development stop feeling like patching a fragile connection. The flow I recommend: one fixed session name per server (ops, dev, release), one consistent way in (mosh for interactive work, SSH for tunnels), and the habit of zellij ls before attaching. That way, moving from laptop to production server and back becomes a routine as smooth as switching tabs.
zellij is run on the target server — verify with zellij ls on the server, not the local machine.-t flag on SSH. Without a pseudo-terminal, interactive applications like Zellij fail to start. Always include -t when running Zellij through an SSH command.In this episode 19 you've taken Zellij beyond the machine boundary. We started by running Zellij on a remote server, understanding why attach and detach tolerate dropped connections, then chose the right transport: mosh for bad networks, jump hosts for layered networks, and remote sessions 0.44 for cross-machine attach without SSH. We closed with best practices that keep the whole flow safe and predictable.
The points to take away:
Remember, the Learn Zellij series consists of 28 episodes that build on each other. Now you can work on any server with a persistent workspace. Next, it's time to share: what if other people join in watching or working in the same session — from their own terminals, or even from a browser? In episode 20 we cover Multiplayer & Web Client: the share plugin, read and write permissions, pair programming flows, and accessing sessions from a browser without installing anything. See you in episode 20!