Zsh history can actually be smaller than bash’s by default, not larger.
Let’s see it in action. Imagine you’ve just SSH’d into a server.
% ls -l
total 8
drwxr-xr-x 2 user user 4096 Feb 15 10:00 dir1
drwxr-xr-x 2 user user 4096 Feb 15 10:00 dir2
% cd dir1
% ls -l
total 0
% git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
% cd ..
% ls -l
total 8
drwxr-xr-x 2 user user 4096 Feb 15 10:00 dir1
drwxr-xr-x 2 user user 4096 Feb 15 10:00 dir2
% pwd
/home/user
You want to find that git status command you just ran. Hit Ctrl+R and start typing git:
(reverse-i-search)`git': git status
There it is. Hit Enter to execute it, or the right arrow to edit it.
Now, let’s build the mental model. Zsh’s history is managed by a set of shell options and variables that control how commands are recorded, shared, and searched. The core idea is to make your command line more efficient and less repetitive.
First, the basics:
setopt HIST_IGNORE_DUPS: This is huge. It prevents consecutive identical commands from being added to your history. So if you accidentally hit Enter twice on the same command, only one gets saved.setopt HIST_IGNORE_ALL_DUPS: An even more aggressive version. It removes any previous occurrence of a command when you re-enter it. This keeps your history cleaner by default.setopt HIST_FIND_NO_DUPS: When you use reverse search (Ctrl+R), this option ensures that only the most recent match is shown. No more cycling through the same command from weeks ago.
These three options alone make zsh’s history feel much more intelligent out of the box.
Next, persistence: you want your history to survive across sessions.
setopt APPEND_HISTORY: Instead of overwriting the history file when you exit, this appends new commands. Crucial for not losing work.setopt INC_APPEND_HISTORY: This is the real magic for real-time sharing. It writes each command to the history file immediately after it’s executed. If you have multiple zsh sessions open, they can all see each other’s commands as they happen. This is incredibly useful when working on a shared server or managing multiple tasks.
Let’s configure this. In your .zshrc file, you’d typically find these lines:
# History settings
setopt HIST_IGNORE_DUPS
setopt HIST_IGNORE_ALL_DUPS
setopt HIST_FIND_NO_DUPS
setopt APPEND_HISTORY
setopt INC_APPEND_HISTORY
setopt SHARE_HISTORY # Sometimes used with INC_APPEND_HISTORY for explicit sharing
# Set the history file location and size
HISTFILE=~/.zsh_history
HISTSIZE=100000 # Number of commands to keep in memory
SAVEHIST=100000 # Number of commands to save to disk
HISTSIZE and SAVEHIST control the number of commands kept in memory and saved to disk, respectively. Setting them high ensures you don’t lose older commands. HISTFILE is just the path to the file.
Now, how do you leverage this?
- Reverse Search (
Ctrl+R): As shown, it’s your primary tool. Type a fragment, and zsh finds the most recent matching command. - Forward Search (
Ctrl+S): Less common, but useful. If your terminal is configured to disable it (often due toXOFFflow control), you might need tostty -ixonto re-enable it. - History Expansion: Zsh has powerful history expansion.
!lsruns the last command starting withls.!!runs the previous command.!$is the last argument of the previous command.!^is the first argument.!*is all arguments. For example, if you ranmkdir my_new_directoryand then want tocdinto it, you can just typecd !$and it expands tocd my_new_directory.
The one thing most people don’t know is that INC_APPEND_HISTORY and SHARE_HISTORY work together to allow real-time history sharing between shells. If you’re in two terminals, and you run a command in the first, the second terminal’s Ctrl+R search will immediately see it. This is incredibly powerful for collaborative work or simply keeping track of what you’ve done across different projects without manually syncing history files. It feels like magic until you see the options.
The next concept you’ll likely run into is managing history across different machines or for specific project contexts.