Atuin: Magical Shell History with Sync
Atuin: Magical Shell History with Sync

Your shell history is one of the most undervalued tools in your development workflow. Every command you run is a piece of institutional knowledge -- how you deployed that service, the exact flags you passed to ffmpeg three months ago, the database query that fixed that production incident. Yet the default shell history in bash and zsh is barely functional: a flat text file with a limited line count, no context, and no way to search across machines.
Atuin replaces your shell history entirely. It stores every command in a SQLite database with full context -- the working directory, hostname, session, exit code, and duration. It gives you a beautiful interactive search UI. And if you opt in, it syncs your history across every machine you work on, end-to-end encrypted.
Why Replace Shell History?
The default shell history has several fundamental problems that Atuin solves:
Limited storage: Bash defaults to 500 lines. Zsh is configurable but still file-based. Atuin stores unlimited history in SQLite with no practical ceiling.
No context: Default history records the command but not where you ran it, how long it took, or whether it succeeded. Atuin records working directory, exit code, duration, hostname, and session ID.
No cross-machine access: If you SSH into a server and run a command, that command lives only on that server. Atuin's sync feature makes your history available everywhere.
Poor search: Ctrl+R in bash gives you reverse incremental search through a flat list. Atuin gives you a full-screen interactive search with fuzzy matching, filtering by directory or host, and time-based ordering.
No statistics: Ever wondered which commands you run most? How much time you spend waiting for builds? Atuin tracks all of this.
Installation
Atuin supports bash, zsh, fish, and nushell on Linux and macOS.
Quick Install (Recommended)
curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh
This installs the binary and provides instructions for shell integration.
Package Managers
# macOS
brew install atuin
# Arch Linux
pacman -S atuin
# Nix
nix-env -iA nixpkgs.atuin
# Cargo
cargo install atuin
Shell Integration
After installation, add Atuin to your shell configuration.
Bash (add to ~/.bashrc):
eval "$(atuin init bash)"
Zsh (add to ~/.zshrc):
eval "$(atuin init zsh)"
Fish (add to ~/.config/fish/config.fish):
atuin init fish | source
Nushell (add to config.nu):
source ~/.local/share/atuin/init.nu
Restart your shell or source the configuration file, and Atuin is ready.
Basic Usage
Interactive Search
Press Ctrl+R (or your configured keybinding) to open Atuin's interactive search. You will see a full-screen interface with your recent commands, ordered by time. Start typing to filter:
> docker compose
[2026-02-14 10:23] docker compose up -d
[2026-02-14 09:15] docker compose logs -f api
[2026-02-13 16:42] docker compose down
[2026-02-13 14:30] docker compose build --no-cache
Use arrow keys to navigate, Enter to select and execute, and Tab to select and edit before running.
Search Modes
Atuin supports several search modes that change how your input matches against history:
Fuzzy (default): Matches commands containing all your search terms in any order. Typing docker build matches docker compose build --no-cache.
Prefix: Matches commands that start with your input. Typing git matches git push but not sudo git push.
Full text: Matches exact substrings. Typing compose up matches docker compose up -d but not docker compose down.
Regex: Full regular expression matching. Typing git (push|pull) matches both push and pull commands.
Switch between modes while searching with Ctrl+R or configure your default in the config file.
Search Filters
One of Atuin's killer features is contextual filtering. You can narrow searches by:
Current directory: Only show commands run in your current working directory. Incredibly useful when you are in a project and want to remember what you did there last week.
Current session: Only show commands from your current terminal session.
Host: Only show commands from the current machine (relevant when sync is enabled).
Global: Search across all machines, all directories, all time.
Toggle between these filter modes with Ctrl+S during search, or set your preferred default.
Configuration
Atuin's configuration lives at ~/.config/atuin/config.toml. Here is a well-tuned configuration:
## Where to store the database
db_path = "~/.local/share/atuin/history.db"
## How to search by default
search_mode = "fuzzy"
## What filter to use by default
filter_mode = "global"
## Filter mode when a search prefix is used
filter_mode_shell_up_key_binding = "directory"
## Style of the search UI
style = "compact"
## Show a preview of the selected command
show_preview = true
## Maximum preview height in lines
max_preview_height = 4
## Inline height (number of results to show)
inline_height = 20
## Show help bar at the bottom
show_help = true
## Show tabs for filter modes
show_tabs = true
## Enable up arrow integration
enter_accept = true
## Key binding style (auto, emacs, vim)
keymap_mode = "auto"
## Cursor style for vim mode
keymap_cursor = { emacs = "blink-block", vim_insert = "blink-block", vim_normal = "steady-block" }
## History filter - commands matching these regexes won't be recorded
history_filter = [
"^secret-tool",
"^export.*TOKEN",
"^export.*KEY",
"^export.*SECRET",
"^export.*PASSWORD",
]
## Control how much context is recorded
cwd_filter = []
Key Configuration Options Explained
search_mode: Set to fuzzy for the most forgiving search experience. Switch to prefix if you prefer more precise matching.
filter_mode: Set to global if you want to search all history by default, or directory to default to showing only commands from the current directory.
filter_mode_shell_up_key_binding: This controls what happens when you press the up arrow. Setting it to directory means pressing up arrow cycles through commands you have previously run in this specific directory -- extremely useful.
history_filter: A list of regex patterns for commands that should never be recorded. Use this to prevent secrets, tokens, and passwords from entering your history database.
style: Choose between compact (more results visible), full (one command per card with metadata), and auto.
Syncing Across Machines
Atuin's sync feature lets you access your command history from any machine. All data is end-to-end encrypted before leaving your machine -- the sync server never sees your commands.
Using the Official Sync Server
# Register an account
atuin register -u your_username -e [email protected] -p your_password
# Log in (on additional machines)
atuin login -u your_username -p your_password
# Sync manually
atuin sync
# Check sync status
atuin status
After login, Atuin syncs automatically in the background. New commands are uploaded and history from other machines is downloaded.
Self-Hosting the Sync Server
If you prefer to keep your encrypted history on your own infrastructure, Atuin provides a self-hostable server:
# Using Docker
docker run -d \
--name atuin-server \
-p 8888:8888 \
-v atuin-data:/config \
ghcr.io/atuinsh/atuin:latest \
server start
# Point your client at it
# In ~/.config/atuin/config.toml:
# sync_address = "https://atuin.yourdomain.com"
The self-hosted server is a lightweight Rust binary that stores encrypted blobs. It cannot decrypt your history -- it simply stores and serves the encrypted data.
Encryption Details
Atuin uses XChaCha20Poly1305 for encryption. Your encryption key is derived from your password using Argon2id. The server stores only encrypted blobs and cannot read your commands. Even if the server is compromised, your history remains private.
Statistics
Atuin tracks rich metadata about every command, letting you analyze your shell usage patterns:
# Show general statistics
atuin stats
# Show stats for the last 7 days
atuin stats --period 7d
# Show stats for the last month
atuin stats --period 30d
The output shows your most-used commands, total commands run, and average command duration. Example output:
Total commands: 12,847
Unique commands: 3,291
Average per day: 43
Top 10 commands:
git 2,841 (22.1%)
cd 1,456 (11.3%)
ls 1,102 (8.6%)
docker 987 (7.7%)
bun 834 (6.5%)
vim 612 (4.8%)
cat 445 (3.5%)
grep 398 (3.1%)
ssh 312 (2.4%)
curl 287 (2.2%)
This is genuinely useful for understanding your workflow patterns and identifying commands you should alias or optimize.
Importing Existing History
When you first set up Atuin, you probably want to import your existing shell history:
# Auto-detect and import
atuin import auto
# Import from specific shells
atuin import bash
atuin import zsh
atuin import zsh-hist-db
atuin import fish
The import process reads your existing history file and loads it into Atuin's SQLite database. Context like working directory and exit code won't be available for imported commands (that data was never recorded), but the commands themselves and their timestamps are preserved.
Advanced Usage
Deleting History Entries
Sometimes you need to remove a command from history (accidentally typed a password as a command, for example):
# Delete a specific entry by ID
atuin search --delete --search-mode prefix "accidentally typed password"
# Delete interactively -- search, select, and delete
atuin search --delete
Custom Key Bindings
If Ctrl+R conflicts with another tool, you can customize the key binding in your shell configuration:
Zsh:
# Use Ctrl+F for Atuin search instead of Ctrl+R
eval "$(atuin init zsh --disable-ctrl-r)"
bindkey '^f' atuin-search
Bash:
eval "$(atuin init bash --disable-ctrl-r)"
bind -x '"\C-f": __atuin_history'
Scripting with Atuin
Atuin's history database is queryable, making it useful for scripting:
# List last 10 commands as JSON
atuin history list --format json | head -10
# Search programmatically
atuin search --search-mode prefix "docker" --format "{time}\t{command}"
# Get history for a specific directory
atuin search --cwd /home/user/project --format "{command}"
Daemon Mode
Atuin can run a background daemon for faster performance and more reliable sync:
# Start the daemon
atuin daemon
# The daemon handles sync in the background
# and provides faster search via Unix socket
With the daemon running, search operations are faster because the database connection is persistent rather than opened fresh for each search.
Migrating from Other History Tools
From McFly
McFly is another intelligent history search tool. To migrate:
- Install Atuin and initialize it
- Import your shell history:
atuin import auto - Remove McFly from your shell configuration
- McFly's neural network ranking is replaced by Atuin's configurable search modes
From fzf History Search
If you use fzf for Ctrl+R history search:
- Install Atuin
- Remove the fzf history key binding from your shell config
- Add Atuin's init script
- Your fzf configuration for other uses (file search, etc.) remains unaffected
Troubleshooting
Atuin Not Recording Commands
Check that the init script is sourced after other shell plugins. Some plugins override key bindings. Place eval "$(atuin init zsh)" at the very end of your .zshrc.
Sync Not Working
# Check your login status
atuin status
# Force a sync
atuin sync -f
# Check the sync server address
grep sync_address ~/.config/atuin/config.toml
Large Database Size
If your database grows very large over time:
# Check database size
ls -lh ~/.local/share/atuin/history.db
# Atuin automatically optimizes, but you can run:
atuin doctor
Slow Search
Enable the daemon for better performance. Also consider using compact style and reducing inline_height if you have a very large history.
Tips for Getting the Most from Atuin
Set directory-based up-arrow filtering: This single setting (filter_mode_shell_up_key_binding = "directory") transforms the up arrow key. In a project directory, pressing up shows only commands you ran in that project. This alone is worth the installation.
Use history_filter aggressively: Add patterns for any command that might contain secrets. Better to miss a few commands in history than to sync a password across machines.
Review your stats weekly: Understanding which commands you use most helps you identify candidates for aliases, scripts, or workflow improvements.
Self-host if you can: While the official sync server is trustworthy and the encryption is solid, self-hosting gives you complete control. The server is lightweight enough to run on a Raspberry Pi.
Combine with other terminal tools: Atuin pairs well with tools like starship (prompt), zoxide (directory jumping), and eza (file listing) for a fully modernized terminal experience.
Conclusion
Atuin turns your shell history from a forgettable text file into a searchable, synchronized, contextual database of everything you have ever done in a terminal. The interactive search is faster and more powerful than any default shell history. Cross-machine sync means you never lose a command. And the statistics give you genuine insights into how you work. For anyone who spends significant time in the terminal, Atuin is one of those tools that, once installed, you wonder how you ever worked without.