Building the foundation of tmux configuration: the location and loading order of ~/.tmux.conf, the bind-key and set-option grammar along with server/global/window option levels, must-have settings like mouse, and the reload workflow.

In episode 5 we changed a lot of tmux behavior — mode-keys vi, set-clipboard on, history-limit — and nearly all of it was done via one-off commands in the command prompt. One-off commands are effective, but they have one problem: they vanish the moment the tmux server restarts. This episode closes that gap by building the foundation of tmux configuration — a single text file named ~/.tmux.conf that holds all your settings and can be carried anywhere.
Why is this config file so important in the real world? Because senior engineers don't work from memory — they work from reproducible artifacts. A good tmux config is living documentation: it records decisions you made in the past (why the prefix was changed to Ctrl+A, why escape-time was lowered), while also being version-controllable in a dotfiles repo and syncable from laptop to server. In tmux 3.7b (the latest stable release at the time of writing), one ~/.tmux.conf makes all your machines feel identical — no more "weird, why doesn't % work on this server?"
The map for this episode: first we understand where the config file lives and when tmux reads it. Then we learn how to reload without restarting via source-file. Next, the core grammar — bind-key, unbind-key, set-option, set-window-option — along with the server, global, session, and window option levels. After that we cover the must-have settings present in almost every config, and we close with a complete starter config you can use right away.
The main tmux config file is ~/.tmux.conf in your home directory. Since tmux 3.1, you can also use $XDG_CONFIG_HOME/tmux/tmux.conf if you follow the freedesktop spec — tmux uses it as long as ~/.tmux.conf doesn't exist. Pick one and stay consistent; don't keep both, because that only creates two sources of truth that can collide.
The full loading order is as follows: if it exists, tmux reads /etc/tmux.conf (system configuration), then the user file — ~/.tmux.conf or the XDG variant. The -f flag of the tmux -f file.conf command can force tmux to use a specific file instead. Finally, if ~/.tmux.conf.local exists, it's read afterward — this is a good pattern for per-machine overrides: the main config stays in version control, while ~/.tmux.conf.local is left free on the local machine.
The crucial point that's rarely understood: the config file is read once, when the tmux server is first created — that is, when the first session is run. When you close the terminal and tmux attach back to the same session, the server is already alive and the config file isn't re-read. This is the source of the classic confusion: "I already edited ~/.tmux.conf, why didn't it change?" The answer isn't that the config is wrong — it's that the config hasn't been re-read. Understanding this reading moment is the basis for the importance of the reload workflow in the next section.
To apply changes without dropping sessions, tmux provides source-file — a command that reads and executes the config file as if it had just been read at startup. Run it from the command prompt with prefix + : then source-file ~/.tmux.conf, or straight from the shell with tmux source-file ~/.tmux.conf. Another useful option: tmux source-file ~/.tmux.conf \; display-message "Config reloaded!" — the semicolon here is a tmux command separator, not a shell one.
Typing that command every time is tiresome, so practitioners install a reload keybinding in the config:
bind r source-file ~/.tmux.conf
bind R source-file ~/.tmux.conf \; display-message "Config reloaded!"The pattern above uses two bindings: prefix + r for a silent reload, and prefix + R for a reload that confirms with a message in the status bar. Note the \; — the backslash before the semicolon tells tmux that the semicolon is a command separator, not part of the source-file argument. This is one of tmux's grammar details that most often trips up beginners, and it'll be a test case in the common pitfalls section. The ideal workflow is always: edit the file → prefix + r → test → commit to dotfiles.
Tip
source-file is also useful for splitting a large config into several files. For example source-file ~/.tmux/bindings.conf inside ~/.tmux.conf — each file holds one domain (keybindings, appearance, plugins), and reload stays a single keystroke. This is the pattern we'll use as the config grows in later episodes.
The ~/.tmux.conf grammar follows tmux command syntax: each line is one command. The two command families used most often are bind-key/unbind-key for keybindings, and set-option for settings.
bind-key KEY perintah connects a key to a tmux command, and unbind-key KEY disconnects it. For beginners, these two commands are often swapped: unbind isn't "release the key to the application", it's removing the tmux binding for that key. The correct order to change one is: unbind first, then bind. Flags you'll often see: -n for prefix-free keybindings (covered in episode 4), -r for repeatable keybindings (resize, for example), and -T to choose a key table — e.g. bind -T prefix C-x new-window binds prefix + Ctrl+x.
set-option (usually shortened to set) sets session options, and set-window-option (setw) sets window options. Both use the -g flag to mark "global", i.e. the default value applying to all newly created sessions or windows. For example: set -g mouse on is a session option, while setw -g mode-keys vi is a window option. Using set for a window option usually still "works" in many cases, but separating them properly makes your config clear and easier for others to read.
The concept you must understand thoroughly is the option level. Tmux distinguishes four layers: server options apply to the whole server; session (global) options become the default for sessions; window (global) options become the default for windows; and pane options apply to individual panes. A value at a more specific layer overrides the global default. This is why set -g history-limit 10000 only needs to be written once — all windows created afterward inherit that value, unless something overrides it specifically.
| Level | Command | Example | Affects |
|---|---|---|---|
| Server | set -s | set -s escape-time 10 | The whole server and all sessions |
| Session (global) | set -g | set -g mouse on | All newly created sessions |
| Session (specific) | set | set mouse off | Only the current session |
| Window (global) | setw -g | setw -g mode-keys vi | All newly created windows |
| Window (specific) | setw | setw remain-on-exit on | Only the current window |
set -g mouse on enables full mouse support: resize panes by dragging borders, scroll the scrollback with the wheel, and click to move focus. Without this option, the mouse wheel does nothing in tmux — one of the biggest complaints from migrants of a plain terminal. The side effect must be understood: mouse text selection is redirected to tmux selection (entering copy mode), so to copy outside tmux you need to hold Shift or use the copy mode mechanisms from episode 5.
set -g history-limit 10000 expands the default scrollback from 2,000 to 10,000 lines. Remember the ring buffer nature from episode 5: this limit is set when the window is created, not when the config is reloaded. Changing it and reloading won't expand existing windows — you need to create a new window or restart the server (tmux kill-server then start again) to see the effect.
set -sg escape-time 10 lowers tmux's timing window for the Escape character from the 500 ms default to 10 ms. This number is very noticeable in vim or emacs: with the default value, pressing Esc inside the editor often feels "stuck" because tmux waits to see whether Escape will be followed by another key (read as an arrow-key sequence). Lowering it makes Esc respond instantly. Be careful at the lower bound: a value too small like 1 ms can make tmux misread arrow-key escape sequences on some terminals — 10 to 50 ms is the safe zone.
set -g base-index 1 changes window numbering from zero to one. The practical reason is simple: prefix + 0 sits in the top-left corner of the keyboard and is often mispressed, even though window 0 is rarely the target; starting from 1 aligns the numbering with human habit. set -g default-shell /bin/zsh ensures tmux always uses the shell you want, regardless of the shell recorded in the system's password database — for those who keep a special shell in their config, this line prevents "why does the pane use another shell?"
set -g mouse on
set -g history-limit 10000
set -sg escape-time 10
set -g base-index 1
set -g default-shell /bin/zsh
setw -g pane-base-index 1The last line, setw -g pane-base-index 1, sets pane numbering to start at 1 — aligned with base-index for windows. With both, your pane and window numbers consistently start at one, which really helps when talking to commands like capture-pane -t 0:1.2 from episode 5.
Here's the combination of everything we've covered, plus the reload keybinding from episode 4 and copy mode from episode 5, in one complete file you can copy and adapt:
# ------------------------------------------------------------
# Starter config Belajar Tmux (tmux 3.7b)
# ------------------------------------------------------------
# Prefix: ubah dari Ctrl+B ke Ctrl+A
set -g prefix C-a
unbind C-b
bind C-a send-prefix
# Setting dasar
set -g mouse on
set -g history-limit 10000
set -sg escape-time 10
set -g base-index 1
set -g default-shell /bin/zsh
# Penomoran window dan pane dimulai dari 1
setw -g pane-base-index 1
# Copy mode gaya vi + clipboard lintas SSH
set -g mode-keys vi
set -g set-clipboard on
# Reload konfigurasi: prefix + r
bind r source-file ~/.tmux.conf
bind R source-file ~/.tmux.conf \; display-message "Config reloaded!"Every part of this file has been covered in previous episodes, so now you can read it like a document, not a string of foreign text. Replace default-shell with the shell path you use (/bin/bash, /bin/zsh, or $SHELL as you prefer). Once the file is saved, start a new server or run tmux source-file ~/.tmux.conf to test. Keep this file in your dotfiles repo — from now on, all your machines will feel like home.
Important
There's one trap to remember: server settings like history-limit and default-shell only take full effect after the server is restarted (tmux kill-server then start a new session). Keybindings and session options can be tested with just prefix + r, but if something feels "unchanged" despite reloading, it's likely a server-only option. Restarting the server isn't scary — the sessions running on it are lost too, so do it when there's no work you need to keep.
Changing history-limit and expecting immediate effect. The scrollback limit is applied when the window is created. For old windows, create a new window or restart the server — reload alone isn't enough.
Forgetting \; for multiple commands in one bind. bind R source-file ~/.tmux.conf \; display-message "..." fails to parse without the backslash before the semicolon. The error message appears on reload, and the keybinding isn't installed.
Swapping set and setw. Window options like mode-keys must use setw; session options like mouse must use set. Even though many options still work in the wrong place, a correct config is easier to read and maintain.
Putting server options in the config file without understanding the reading moment. The config is read once when the server is born. New changes need a reload or restart, not just an edit.
Setting escape-time too low. A 1 ms value does make Esc instant, but it can misread arrow-key sequences on certain terminals. Start at 10 ms and increase if there's a problem.
Keeping the config only on the local machine without version control. A config that isn't in a dotfiles repo will be lost or fragmented across machines — and you'll redo all these decisions from scratch on the next server.
This episode brought everything together into one lasting artifact. You understand where tmux looks for configuration (~/.tmux.conf or the XDG variant), when the config is read (once when the server is born), and how to apply changes without restarting via source-file — complete with the prefix + r keybinding. You mastered the bind-key/unbind-key grammar, set-option vs set-window-option, and the server, global, session, and window option levels. You also carry the must-have settings: mouse on, history-limit 10000, escape-time 10, base-index 1, and default-shell — all summarized in a ready-to-use, version-controllable starter config.
Key points to take away:
tmux source-file ~/.tmux.conf.bind/unbind for keybindings, set/setw for options; -g means global.mouse, history-limit, escape-time, base-index, and default-shell are the foundation of almost every config.~/.tmux.conf in a dotfiles repo; provide ~/.tmux.conf.local for per-machine overrides.With a tidy config, your tmux now feels like "yours". In episode 7 we step up to the art of arranging space: pane layout and advanced manipulation — preset layouts like even-horizontal and main-vertical, precise resizing, swapping panes, break-pane and join-pane for moving panes between windows, zoom, up to display-panes. See you in episode 7!