A cost cheatsheet for running a product cheaply: free-tier frontend hosting, serverless databases, …
Atuin Cheatsheet: Better Shell History Search Atuin Cheatsheet: Better Shell History Search

Summary
Every terminal user has done this: you ran the right command last Tuesday, on a different
machine, in a different directory, and now you are pressing the up arrow forty times hoping
to recognise it. Ctrl-R helps a little, but it only matches from the start of what you
type and shows you one result at a time.
Atuin fixes that. It replaces your shell history with a small database, then gives
Ctrl-R a real search screen — fuzzy matching, multiple results at once, and filters like
“only commands I ran in this folder”. Optionally it syncs that history between your
machines, encrypted so the server cannot read it.
Everything below was checked against Atuin 18.19.0 on Linux. If you live in a terminal all day, pair this with my tmux cheatsheet.
What it actually does, in plain words
Your shell normally keeps history in a plain text file — one command per line, and that is all it knows. Atuin keeps a SQLite database instead, and records extra facts about every command:
| Atuin remembers | Why you care |
|---|---|
| The command itself | Same as before |
| Which directory you ran it in | “What did I run in this repo?” |
| Whether it worked (exit code) | Skip the commands that failed |
| How long it took | Spot the slow ones |
| Which machine and session | Separate work laptop from server |
| When you ran it | “Sometime last week” becomes searchable |
That extra context is the whole point. A text file cannot answer “show me the commands I ran in this folder that actually succeeded” — a database can.
Expand your knowledge with Kubernetes Cheatsheet
~/.local/share/atuin/history.db and
that is it. If you ever want out, your history is sitting right there in a standard format.Install
# The official one-liner
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
Or through a package manager you already trust:
brew install atuin # macOS / Linuxbrew
cargo install atuin --locked # if you have Rust
paru -S atuin # Arch
Then wire it into your shell. This is the step people forget — installing the binary alone
does nothing to Ctrl-R:
echo 'eval "$(atuin init bash)"' >> ~/.bashrc # bash (also needs ble.sh or bash-preexec)
echo 'eval "$(atuin init zsh)"' >> ~/.zshrc # zsh
echo 'atuin init fish | source' >> ~/.config/fish/config.fish
Atuin supports bash, zsh, fish, nushell, xonsh and PowerShell.
Bring your existing history across — this reads your old history file and imports it, so you do not start from an empty screen:
atuin import auto # detects your current shell
atuin import bash # or name it explicitly
atuin import zsh
atuin import fish
atuin import also understands nu, xonsh, powershell, replxx, resh, and the
SQLite-backed variants zsh-hist-db, nu-hist-db and xonsh-sqlite.
Deepen your understanding in Bash CLI One-Liners Cheatsheet
~/.bash_history. If you decide Atuin is not for you, remove the eval
line from your shell config and everything is exactly as it was.The search screen
Press Ctrl-R (or the up arrow) and you get a full search UI instead of a one-line prompt.
| Key | What it does |
|---|---|
Ctrl-R | Open search — press again to cycle the filter mode |
Up arrow | Also opens search (rebindable) |
Enter | Run the selected command |
Tab | Put it on your prompt to edit before running |
Alt-1 … Alt-9 | Jump straight to result 1–9 |
Esc / Ctrl-C | Cancel |
Tab is the one to remember. Most of the time you want last week’s command nearly
verbatim — one flag different — and Tab hands it to you for editing rather than firing it
off immediately.
If you would rather keep your normal keys, turn the bindings off individually:
Explore this further in tmux Cheatsheet
atuin init bash --disable-ctrl-r # leave Ctrl-R alone
atuin init bash --disable-up-arrow # leave the up arrow alone
atuin init bash --disable-ai # leave "?" alone
Filter modes — the killer feature
Pressing Ctrl-R again while the search screen is open cycles through what you are
searching:
| Filter mode | Searches |
|---|---|
global | Everything, every machine (the default) |
host | Only this machine |
session | Only this terminal session |
directory | Only commands run in this folder |
workspace | The current git repo |
directory is the one that changes how you work. Land in a project you have not touched in
six months, hit Ctrl-R twice, and you are looking at exactly the commands you last ran
there — the right make target, the right docker compose invocation, the right
deploy script.
Set your usual default in the config, or override it per command:
Discover related concepts in MSK vs Kinesis Cheatsheet (Cost & When to Choose)
atuin search --filter-mode directory deploy
atuin search --filter-mode host kubectl
Search modes
How your typing is matched:
| Search mode | Behaviour |
|---|---|
fuzzy | Letters in order, gaps allowed — the default |
prefix | Must start with what you typed |
fulltext | Match anywhere in the command |
daemon-fuzzy | Fuzzy, served by the background daemon |
Fuzzy is why this feels fast. Typing kgp finds kubectl get pods — the letters just have
to appear in order, not next to each other:
atuin search --search-mode fuzzy "kgp"
2026-08-11 22:29:53 kubectl logs -f deploy/api 0s
2026-08-11 22:29:53 kubectl get pods -n prod 0s
Note that kubectl logs -f deploy/api matches too — it also contains k…g…p in order. Fuzzy
is generous on purpose; you narrow it by typing another letter or two.
Uncover more details in Bash CLI One-Liners Cheatsheet
Searching from the command line
The search screen is interactive, but atuin search works in scripts too:
atuin search kubectl # plain text search
atuin search --limit 5 docker # cap the results
atuin search --cwd /srv/app terraform # only in this directory
atuin search --exclude-cwd /tmp deploy # skip a directory
atuin search --exit 0 make # only commands that succeeded
atuin search --exclude-exit 0 make # only commands that FAILED
atuin search --after "1 day ago" aws # time-boxed
atuin search --before "2026-08-01" psql
atuin search -i # open the interactive UI
--exclude-exit 0 deserves a mention: it shows you only the commands that failed,
which is a surprisingly good way to reconstruct what went wrong during an incident.
Journey deeper into this topic with Bash CLI One-Liners Cheatsheet
Run atuin search in a script or CI job and you may get:
Error: Failed to find $ATUIN_SESSION in the environment.
Check that you have correctly set up your shell.
Nothing is broken. Atuin’s shell init exports ATUIN_SESSION in every interactive shell,
and non-interactive contexts never run it. Set one yourself:
export ATUIN_SESSION=$(atuin uuid)
atuin search kubectl
That is precisely what the atuin uuid subcommand exists for.
Stats
atuin stats # since the beginning
atuin stats last week
atuin stats --count 20 # top 20 instead of top 10
atuin stats --ngram-size 2 # count two-word commands together
--ngram-size 2 is the useful one: it counts git commit and git push separately instead
of lumping everything under git.
Enrich your learning with Docker Cheatsheet
Total commands: 10
Unique commands: 10
Sync between machines
Sync is optional. Atuin is perfectly good as a local-only tool, and if you never run
register nothing leaves your machine.
On your first machine:
atuin register -u <username> -e <email> # create an account
atuin sync # push history up
atuin key # PRINT YOUR ENCRYPTION KEY — save it
On every other machine:
atuin login -u <username> # it will ask for the key from above
atuin sync
atuin status # check it worked
atuin sync -f # force a full sync
atuin logout
atuin account delete # remove the account entirely
Your history is encrypted on your machine before upload, so the server stores something
it cannot read. That is good for privacy and unforgiving about key loss: without the key
from atuin key, a new machine cannot decrypt the history it downloads, and nobody can
recover it for you — the server genuinely does not have it.
Save it in your password manager the moment you register, not later.
Prefer not to trust anyone else’s server? Point Atuin at your own by setting
sync_address in the config — the server is open source and self-hostable.
Gain comprehensive insights from Bash CLI One-Liners Cheatsheet
Config worth changing
Lives at ~/.config/atuin/config.toml. Print the fully commented default with
atuin default-config.
search_mode = "fuzzy" # prefix | fulltext | fuzzy | daemon-fuzzy
filter_mode = "global" # global | host | session | directory | workspace
style = "compact" # "compact" or "full"
inline_height = 40 # 0 = full screen; small number = inline
show_preview = true # show the full command in a preview pane
enter_accept = true # Enter runs it; false = Enter only selects
keymap_mode = "emacs" # or "vim-normal" / "vim-insert"
auto_sync = true
sync_frequency = "5m"
sync_address = "https://api.atuin.sh" # change for a self-hosted server
workspaces = false # treat git repos as workspaces
secrets_filter = true # do not record things that look like secrets
update_check = true
Three worth a second look:
secrets_filter = true— on by default, and it tries to keep API keys and tokens out of the database. Leave it on.inline_height— a full-screen takeover on everyCtrl-Rannoys some people. Set something like20and the search appears inline instead.enter_accept— set tofalseif you wantEnterto put the command on your prompt rather than run it straight away. Safer if you tend to hit Enter reflexively.
To stop recording specific commands entirely, use the filters:
Master this concept through Bash Basics Cheatsheet
history_filter = ["^secret-cmd", "^curl .*token"] # by command pattern
cwd_filter = ["^/very/secret/directory"] # by directory
When something is wrong
atuin doctor # checks for common setup problems
atuin info # where the config and database live
atuin --version
atuin doctor first, always. It catches the usual suspects — shell integration not loaded,
a missing bash-preexec on bash, a stale daemon.
Delve into specifics at MSK vs Kinesis Cheatsheet (Cost & When to Choose)
Beyond history
Recent versions carry more than search. Worth knowing they exist:
atuin dotfiles # sync aliases and env vars alongside history
atuin scripts # save and run parameterised scripts
atuin kv # small key-value store, synced
atuin wrapped # a year-in-review of your terminal
atuin daemon # background daemon (experimental)
atuin mcp # expose history search to AI tools over MCP
That last one may interest you if you have been building with the
Model Context Protocol — atuin mcp runs a stdio MCP
server so an assistant can search your shell history as a tool.
Deepen your understanding in Bash CLI One-Liners Cheatsheet
Is it worth it?
If you use one machine and rarely repeat commands, plain Ctrl-R is fine and this is
overkill.
It earns its place when you have more than one machine, or when your commands are long
enough that retyping them is a real cost — kubectl invocations with four flags, docker run lines with six mounts, aws commands with ARNs in them. Directory filtering alone
saves the “what was the command for this project again?” round trip, several times a day.
Start local. Skip register entirely, run it for a week, and only set up sync once you have
caught yourself wishing your laptop knew what you typed on the server.
Deepen your understanding in Bash CLI One-Liners Cheatsheet
References
How many times a day do you press the up arrow more than five times in a row?
Similar Articles
Related Content
More from devops
Quick-reference tmux cheatsheet: sessions, windows, panes, copy mode, synchronize-panes, .tmux.conf …
Jenkins cheatsheet with declarative pipeline syntax, credentials, parameters, parallel stages, …
You Might Also Like
Quick-reference Bash basics cheatsheet: variables, parameter expansion, conditionals, loops, arrays, …
Quick-reference Ubuntu terminal cheatsheet: apt and dpkg, snap, systemd and journalctl, ufw, users …
Knowledge Quiz
Test your general knowledge with this quick quiz!
A set of multiple-choice questions to test your knowledge.
Take as much time as you need.
Your score will be shown at the end.
Question 1 of 5
Quiz Complete!
Your score: 0 out of 5
Loading next question...

