top | item 40476410

Tmux is worse-is-better

225 points| hiAndrewQuinn | 1 year ago |hiandrewquinn.github.io

271 comments

order
[+] kelnos|1 year ago|reply
I feel like "parsing each keystroke twice" is pretty low on the list of things that wastes CPU cycles and drains my laptop battery. I cannot at all get worked up over this, getting to the point I'd pull out the word "poison" to describe it.

It's nice that Kitty does most of what tmux does built in, but as the author points out, that's not really all that helpful for anyone who does any work over ssh.

And to me, bundling all that into a terminal emulator is bloat. Terminals should be terminals. If I want a multiplexer on top of that, I will... use a multiplexer on top of that.

I am potentially sympathetic to the idea that tmux and screen make it harder for terminal developers to add new features to their terminals. I don't really know enough about the issues involved to form an opinion. But from the perspective of a regular user, I do not want a multiplexer in my terminal app. When I need one, I prefer to reach for an app-agnostic multiplexer like tmux or screen.

[+] j2kun|1 year ago|reply
> remote persistence

This is the real reason I actually need tmux. I often lose connection to a server for various reasons and don't want to lose my vim session or whatever

[+] bayindirh|1 year ago|reply
It's not only a safety net for losing connection. As soon as I connect to a server to do work, I automatically fire screen, and create new terminals and rename them as I work with the system.

If my work is unfinished, I leave the screen as is, and disconnect. We don't touch each others' screen instances on servers, so it's a safe workspace which I can return whenever I want.

[+] pessimizer|1 year ago|reply
I've literally had projects running from screen sessions for years. I always assumed the purpose of them was so I could turn off my computer while doing something over the network that was either long-lived, on an unstable connection, or a daemon/server of some sort.
[+] bradfox2|1 year ago|reply
Is there anything better than tmux for this purpose? I need persistence but hate the key bindings and general interface.
[+] adtac|1 year ago|reply
tmux over mosh over wireguard is all you need
[+] e40|1 year ago|reply
I can’t live without X11 emacs, so I use Starnet’s FastX, which allows me to disconnect and reconnect either when my connection drops or when I move between office and home. I absolutely couldn’t live without it.
[+] marcosdumay|1 year ago|reply
Nowadays everybody is in a GUI terminal emulation anyway. Multiplexing is completely redundant.

I imagine everybody uses screen and tmux mainly for remote persistence.

[+] nephanth|1 year ago|reply
Imo, the killer feature of tmux is that not only does it persist your shell, it persists your workspace. If I ssh into my server, i'm going to find my whole session as i left it, with the same tabbing / panes.

This is a need kitty+screen doesn't answer. If I close kitty & reopen it, i'll have to re-split every individual pane, and reconnect each of them and reattach them to the right persistent screen pts...

Infact if there was a way to handle that "workspace-persistence" with terminal emulator-based workspaces, I'd ditch tmux in a minute

EDIT: now that i think about it, this could maybe be achieved by keeping the terminal multiplexer's "server", but having the terminal emulator act as a client to it

[+] bee_rider|1 year ago|reply
> Kovid Goyal, developer of the ePub powerhouse calibre and my current teminal emulator of choice Kitty, has gone on record a number of times saying he is not a fan of tmux. He has a whole section in his FAQ about it:

>> [T]erminal multiplexers are a bad idea, do not use them, if at all possible. kitty contains features that do all of what tmux does, but better, with the exception of remote persistence.

Bit funny, most of the time I’m running tmux in kitty (or ssh in kitty to a server with tmux).

Remote persistence is a pretty massive deal, though.

In general, I don’t like getting attached to a terminal emulator, and mostly just try to avoid using any unique features they’ve got. If a terminal emulator and a command line program are competing for doing a task, the terminal emulator in some sense has an unfairly high hurdle to pass: if I become dependent on the terminal emulator to do it, then I can’t replace the terminal emulator without also getting a new muscle memory for that task, if I ever want to switch terminal emulators.

Which means it has to do that task so much better than the command line program that the delta is worth more than any possible improvements from switching terminal emulators. Kitty is a great terminal emulator but this is an absurd and basically unfair bar that it could never pass.

In this case, though, it is actually worse than tmux because it can’t offer the best thing terminal multiplexers do: remote persistence, which is the killer feature.

[+] omoikane|1 year ago|reply
kitty seems to be a relatively more opinionated terminal compared to other terminals. The first time I heard about kitty was via a comment about not implementing Sixel support:

https://github.com/kovidgoyal/kitty/issues/2511#issuecomment...

"Terminal multiplexers are a bad idea" sounds just like Sixel being "an inferior graphics protocol", and Sixel is probably another example of "worse is better".

[+] neilv|1 year ago|reply
Basic `screen` or `tmux` awareness (how to start it, how to create and switch between windows, how to reattach if disconnected) should be in the toolkit of anyone who finds themself needing to SSH into a server.

Especially in startups, where you can't afford to be sitting atop massive too-big-to-fail enterprise bureaucracy, and need to understand the systems, and work creatively and efficiently with them.

[+] SoftTalker|1 year ago|reply
Yes very much. You don't need to be an expert. Just knowing how to detach from a running tmux and reattach later, and knowing how to create and navigate between tmux windows and panes is most of what you need to know.
[+] noloblo|1 year ago|reply
i use neovim and screen as defaults and find them quite useful, but never found tmux useful, please change my mind tmux what are good starter tutorials?
[+] andrewaylett|1 year ago|reply
In your `~/.ssh/config`, make sure you have:

    Host *
      ControlMaster auto
      ControlPath ~/.ssh/control/%C.sock
      ControlPersist 300s
And SSH will multiplex as many sessions as you want into a single connection. If you're not using tmux to allow you to resume detached session, this works really nicely. I have fingerprint auth for the first session, to establish the connection, then I can connect and disconnect to my heart's content without authenticating again unless I have no connections open for 300s.

I typically use plain SSH with persistent sessions, and connect over Tailscale so even if I go offline and reappear on a different IP address my session will probably survive. If my session doesn't survive, it's easy enough to start a new one :).

The missing piece, from what others have commented about, is long-running commands. If I'm upgrading Debian over SSH then I will do that in `screen`, but for pretty much anything else I'd prefer to launch it as a (possibly ad-hoc) service and let my service manager look after it.

[+] erik_seaberg|1 year ago|reply
I nohup anything slow that isn't interactive, it's POSIX and the logged output might be useful if it dies halfway.
[+] tombert|1 year ago|reply
> but its fundamental value add to any programmer who has to SSH into servers more than once a week is it allows you to split your screen up into multiple independent shells without needing a graphical environment at all.

I actually think that value add for SSH is that people is the ability to allow long-running jobs to survive a disconnection. It can be frustrating doing something that takes multiple hours (like a large wget download) just to have your connection break about ten minutes before it's done. Even if you never use any of the other features you immediately benefit from that.

[+] idatum|1 year ago|reply
For remote SSH, I like to use an .ssh/config setting for the remote host and automatically start a remote tmux. Saved my work a few times from spotty connections from my laptop tethered to my phone. Something like this:

    Host t-sdf
        HostName sdf.org
        User idatum
        RemoteCommand tmux new -A -s mylaptop
        RequestTTY yes
Then log in with

    ssh t-sdf
and tmux is happily running a session named "mylaptop". Connecting again gets you back to the same tmux session.

I use tmux daily and I haven't found a reason to switch.

[+] jrockway|1 year ago|reply
I agree with all of this completely. I also run Windows as my host OS and do all my work in Linux. I don't use X, I ssh into the Linux VM and have Emacs alongside a bunch of shells running in tmux. It is very productive and even when I have a physical Linux machine, I just start up X, maximize a terminal, and use tmux.

The author of Kitty is also right about performance. I've never looked into exactly where the problem is, but tmux <- ssh <- windows terminal is very very very slow. This is most annoying when some program starts printing a ton of stuff and your control C keypress is ignored for a good 15 seconds. While this Should Not Be, I can live with it for the other gains. I do a lot of pair programming with people, and I've never seen a better or more productive setup than this one.

[+] bombela|1 year ago|reply
What is the advantage/use of Windows compared to some Linux desktop in your setup?
[+] tedunangst|1 year ago|reply
Possibly tmux buffering output. Control C kills the process immediately, but there's still 15 seconds of output in the pipe.
[+] orev|1 year ago|reply
That 15 second lag is related to the network buffering, and would happen inside a muxer as well as outside. A muxer may add another layer of buffering, but I find that you can typically clear it out faster by switching to another window then back, so the output doesn’t need to be sent over the network.
[+] chasil|1 year ago|reply
>every byte has to be parsed twice, once by the middleman and once by the terminal.

The ~ (tilde) codes in OpenSSH imply that it also performs minimal parsing. Particularly, "(return)~." to terminate a locked session.

The tmux program is invaluable to me when I have a long-running set of interactive commands, and I want them to survive a network disconnect.

There may be valid criticisms of tmux, but wow is it good at this particular thing.

[+] INTPenis|1 year ago|reply
Kovid may be right, but from a usability standpoint they're dead wrong.

Users will gravitate towards what makes their life simpler, once it was screen and now it's tmux. Regardless of the technicality behind it.

I actually gave zellij a try recently but went right back to tmux. Zellij seems like a very promising software but tmux still has a lower threshold of entry.

[+] sgt|1 year ago|reply
What's wrong with screen? I tried tmux about 15 years ago but didn't really see the major benefit. Has it changed much?
[+] KolmogorovComp|1 year ago|reply
The only annoying thing with tmux are recursive sessions. By that I mean when you run tmux on your laptop, then ssh to your server and start another tmux session there. It is suddenly confusing and you then have to escape commands depending on which session you want to interact with.

I’ve been using screen at first remotely for those cases, but eventually bailed out and used my graphical multiplexer locally instead of tmux, or not using tmux remotely when already using it locally.

[+] wging|1 year ago|reply
The way I typically handle that is via native terminal-app tabbing. Tab 1: local tmux session, tab 2: remote tmux session. (My normal workflow doesn't go beyond 2 systems, 3 in an edge case.) You don't need much support from the terminal to do it this way; it works in gnome-terminal on Linux and iTerm2 on Mac, and probably also macOS's built-in native terminal. You just need an app-level shortcut to go forward/back between tabs, then tmux's shortcuts for navigation within the system.

(I don't use iTerm2's native tmux integration, so any poor interactions with that when I'm on Mac aren't a concern, and when I'm on Linux gnome-terminal has just as much utility for me.)

[+] mrshu|1 year ago|reply
Being a big tmux fan, I never thought it would come to something like this, but Zellij (https://zellij.dev/) has completely solved this for me. I generally run Zellij on my laptop and tmux on remote servers -- it's been a surprisingly positive experience so far.

Try it out -- your tmux muscle memory (e.g. all the hotkeys you remember) will also work out of the box.

[+] jwr|1 year ago|reply
I made this somewhat less confusing for myself by defining keyboard shortcuts in my Terminal app (MacOS) and using those for switching between tmux screens. E.g. command-n and command-p switch to next and previous locally, while shift-command-n and shift-command-p switch next and previous in a nested remote tmux session.
[+] thanatos519|1 year ago|reply
I use different escape keys for my local and remote sessions and after many years I don't get confused anymore.
[+] mat_epice|1 year ago|reply
I have a system where I use a tmux-server config that has a different prefix (^O), status bar color (yellow), and location (top). I use that for my outer tmux session, then start default configs on other host systems. Works pretty well, I don’t have any complaints.
[+] ehsankia|1 year ago|reply
To me, the only annoying thing with tmux is copy/pasting across different setups and how inconsistent / flaky / tricky it is to get working.
[+] tetris11|1 year ago|reply
This very much so. I wish there was some kind of SSH "passthrough" that allowed a tmux session on remote to attach to a tmux local.
[+] wazoox|1 year ago|reply
For this reason I usually run screen locally and tmux remotely, that's good enough IMO.
[+] gitaarik|1 year ago|reply
Yeah that's why I use Kitty tabs for every single tmux session I run :)
[+] amouat|1 year ago|reply
Just wanted to say that I appreciate how well written this is. It does make a difference when an author can clearly and succinctly state their case.
[+] kanodiaashu|1 year ago|reply
I ssh from a mac into linux servers for my everyday work.

I went from tmux + vim TO (doom) emacs + tramp + projectile. I think I outgrew vim, and emacs EVIL gave me VIM but also magit and org and projectile. I tried to work in the emacs shell for a while. I realised I need tmux persistence still. Emacs shell also just doesn't do well with EVIL mode. So now I just do all development on emacs and manage runs etc through my tmux, occasionally still using vim on the tmux to manage config files when I don't want to load them into emacs because its a one off.

I dk about kitty, but I'm a fan of Kovid Goyal's calibre. I can't imagine how I would live without a. multiplexing b.persistence c.returning me to my context. And I never have had any tmux problems.

[+] PUSH_AX|1 year ago|reply
I would be lost without tmux, if you have a regular ssh date with some machine it’s a life saver.
[+] ProfessorZoom|1 year ago|reply
bad for energy? sir i code typescript in tmux
[+] Repulsion9513|1 year ago|reply
> > [Terminal m]ultiplexers add unnecessary overhead, suffer from a complexity cascade, because they actually have to translate escape codes, modifying them in hackish ways to get them to work with their concepts of windows/sessions. […]

So... like how a terminal emulator translates escape codes, modifying them in hackish ways to get them to work with X's/Wayland's/users' concepts of windows/sessions? :)

Obviously that's not an apples to apples comparison but really, while that may make it more complex and slightly buggier I don't see how that makes it bad.

> I find myself typing out “tmux” as the first command I run. Because it’s always going to be there, and it does the one thing I actually need it to no matter what: Let me run multiple shells at once, without SSHing in multiple times

I don't understand why people hate opening up another SSH session. If you're really worried about the 10 seconds it might take, you can easily configure it to take more like 1:

       -M      Places  the  ssh client into “master” mode for connection shar‐
               ing.  Multiple -M options places ssh  into  “master”  mode  but
               with confirmation required using ssh-askpass(1) before each op‐
               eration that changes the multiplexing state (e.g. opening a new
               session).    Refer  to  the  description  of  ControlMaster  in
               ssh_config(5) for details.

The only reason I ever use screen is for persistence, the multi-windows is just a secondary feature.

(Since when is tmux "always going to be there"?)

[+] neilv|1 year ago|reply
I once half-seriously leaned on the lightweight possibilities of reattachable SSH sessions, for a very-very simple way of running/monitoring/futzing a simple server process, when you don't need a big enterprise deployment and observability platform.

https://www.neilvandyke.org/racket/rackonsole/

[+] SoftTalker|1 year ago|reply
Love tmux. I don't find myself splitting one window into panes very often, but I certainly use multiple "tabs" (windows) in a tmux session. I keep a tmux session running on my work computer, which has logins to all my commonly needed systems. I can ssh in from home (or anywhere), attach to that tmux session, and instantly have everything I need.
[+] noloblo|1 year ago|reply
how do you attach to a tmux session via ssh?
[+] eigenvalue|1 year ago|reply
I, for one, love tmux. But I hate it with the stock settings on a fresh machine. Having to use keyboard shortcuts to switch between windows is especially annoying. I have this in an ansible playbook I run on all new machines to set tmux up nicely (I also use ohmyzsh and atuin, but that’s another story):

    - name: Install custom tmux configuration
      become: yes
      become_user: ubuntu
      git:
        repo: https://github.com/gpakosz/.tmux.git
        dest: /home/ubuntu/.tmux/

    - name: Set up custom tmux configuration
      become: yes
      become_user: ubuntu
      shell: |
        cd /home/ubuntu/
        ln -s -f .tmux/.tmux.conf
        cp .tmux/.tmux.conf.local .

    - name: Set up further tmux customizations
      become: yes
      become_user: ubuntu
      blockinfile:
        path: "/home/ubuntu/.tmux.conf.local"
        insertafter: "# EOF"
        block: |
          set-option -g default-shell $SHELL
          set -g mouse on
          set-option -g history-limit 25000
          set -g @plugin 'tmux-plugins/tmux-resurrect'