Shell history is one of the few genuinely bad defaults left on a Linux machine. It is a flat text file, written when the shell exits, so two terminals open at once overwrite each other’s additions. It truncates at a few thousand lines. It records no directory, no exit code, no duration, and no machine. And Ctrl+R searches it with a substring match and no way to narrow anything down.
Atuin replaces the file with a SQLite database, records the context, and gives Ctrl+R a real interface.
Is it worth your time? If you spend hours a day in a terminal and regularly hunt for a command you typed last month, yes — the searchable history alone pays for the install, and the sync between machines is the part people end up unable to give up.
The real no case: it replaces a keybinding you have used for twenty years, and for a while that friction is real. If you mostly use a terminal occasionally, or work on machines you cannot install things on, plain Ctrl+R plus a properly configured HISTSIZE covers most of the benefit for none of the change. It is also another moving part in your shell startup — if a broken shell on a remote box would be a serious problem, weigh that.
What it actually is
A binary that hooks into your shell’s pre-execute and post-execute points, writing each command to a local SQLite database along with the working directory, the exit code, how long it took, the hostname and the session. Nothing leaves the machine unless you separately turn on sync.
It binds Ctrl+R — and, by default, the up arrow — to a full-screen search over that database. Officially supported shells are bash, zsh, fish, nushell, xonsh and PowerShell.
Installing
# the project's installer
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
# or from a package manager
sudo pacman -S atuin
brew install atuin
cargo install atuinThen add the shell hook. For zsh and bash:
# ~/.zshrc
eval "$(atuin init zsh)"
# ~/.bashrc - needs ble.sh or bash-preexec; the installer sets this up
eval "$(atuin init bash)"Import what you already have, once:
atuin import autoBash is the fiddly one — it has no native pre-execute hook, so Atuin relies on bash-preexec or ble.sh. The official installer handles it; a manual install that skips that step gives you a working binary that records nothing.
The 20% you will use
Press Ctrl+R and type. Inside the search interface:
| Key | Does |
|---|---|
Ctrl+R again | Cycle the filter: this session → this directory → this host → everything |
Tab | Put the command on the prompt for editing rather than running it |
Enter | Run it immediately |
Ctrl+O | Inspect the entry — when, where, exit code, duration |
Esc | Leave without doing anything |
That filter cycle is the feature. “The thing I ran in this directory last week” is a question plain Ctrl+R cannot answer at all, and it is how you actually remember commands.
Prefer Tab to Enter. Pulling a half-remembered command onto the prompt and reading it before running is a good habit generally, and it matters more here because the search is so good at surfacing old, destructive one-liners you had forgotten about.
From the shell rather than the interface:
atuin search docker # plain search
atuin search --cwd . rsync # only in this directory
atuin search --exit 0 psql # only the ones that worked
atuin search --after '2026-08-01' --before '2026-08-15' deploy
atuin stats # what you actually run all day--exit 0 is quietly excellent: it filters out every typo and failed attempt, leaving only commands that did something.
Sync, and what it does with your data
Sync is opt-in and off until you register. When you do enable it, your history is encrypted on your machine before it is uploaded — the server stores ciphertext and cannot read your commands.
atuin register -u you -e you@example.com
atuin key # PRINT THIS AND STORE IT SAFELY
atuin sync
# on the second machine
atuin login -u you # asks for the key from above
atuin syncThe key is generated locally and cannot be recovered. Lose it and your synced history is unreadable, permanently, by you and by anyone else — there is no reset link, because the server never had the means to decrypt anything. Put it in your password manager before you do anything else.
If you would rather not involve a hosted service at all, the sync server is open source and self-hostable; the docs cover Docker, Kubernetes and systemd deployments. That is the right choice for a work machine whose history includes hostnames and internal tooling you would rather not upload anywhere, encrypted or not.
Beyond history, Atuin can also sync shell aliases and environment variables, though that is still opt-in and clearly a work in progress — enable it deliberately rather than expecting it to be on.
Keeping secrets out of it
A searchable, permanent, synced history is a much better place for a leaked credential to live than a file that truncates every few thousand lines. Atuin filters some obvious patterns by default; add your own:
# ~/.config/atuin/config.toml
history_filter = [
"^curl.*-u ",
"^export .*(TOKEN|SECRET|PASSWORD|KEY)=",
"^mysql .*-p",
]
cwd_filter = ["^/home/me/private"]And to remove something already recorded:
atuin search --delete --search-mode full-text 'AWS_SECRET'The habit worth keeping regardless: put secrets in environment files or a password manager and reference them, rather than typing them on a command line where several tools will remember them.
Configuration worth setting
# ~/.config/atuin/config.toml
# stop it taking over the up arrow
keymap_mode = "auto"
# start filtered to this directory rather than everything
filter_mode_shell_up_key_binding = "directory"
# inline rather than full screen
style = "compact"
inline_height = 20
# fuzzy rather than prefix matching
search_mode = "fuzzy"
update_check = false# if the up arrow is the part you dislike
eval "$(atuin init zsh --disable-up-arrow)"That last one is the single most common adjustment. The full-screen search on Ctrl+R is a clear win; hijacking the up arrow, which people use reflexively to get the previous command, is the part that annoys them.
Gotchas
| Symptom | Cause | Fix |
|---|---|---|
| Nothing is being recorded in bash | bash-preexec not loaded | Use the official installer, or load it before atuin init |
| Up arrow behaves unexpectedly | Atuin took the binding | --disable-up-arrow |
| Old history missing | Never imported | atuin import auto |
| Sync silently doing nothing | Not logged in on this machine | atuin status |
| Cannot log in on a new machine | The key, not the password, is what decrypts | Retrieve the key from where you stored it |
| A secret is in your history | Typed on a command line | Delete it, then add a history_filter |
| Shell startup feels slower | One more thing initialising | Small, but real; measure before blaming it |
| Something is wrong and it is not obvious what | — | atuin doctor, which is what to attach to a bug report |
Where it does not belong
- Shared or service accounts. A per-person history synced to a personal account has no business on a shared login.
- Machines you touch once. A jump host or a container is not worth the shell startup change.
- Anywhere the shell must be minimal — rescue environments, initramfs, a recovery shell. Keep the plain path working.
- As documentation. A command you will need again in six months belongs in a script or a README, not in a history search.
Also worth knowing: the project has been adding AI features to the CLI, currently free while in testing, and there is a separate Atuin Desktop product for runbooks. Neither is required — the history tool works exactly as described above without touching any of it.
Quick reference
Ctrl+R # search; press again to cycle the filter
Tab # edit rather than run
Ctrl+O # inspect the entry
atuin import auto # bring in existing history
atuin search --cwd . rsync # search this directory
atuin search --exit 0 psql # only commands that succeeded
atuin stats # what you actually run
atuin key # your encryption key - store it
atuin status # sync state
atuin doctor # diagnostics for a bug reportRelated reading
- Shell history — what you are replacing, and how to configure it properly first
- fzf — the other way to make
Ctrl+Ruseful - What a shell actually is — where these hooks attach
- zoxide vs cd — the same idea applied to directories
- tmux vs screen — the other half of living in a terminal
