Zsh shared history is a game-changer for anyone who uses multiple terminals.

Let’s see it in action. Imagine you’re in one terminal window, and you run a command:

% ls -l /etc/nginx/sites-available

Now, open a new terminal window. If shared history is set up correctly, that same command should immediately be available if you start typing ls -l. Pressing the up arrow should also bring it up.

The core problem Zsh shared history solves is that by default, each Zsh session maintains its own independent command history. When a session ends, its history is saved to a file (usually ~/.zsh_history). If you have multiple shells open, the last one to exit "wins," overwriting the history from all other sessions. This means you lose commands entered in shells that were still open when another exited.

To enable shared history, you need to configure a few options in your ~/.zshrc file. The key is to tell Zsh to append to the history file rather than overwrite it, and to read the history file back into memory at the start of each session.

Here’s the essential configuration:

# ~/.zshrc

# Append to the history file, don't overwrite it
setopt APPEND_HISTORY

# Save history when the shell exits
setopt INC_APPEND_HISTORY

# Read history from the file at the start of the session
setopt SHARE_HISTORY

# Set the history file location
HISTFILE=~/.zsh_history

# Set the number of lines of history to keep in memory and in the file
HISTSIZE=10000
SAVEHIST=10000

Let’s break down what each of these does:

  • setopt APPEND_HISTORY: This is crucial. It ensures that when you exit a shell, its history is appended to the HISTFILE instead of overwriting it. Without this, only the last shell’s history would be saved.
  • setopt INC_APPEND_HISTORY: This option writes each command to the history file immediately after it’s executed, rather than waiting for the shell to exit. This is what makes history appear in other shells while they are running, not just after they’ve restarted.
  • setopt SHARE_HISTORY: This tells Zsh to read the contents of HISTFILE into the current shell’s history when the shell starts. Combined with INC_APPEND_HISTORY, this creates the shared experience.
  • HISTFILE=~/.zsh_history: This explicitly defines the path to your history file. It’s good practice to set this, though ~/.zsh_history is the default.
  • HISTSIZE=10000 and SAVEHIST=10000: These control the maximum number of commands stored in memory (HISTSIZE) and the maximum number of commands saved to HISTFILE (SAVEHIST). Setting them to a high number ensures you don’t lose older commands.

With this setup, when you run a command in one shell, INC_APPEND_HISTORY writes it to ~/.zsh_history. When another Zsh shell starts, SHARE_HISTORY reads that updated ~/.zsh_history file into its memory. APPEND_HISTORY ensures that when the first shell eventually exits, its history is added to the file without losing what was already there from other sessions.

The magic is that INC_APPEND_HISTORY and SHARE_HISTORY work together. INC_APPEND_HISTORY makes history available immediately to other shells. SHARE_HISTORY then picks it up on their next startup or when they refresh. The combination is what gives you that seamless experience.

What most people miss is that INC_APPEND_HISTORY is the real enabler for live sharing. Without it, you’d only see history updates after restarting shells. It causes each command to be written to disk as soon as it’s executed, making it available for other shells to read.

The next thing you’ll likely want to explore is how to exclude certain commands from your history, or how to manage duplicate entries.

Want structured learning?

Take the full Zsh course →