At some point last year I typed a sequence of six commands to do a database migration on a staging environment. It worked. I didn't write it down. Three weeks later I needed to do it again and I had three of the six steps in my memory and two variations of the other three that might have been right. I spent forty minutes reconstructing it.
This was the kind of thing that gets you to finally fix your shell history setup.
The Problem with Default History
Default shell history is almost useless for this kind of retrieval. Bash history is typically capped at 500 or 1000 entries, overwrites on new sessions, and offers only substring matching. Zsh is better but still configured by default for recency rather than retrieval.
The three things I needed: large history (100k+ entries), deduplication that preserves context, and actually good search.
The Setup
I use atuin now. It's a shell history replacement that stores history in a SQLite database, supports fuzzy search, shows per-session and per-directory context, and optionally syncs encrypted history across machines. I use the local-only mode — the sync feature exists but I haven't evaluated it for my threat model.
# atuin replaces ctrl-r and up-arrow
eval "$(atuin init zsh)"
# keep the original up-arrow for single-step recall
export ATUIN_NOBIND=false
The search interface uses ctrl-r and gives you a TUI with filtering, regex support, and the ability to filter by directory or session. The thing that matters most in practice: it's fast. History search shouldn't feel slow.
What I Annotate
atuin doesn't do annotation natively, but you can use a comment as a searchable label. Commands followed by # db-migration or # deploy-staging become retrievable by that tag. This is low-effort and high-return.
I also keep a ~/.local/notes/commands.md for multi-step sequences. Not a full runbook — just the sequence, the context, and the date. This is what I should have done with the migration sequence.
The Actual Lesson
Shell history is ambient documentation. You're generating it every working day. Most setups throw most of it away. The cost of fixing that is about twenty minutes of configuration. The return is every command you'll reconstruct without having to reconstruct it.
I have nine months of history in atuin now. I've used it to reconstruct three sequences I otherwise would have lost. That's already paid off.