mrkeyoor.com_
Wed 30 Sept 20:34 UTC
Dev Toolsevaluationupdated 26 Aug 2026

atuin review

Atuin replaces flat shell history with a searchable SQLite database that records the command, time, working directory, exit status, duration, host, and session. It can stay entirely local or synchronize end-to-end encrypted history through Atuin Cloud or a server you operate.

+62stars / 7d
Verdict

Our Atuin run passed 297 of 300 tests before three server tests hit connection resets, so commit 824c871 is close to clean but still needs that integration failure understood. The local search and metadata are useful even with sync disabled, which makes Atuin easier to recommend than a cloud-only history service. Review installer changes, exclude sensitive commands, back up the encryption key, and qualify the exact shell integration before rolling it across a team.

We ran it

Lab card: what happened when we ran atuinScreenshot of atuin (atuin.sh)
Install✓ · 20s677 packages
Build✓ · 234s
Tests✗ · 274s297 passed · 3 failed of 300 (cargo test)
Repo590 files~87,868 lines of source · 8.4 MB · 13 CI workflows · Dockerfile

Answers from our run

Does atuin build from source?

Dependencies installed in 20 seconds (677 packages), and the build succeeded in 234 seconds. We cloned commit 824c871 into a clean Debian container with 3 CPUs and no project-specific setup.

Do atuin's tests pass?

Not all of them: 297 of 300 passed and 3 failed when we ran the project's own test command (cargo test). Some failures need services or credentials a bare container does not have.

Who should not use atuin?

Anyone who cannot keep a recovery key safe: the sync guide says lost encryption keys cannot be recovered by the Atuin team.

What are the alternatives to atuin?

Hishtory, fzf, zsh-histdb. Our Atuin run passed 297 of 300 tests before three server tests hit connection resets, so commit 824c871 is close to clean but still needs that integration failure understood.

Setup4/5Quick installer; shell hooks and sync recovery need attention
Docs5/5Clear shell, sync, import, server, backup, and uninstall guides
Community5/5Same-day release, push, fixes, and active issue discussion
Maturity4/5Developed since 2020, with three failed server tests in our run

Discussed on

  1. hnAtuin replaces your existing shell history with a SQLite database551 points
  2. hnAtuin’s New Runbook Execution Engine138 points
  3. hnAtuin replaces your existing shell history with a SQLite database108 points
  4. hnShow HN: Atuin, improved shell history with multi-machine sync48 points
  5. hnAtuin desktop: Runbooks that run37 points

Who it’s for

Developers who regularly search old commands and need more context than a shell history file keeps.
People working across several machines who will safeguard a separate encryption key for synchronized history.
Terminal users on zsh, bash, fish, Nushell, xonsh, or PowerShell who can review changes to their shell startup files.
Teams willing to self-host a small sync service with SQLite or PostgreSQL when cloud sync is unsuitable.

Who it’s NOT for

Anyone who cannot keep a recovery key safe: the sync guide says lost encryption keys cannot be recovered by the Atuin team.
Bash users expecting every command boundary and ignorespace behavior to remain identical: the docs list bash-preexec limitations for subshells, functions, durations, exit status, and the original history file.
People who do not want an installer changing shell and agent configuration: an open report says the installer added hooks for coding agents without asking and provided no hook-specific uninstall command.
Machines with many concurrent shells where local database growth cannot be watched: an open 18.20.0 report describes an unbounded SQLite WAL, with a fix still in an open pull request.
Organizations that prohibit recording working directories, hostnames, durations, or commands containing secrets unless they define exclusions and retention first.

Setup reality

Our Cargo dependency install succeeded in 20 seconds with 677 packages, and the build succeeded in 234 seconds. Tests ran for 274 seconds, then failed: 297 passed and 3 failed out of 300. change_password, multi_user_test, and registration ended after a client connection was reset by its peer; the tail does not show which side closed it or why.

The installer adds the binary and shell integration, then can import existing history and create a sync account. Sync needs a username, password, server address, and a separately stored encryption key. Local-only use needs none of those. Bash may also load ble.sh or bash-preexec.

Self-hosting adds atuin-server, a writable SQLite database or PostgreSQL 14 or newer, persistent storage, TLS through a reverse proxy, backups, and client sync_address configuration. Pin a tagged image because the docs warn that upgrades can require manual work.

SQLite history is more useful than a line-numbered file

Atuin records each command with its working directory, host, session, timestamp, duration, and exit code. The search interface can limit results to the current session or directory, filter on metadata, and either execute a match or place it back on the command line for editing. That turns history into a work log rather than a bag of strings, especially when the same command means different things in different repositories.

Our checkout at commit 824c871 contained 590 files, about 87,868 lines of source, and occupied 8.4 MB. The Rust workspace pulled 677 packages during the lab install and included 13 CI workflow files plus a Dockerfile. The repository contains a client, sync server, database code, shell integrations, daemon work, encryption, a TUI, and newer AI-related features. Its scope is now broader than a replacement for ctrl-r.

Local-only mode avoids accounts and network trust

Atuin can record and search history without registering or syncing. The old shell history file continues to be updated, which gives users a familiar fallback during evaluation. Existing history can be imported automatically or by naming the shell. This is the safest adoption path: install on one machine, check what metadata is captured, configure exclusions, and decide later whether cross-device history justifies an account or server.

The shell layer varies by environment. zsh and fish have direct initialization snippets. Bash works best with ble.sh, while the bundled bash-preexec fallback has documented gaps around subshell commands, function definitions, duration, exit status, and ignorespace. Nushell writes a generated init file because its source command requires a static path. A team with several shells should test each tier instead of distributing one startup fragment everywhere.

Encrypted sync makes the recovery key your job

When a user registers, Atuin creates an encryption key locally. The sync guide states that the service cannot recover it, and users must copy it to each additional machine during login. This is the correct consequence of end-to-end encryption, but it changes the backup plan. Save the key in a password manager before treating sync as the only copy of valuable history.

Synchronization defaults to once per hour and can also run manually or force a full pass. The public server stores encrypted history, while a self-hosted server uses the same client-side encryption model. Commands may still contain secrets before encryption, and every logged-in endpoint can decrypt with the key. Filter policies, device access, local disk permissions, and account removal remain part of the threat model.

What happened when we ran it

Our fresh Debian sandbox installed 677 Rust packages in 20 seconds and completed the build in 234 seconds. It used 3 CPUs, 12 GB of RAM, no secrets, and commit 824c871. This was a successful source build in an unprivileged container, although most users can skip that work by installing a release binary or package.

Cargo tests ran for 274 seconds and returned exit code 101. Across the suite, 297 tests passed and 3 failed out of 300. The three failures were change_password, multi_user_test, and registration in the Atuin server user tests. Their common tail shows a request connection reset by peer at api_client.rs:141. It does not identify which process reset the connection or the condition that triggered it.

The installer deserves inspection before execution

The Unix guide recommends piping the Atuin setup script into a shell. It installs under ~/.atuin/bin, edits shell integration, offers history import, and can set up sync. Manual paths exist through Cargo, Homebrew, MacPorts, mise, Nix, Pacman, XBPS, Termux, zinit, and WinGet. Users who care about startup files should choose a package and add the relevant init line themselves.

Issue 3976 adds a current concern. The reporter says installation added hooks for Codex and other agents without a confirmation prompt, and that removing those hooks required manual work. The general uninstall guide covers Atuin directories and shell startup lines, but it does not give a hook-specific removal command. Until that behavior changes or is clarified, review the installer diff and agent configuration after setup.

Self-hosting is small, though it is still a service

The standalone atuin-server binary needs a database URI. PostgreSQL 14 or newer is supported, as is SQLite 3 or newer for a smaller deployment. Server configuration controls the listen address, port 8888 by default, registration policy, path prefix, and database. TLS was removed from the server configuration, so public deployments need nginx, Caddy, Traefik, or another reverse proxy.

Docker documentation includes persistent database mounts and a daily PostgreSQL backup service. It also warns operators to pin tagged releases because updates do not always apply without intervention. SQLite reduces moving parts for one user, while PostgreSQL fits a group. Either way, test restoration, protect registration, and monitor storage. Encrypted payloads do not remove the need to preserve the database or keep the service patched.

A current release coexists with a local WAL report

Atuin 18.20.0 was released on 2026-08-25, the same date as the latest GitHub push. The repository showed 406 open issues and pull requests, with fixes and reports receiving responses throughout that day. Release 18.20.0 includes shell, sync, search, installer, compression, and database work, plus separate client and server artifacts with attestations. This is an active, established project rather than an abandoned dotfile experiment.

Issue 3989 reports that history.db-wal can grow without being truncated on a machine running many concurrent shells. The report includes measurements from one system and links to an open fix. Most users may never reproduce that workload, but anyone operating dozens of terminals should watch the Atuin data directory after upgrading. For ordinary use, the core proposition holds: richer local history is useful, and sync remains an optional second decision.

Alternatives

ProjectWhat it isPick it when
HishtoryA synced and contextual shell history tool with local search and optional server use.pick this instead when you want another purpose-built synchronized history system and prefer its workflow.
fzf gh↗A general fuzzy finder commonly wired to a shell's existing history file.pick this instead when fast interactive search is enough and you do not need metadata or encrypted sync.
zsh-histdbA zsh plugin that records commands and session context in SQLite.pick this instead when you only use zsh and want a smaller local database layer without a sync service.
zsh-history-substring-searchA lightweight zsh plugin for matching previous commands with the up and down keys.pick this instead when substring recall is the whole requirement and changing the storage model is unnecessary.

What people are saying

  1. [github-trending] atuinsh/atuin

Sources

  1. Atuin README
  2. Atuin installation guide
  3. Atuin sync guide
  4. Atuin self-hosted server setup
  5. Atuin Docker and backup guide
  6. Atuin 18.20.0 release
  7. Atuin issue 3976, unprompted agent hooks
  8. Atuin issue 3989, SQLite WAL growth

More dev tools reviews

gander · lipgloss · roundhouse · GhostTrack · Codex-Dream-Skin · TokenTracker · the whole board →