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 atuin

Then 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 auto

Bash 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:

KeyDoes
Ctrl+R againCycle the filter: this session → this directory → this host → everything
TabPut the command on the prompt for editing rather than running it
EnterRun it immediately
Ctrl+OInspect the entry — when, where, exit code, duration
EscLeave 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 sync

The 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

SymptomCauseFix
Nothing is being recorded in bashbash-preexec not loadedUse the official installer, or load it before atuin init
Up arrow behaves unexpectedlyAtuin took the binding--disable-up-arrow
Old history missingNever importedatuin import auto
Sync silently doing nothingNot logged in on this machineatuin status
Cannot log in on a new machineThe key, not the password, is what decryptsRetrieve the key from where you stored it
A secret is in your historyTyped on a command lineDelete it, then add a history_filter
Shell startup feels slowerOne more thing initialisingSmall, but real; measure before blaming it
Something is wrong and it is not obvious whatatuin 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 report

Related reading

Leave a Reply

Your email address will not be published. Required fields are marked *