Atuin
Sync, search and back up your shell history
Atuin replaces your shell history with a SQLite database and provides an optional self-hostable sync server for encrypted history sharing across machines. It adds full-text search and contextual filtering.
Key features
- Searchable shell history
- Self-hosted encrypted sync
- Cross-machine history
- SQLite-backed
Pros & cons
Strengths
- Encrypted history sync
- Powerful full-text search
- Optional self-host server
Trade-offs
- Replaces shell keybindings
- Shell integration required
Atuin replaces
Last reviewed Aug 26, 2026 · 839 words
Atuin's self-hosted sync server is optional, and I would tell most people to skip it for the first month. Install the client, run atuin import auto, press Ctrl-R, and the value is immediate: every command you have run, on this machine, searchable by text, directory, exit code and time, in a full-screen picker instead of a single line that matches from the end. That part needs no server, no account and about 10 MB on disk. The sync server is what you add when you want the same history on your laptop, your desktop and 3 servers, encrypted so the server never sees a command. It is small enough to run anywhere and it is the part this guide spends most of its words on, because it is the part with decisions.
The client changes two keybindings and that is the whole disruption
The catalogue's "replaces shell keybindings" is exactly right: after eval "$(atuin init zsh)" (or bash, fish, nushell), Ctrl-R opens Atuin's search and the up arrow opens it too, filtered to the current session. The up-arrow takeover is the one people object to, and it is one flag away: atuin init zsh --disable-up-arrow. Everything else in the shell is untouched. History still writes to the old file too, so uninstalling loses nothing.
The features that stick after a week are the filter modes. Tab cycles between global history, this host, this directory and this session, so "what did I run in this project's directory last month" is a 3-keystroke query. Exit codes are stored, which means you can find the version of a command that actually worked rather than the 4 attempts before it.
Secrets in history are the thing to think about before you sync
Shell history contains things you typed with a token in them. Locally that was already a risk; syncing it makes the copies multiply. Atuin encrypts history end-to-end with a key stored at ~/.local/share/atuin/key and never sent to the server, so a compromised server yields ciphertext. That handles the server. It does not handle the fact that your laptop's history now contains the curl -H "Authorization: Bearer ..." you ran on a server last year. Atuin's config has a history_filter list of regexes that stops matching commands from being recorded at all; put patterns for AWS_SECRET, token= and password in it before you turn on sync, not after. And store the encryption key itself somewhere durable; atuin key prints it, and Vaultwarden is where mine lives, because losing it means losing every synced record.
The server is one container and a Postgres
The official image runs the server with 3 settings that matter:
services:
atuin:
image: ghcr.io/atuinsh/atuin:latest
command: server start
environment:
- ATUIN_HOST=0.0.0.0
- ATUIN_PORT=8888
- ATUIN_OPEN_REGISTRATION=true # false once your account exists
- ATUIN_DB_URI=postgres://atuin:atuin@postgres/atuin
ports:
- "8888:8888"
depends_on:
- postgres
restart: unless-stopped
Turn registration off after atuin register on your first machine, then atuin login everywhere else with the same key. Set sync_address = "https://history.example.com" in each client's ~/.config/atuin/config.toml and put Caddy in front for TLS. Ram usage sits well inside the 128 MB the catalogue lists; the server is doing nothing but storing encrypted blobs and serving them back. Exposing it publicly is defensible given the encryption, but I keep mine reachable only over Tailscale, because there is no reason for a shell history server to answer the internet.
Where it sits alongside the rest of a terminal setup
Atuin belongs in the same dotfiles as Delta and the rest of the single-binary Rust tools: install once, configure with 5 lines, forget. The difference is that Atuin has state worth caring about. The SQLite database at ~/.local/share/atuin/history.db is the source of truth per machine, and the server holds the encrypted union. If you have ever lost a decade of .zsh_history to a full disk or a botched migration, that union is the feature: a new machine runs atuin login and has everything within a minute.
The hosted sync at atuin.sh is free and runs the same encryption, so self-hosting is about ownership rather than security. Choose it if you already run a server and want the history to live where your other data does.
What I'd do
Install the client today with the up-arrow override left in place, add 3 or 4 history_filter patterns, and use it for a month without sync. Then, if you touch more than one machine regularly, run the container above behind Caddy on the box that already runs your other small services, close registration, and copy the key into your password manager. Total commitment is one container, one Postgres, and a config file you edit once. For a tool that fixes a 30-year-old annoyance, that is a very small bill.
Similar developer tools & git apps
Excalidraw
Developer Tools & GitVirtual hand-drawn style whiteboard
Replaces Miro
lazygit
Developer Tools & GitSimple terminal UI for Git commands
Replaces GitKraken, Sourcetree
Hoppscotch
Developer Tools & GitOpen-source API development ecosystem
Replaces Postman, Insomnia
json-server
Developer Tools & GitFull fake REST API from a JSON file in seconds
Replaces Mockoon, Postman Mock
Strapi
Developer Tools & GitLeading open-source headless CMS
Replaces Contentful
NocoDB
Developer Tools & GitOpen-source Airtable alternative
Replaces Airtable