WezTerm provides powerful multiplexing features that allow you to manage multiple terminal sessions within a single application. You can organize your work using tabs, split panes, multiple windows, and even connect to remote multiplexer sessions.
Multiplexing is an actively evolving feature in WezTerm. Your feedback and suggestions are welcomed!
What is Multiplexing?
Multiplexing allows you to run multiple terminal sessions in a single terminal emulator instance. Think of it as having multiple terminals in one, similar to tools like tmux or screen .
Benefits of Multiplexing
Organize your workspace - Group related tasks in tabs or split them into panes
Preserve sessions - Keep sessions alive even when disconnected (with domains)
Remote access - Connect to multiplexer sessions on remote machines
Efficient workflow - Switch between tasks without managing multiple terminal windows
Core Concepts
Panes
Panes are individual terminal sessions within a tab. You can split a tab horizontally or vertically to create multiple panes.
Tabs
Tabs contain one or more panes. Each tab can be split independently and has its own title.
Windows
Windows are separate operating system windows, each containing tabs. Multiple windows allow you to use multiple monitors effectively.
Domains
Domains are distinct sets of tabs and panes. Domains can be local or remote (via SSH, Unix socket, or TLS).
Working with Panes
Panes allow you to divide a single tab into multiple terminal sessions.
Creating Panes
Default: Ctrl+Shift+Alt+% (or Cmd+Shift+% on macOS) config . keys = {
{
key = '%' ,
mods = 'CTRL|SHIFT|ALT' ,
action = wezterm . action . SplitHorizontal { domain = 'CurrentPaneDomain' },
},
}
Default: Ctrl+Shift+Alt+" (or Cmd+Shift+" on macOS) config . keys = {
{
key = '"' ,
mods = 'CTRL|SHIFT|ALT' ,
action = wezterm . action . SplitVertical { domain = 'CurrentPaneDomain' },
},
}
Navigating Between Panes
Move focus between panes using directional keys:
config . keys = {
{
key = 'LeftArrow' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . ActivatePaneDirection 'Left' ,
},
{
key = 'RightArrow' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . ActivatePaneDirection 'Right' ,
},
{
key = 'UpArrow' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . ActivatePaneDirection 'Up' ,
},
{
key = 'DownArrow' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . ActivatePaneDirection 'Down' ,
},
}
Resizing Panes
Adjust pane sizes dynamically:
config . keys = {
{
key = 'LeftArrow' ,
mods = 'CTRL|SHIFT|ALT' ,
action = wezterm . action . AdjustPaneSize { 'Left' , 5 },
},
{
key = 'RightArrow' ,
mods = 'CTRL|SHIFT|ALT' ,
action = wezterm . action . AdjustPaneSize { 'Right' , 5 },
},
}
You can zoom a pane to full-screen temporarily while keeping other panes in the background. Use TogglePaneZoomState to zoom/unzoom.
Working with Tabs
Tabs help you organize multiple terminal sessions without cluttering your screen.
Creating and Managing Tabs
config . keys = {
-- Create new tab
{
key = 't' ,
mods = 'SUPER' ,
action = wezterm . action . SpawnTab 'CurrentPaneDomain' ,
},
-- Close current tab
{
key = 'w' ,
mods = 'SUPER' ,
action = wezterm . action . CloseCurrentTab { confirm = true },
},
-- Navigate tabs
{
key = '[' ,
mods = 'SUPER|SHIFT' ,
action = wezterm . action . ActivateTabRelative ( - 1 ),
},
{
key = ']' ,
mods = 'SUPER|SHIFT' ,
action = wezterm . action . ActivateTabRelative ( 1 ),
},
}
Jump to Specific Tab
Quickly switch to a tab by number (1-9):
for i = 1 , 9 do
table.insert ( config . keys , {
key = tostring ( i ),
mods = 'SUPER' ,
action = wezterm . action . ActivateTab ( i - 1 ),
})
end
Setting Tab Titles
Customize tab titles programmatically:
# Using wezterm CLI
wezterm cli set-tab-title "My Project"
Or configure dynamic titles based on the running process:
wezterm . on ( 'format-tab-title' , function ( tab , tabs , panes , config , hover , max_width )
local title = tab . tab_title
-- If no title is set, use the active pane's title
if title and # title > 0 then
return title
end
return tab . active_pane . title
end )
Multiplexing Domains
Domains are the foundation of WezTerm’s multiplexing architecture. Each domain represents a distinct set of windows and tabs.
Local Domain
The default domain manages tabs and windows in your local WezTerm instance. These sessions persist until closed but don’t survive application restarts.
Unix Domains
Unix domains allow you to connect to a WezTerm multiplexer server via Unix sockets, enabling persistent sessions that survive client disconnections.
Unix domains work on all platforms, including Windows (using named pipes), and are perfect for connecting Windows to WSL.
Basic Configuration
config . unix_domains = {
{
name = 'unix' ,
},
}
-- Auto-connect on startup
config . default_gui_startup_args = { 'connect' , 'unix' }
Manual Connection
Advanced Configuration
config . unix_domains = {
{
name = 'unix' ,
-- Custom socket path (optional)
socket_path = '/path/to/socket' ,
-- Don't auto-start server if connection fails
no_serve_automatically = false ,
-- Skip permission checks (useful for WSL)
skip_permissions_check = false ,
-- Predictive local echo threshold (milliseconds)
local_echo_threshold_ms = 10 ,
},
}
Connecting Windows to WSL
This only works with WSL 1. WSL 2 doesn’t support AF_UNIX interop between Windows and Linux.
Inside WSL:
config . unix_domains = {
{
name = 'wsl' ,
socket_path = '/mnt/c/Users/USERNAME/.local/share/wezterm/sock' ,
skip_permissions_check = true ,
},
}
On Windows:
config . unix_domains = {
{
name = 'wsl' ,
serve_command = { 'wsl' , 'wezterm-mux-server' , '--daemonize' },
},
}
config . default_gui_startup_args = { 'connect' , 'wsl' }
SSH Domains
SSH domains connect to a remote WezTerm multiplexer over SSH, providing persistent remote sessions.
A compatible version of WezTerm must be installed on the remote system.
Configuration
config . ssh_domains = {
{
name = 'my.server' ,
remote_address = '192.168.1.1' ,
username = 'wez' ,
-- Optional: specify SSH options
-- ssh_option = {
-- identityfile = '/home/user/.ssh/id_rsa',
-- },
},
}
Connecting
wezterm connect my.server
Auto-populated SSH Hosts
Starting with version 20230408-112425-69ae8472, WezTerm automatically populates domains from your ~/.ssh/config:
SSH:hostname - Regular SSH connection
SSHMUX:hostname - Multiplexing SSH domain
wezterm connect SSHMUX:my.server
# Or spawn in existing instance
wezterm cli spawn --domain-name SSHMUX:my.server
TLS Domains
TLS domains use encrypted TCP connections for remote multiplexing with bootstrap via SSH.
Client Configuration
config . tls_clients = {
{
name = 'server.name' ,
remote_address = 'server.hostname:8080' ,
bootstrap_via_ssh = 'server.hostname' ,
},
}
Server Configuration
config . tls_servers = {
{
bind_address = 'server.hostname:8080' ,
},
}
Connecting
wezterm connect server.name
After initial SSH bootstrap, WezTerm automatically reconnects using the obtained certificate, resuming sessions even after network interruptions.
Advanced Features
Moving Panes Between Tabs
Move a pane to a new tab:
config . keys = {
{
key = 'M' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . PaneSelect {
mode = 'MoveToNewTab' ,
},
},
}
Pane Selection Mode
Visually select panes:
config . keys = {
{
key = 'P' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . PaneSelect ,
},
}
Workspace Management
Organize windows into named workspaces:
config . keys = {
{
key = 'N' ,
mods = 'CTRL|SHIFT' ,
action = wezterm . action . SwitchToWorkspace {
name = 'default' ,
},
},
}
Best Practices
Use domains for persistent sessions
Set up Unix or SSH domains for work that needs to survive disconnections or client restarts.
Organize by project
Create separate tabs or workspaces for different projects to keep context organized.
Leverage shell integration
Use shell integration to spawn new panes in the current working directory automatically.
Customize keybindings
Configure keybindings that match your workflow and muscle memory.
Learn More