> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/wezterm/wezterm/llms.txt
> Use this file to discover all available pages before exploring further.

# Multiplexing

> Understanding WezTerm's multiplexing capabilities with tabs, panes, windows, and domains

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.

<Note>
  Multiplexing is an actively evolving feature in WezTerm. Your feedback and suggestions are welcomed!
</Note>

## 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](https://github.com/tmux/tmux/wiki) or [screen](https://en.wikipedia.org/wiki/GNU_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

<Steps>
  <Step title="Panes">
    Panes are individual terminal sessions within a tab. You can split a tab horizontally or vertically to create multiple panes.
  </Step>

  <Step title="Tabs">
    Tabs contain one or more panes. Each tab can be split independently and has its own title.
  </Step>

  <Step title="Windows">
    Windows are separate operating system windows, each containing tabs. Multiple windows allow you to use multiple monitors effectively.
  </Step>

  <Step title="Domains">
    Domains are distinct sets of tabs and panes. Domains can be local or remote (via SSH, Unix socket, or TLS).
  </Step>
</Steps>

## Working with Panes

Panes allow you to divide a single tab into multiple terminal sessions.

### Creating Panes

<Accordion title="Split Horizontally">
  Default: `Ctrl+Shift+Alt+%` (or `Cmd+Shift+%` on macOS)

  ```lua theme={null}
  config.keys = {
    {
      key = '%',
      mods = 'CTRL|SHIFT|ALT',
      action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' },
    },
  }
  ```
</Accordion>

<Accordion title="Split Vertically">
  Default: `Ctrl+Shift+Alt+"` (or `Cmd+Shift+"` on macOS)

  ```lua theme={null}
  config.keys = {
    {
      key = '"',
      mods = 'CTRL|SHIFT|ALT',
      action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' },
    },
  }
  ```
</Accordion>

### Navigating Between Panes

Move focus between panes using directional keys:

```lua theme={null}
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:

```lua theme={null}
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 },
  },
}
```

<Tip>
  You can zoom a pane to full-screen temporarily while keeping other panes in the background. Use `TogglePaneZoomState` to zoom/unzoom.
</Tip>

## Working with Tabs

Tabs help you organize multiple terminal sessions without cluttering your screen.

### Creating and Managing Tabs

```lua theme={null}
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):

```lua theme={null}
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:

```bash theme={null}
# Using wezterm CLI
wezterm cli set-tab-title "My Project"
```

Or configure dynamic titles based on the running process:

```lua theme={null}
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.

<Info>
  Unix domains work on all platforms, including Windows (using named pipes), and are perfect for connecting Windows to WSL.
</Info>

#### Basic Configuration

```lua theme={null}
config.unix_domains = {
  {
    name = 'unix',
  },
}

-- Auto-connect on startup
config.default_gui_startup_args = { 'connect', 'unix' }
```

#### Manual Connection

```bash theme={null}
wezterm connect unix
```

#### Advanced Configuration

```lua theme={null}
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

<Warning>
  This only works with WSL 1. WSL 2 doesn't support AF\_UNIX interop between Windows and Linux.
</Warning>

**Inside WSL:**

```lua theme={null}
config.unix_domains = {
  {
    name = 'wsl',
    socket_path = '/mnt/c/Users/USERNAME/.local/share/wezterm/sock',
    skip_permissions_check = true,
  },
}
```

**On Windows:**

```lua theme={null}
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.

<Note>
  A compatible version of WezTerm must be installed on the remote system.
</Note>

#### Configuration

```lua theme={null}
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

```bash theme={null}
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

```bash theme={null}
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

```lua theme={null}
config.tls_clients = {
  {
    name = 'server.name',
    remote_address = 'server.hostname:8080',
    bootstrap_via_ssh = 'server.hostname',
  },
}
```

#### Server Configuration

```lua theme={null}
config.tls_servers = {
  {
    bind_address = 'server.hostname:8080',
  },
}
```

#### Connecting

```bash theme={null}
wezterm connect server.name
```

<Info>
  After initial SSH bootstrap, WezTerm automatically reconnects using the obtained certificate, resuming sessions even after network interruptions.
</Info>

## Advanced Features

### Moving Panes Between Tabs

Move a pane to a new tab:

```lua theme={null}
config.keys = {
  {
    key = 'M',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.PaneSelect {
      mode = 'MoveToNewTab',
    },
  },
}
```

### Pane Selection Mode

Visually select panes:

```lua theme={null}
config.keys = {
  {
    key = 'P',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.PaneSelect,
  },
}
```

### Workspace Management

Organize windows into named workspaces:

```lua theme={null}
config.keys = {
  {
    key = 'N',
    mods = 'CTRL|SHIFT',
    action = wezterm.action.SwitchToWorkspace {
      name = 'default',
    },
  },
}
```

## Best Practices

<Steps>
  <Step title="Use domains for persistent sessions">
    Set up Unix or SSH domains for work that needs to survive disconnections or client restarts.
  </Step>

  <Step title="Organize by project">
    Create separate tabs or workspaces for different projects to keep context organized.
  </Step>

  <Step title="Leverage shell integration">
    Use shell integration to spawn new panes in the current working directory automatically.
  </Step>

  <Step title="Customize keybindings">
    Configure keybindings that match your workflow and muscle memory.
  </Step>
</Steps>

## Learn More

* [Terminal Basics](/concepts/terminal-basics) - Understand PTYs and how terminals work
* [Shell Integration](/concepts/shell-integration) - Enhanced features with OSC sequences
* [Key Bindings](https://wezfurlong.org/wezterm/config/keys.html) - Complete keybinding reference
