# How the Omarchy Update System Works: A Deep Dive into the Atomic Upgrade Pipeline

> Explore the Omarchy update system's atomic upgrade pipeline. Learn how exclusive locking, Btrfs snapshots, and ten specialized phases ensure safe system updates for your repository.

- Repository: [37signals/omarchy](https://github.com/basecamp/omarchy)
- Tags: deep-dive
- Published: 2026-08-18

---

**The Omarchy update system is a self-contained Bash pipeline orchestrated by `omarchy-update` that guarantees safe, atomic system upgrades through exclusive locking, Btrfs snapshots, and ten distinct specialized phases.**

Omarchy's [update process](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update) transforms a potentially risky Arch Linux rolling upgrade into a deterministic, recoverable operation. Designed for developer workstations that demand both bleeding-edge packages and rock-solid reliability, the system splits every update into isolated phases with clear failure boundaries and automatic rollback capabilities.

## How to Trigger an Omarchy Update

The simplest entry point is the `omarchy` CLI wrapper:

```bash
omarchy update

```

For **unattended operation**—ideal for cron jobs, CI pipelines, or remote management—add the `-y` flag:

```bash
omarchy update -y

```

This single flag sets `OMARCHY_UPDATE_UNATTENDED=1` and bypasses all interactive prompts.

## Phase 1: Logging and Exclusive Lock Acquisition

The `omarchy-update` script begins by ensuring complete observability. When `OMARCHY_UPDATE_LOGGED` is unset, the entire command re-executes under `script` to capture output at `/tmp/omarchy-update.log` (lines 10–13).

Before any mutation occurs, **[`omarchy-update-lock`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-lock)** creates an exclusive lock at `$XDG_RUNTIME_DIR/omarchy-update.lock`. If another update holds the lock, the current process exits immediately with a user-friendly message (lines 15–17). This prevents the corruption that parallel Pacman operations can cause.

## Phase 2: Preconditions and Safety Guards

Two critical checks run before the upgrade begins:

### Free-Space Verification

**[`omarchy-update-requires-free-space`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-requires-free-space)** validates at least **10 GiB** of available space on the root filesystem (lines 8–16). Pacman operations can consume substantial temporary space during package decompression and installation.

Force bypass for debugging with:

```bash
export OMARCHY_UPDATE_FORCE=1
omarchy update

```

### Unattended Mode Detection

The `-y` flag sets `OMARCHY_UPDATE_UNATTENDED=1` (lines 24–27), which **[`omarchy-update-confirm`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-confirm)** respects by skipping interactive confirmation (line 28).

## Phase 3: Preparation and Snapshot Creation

Three preparatory steps create a clean, protected state:

1. **Package cache pruning** — **[`omarchy-update-pkg-prune`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-pkg-prune)** clears Pacman cache and prepares package state (line 31)
2. **Btrfs snapshot** — **[`omarchy-snapshot`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-snapshot)** creates a filesystem snapshot; failure with exit code 127 (Snapper absent) generates only a warning, while other errors halt the update (lines 36–38)
3. **Stay-awake inhibitor** — **[`omarchy-update-stay-awake`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-stay-awake)** prevents laptop suspension during long-running operations (line 39)

## Phase 4: Core Update Execution

The pipeline executes ten specialized scripts in sequence:

| Script | Responsibility |
|--------|---------------|
| **[`omarchy-update-dev`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-dev)** | Updates Omarchy-provided development packages |
| **[`omarchy-update-keyring`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-keyring)** | Synchronizes Pacman keyring to prevent signature verification failures |
| **[`omarchy-update-system-pkgs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-system-pkgs)** | Executes `pacman -Syu` for base system upgrade |
| **[`omarchy-migrate`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-migrate)** | Runs database and configuration migrations bundled with new packages |
| **[`omarchy-hook`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-hook)** (post-update) | Executes user-defined custom scripts |
| **[`omarchy-update-aur-pkgs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-aur-pkgs)** | Rebuilds and upgrades AUR packages from source |
| **[`omarchy-update-mise`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-mise)** | Updates language runtimes managed by *mise* |
| **[`omarchy-update-orphan-pkgs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-orphan-pkgs)** | Removes packages no longer required by dependency tree |
| **[`omarchy-update-analyze-logs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-analyze-logs)** | Parses `/tmp/omarchy-update.log` for failures and surfaces them |
| **[`omarchy-update-status`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-status)** | Updates the Quickshell UI badge to reflect current state (lines 55–56) |

This phased approach isolates failure domains: a broken AUR package cannot corrupt the base system upgrade that preceded it.

## Phase 5: Cleanup and Optional Restart

The **stay-awake inhibitor** stops (line 60) and its EXIT trap removes (line 61). **[`omarchy-update-restart`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-restart)** then checks if the kernel or critical components changed, offering a reboot when required (line 63).

## Error Handling and Safety Mechanisms

Two defensive patterns protect users:

- **Discord-linked error messages** — Any uncaught error displays a red-colored message with a link to the community Discord for support (line 19)
- **EXIT trap cleanup** — The `trap` on EXIT guarantees the stay-awake lock clears even if the script terminates abnormally (line 20)

## Advanced Operations

### Check Update Status Manually

```bash
omarchy-update-status

```

This queries whether updates are available, driving the Quickshell UI badge.

### Acquire Lock for Custom Operations

```bash
omarchy-update-lock run my-custom-script.sh

```

This leverages the same locking mechanism for ad-hoc maintenance.

## Summary

- **`omarchy-update`** orchestrates a **10-phase atomic pipeline** with exclusive locking and Btrfs snapshots
- **Unattended mode** (`-y`) enables fully automated, non-interactive upgrades
- **10 GiB free-space guard** prevents disk-full failures during Pacman operations
- **Phase isolation** ensures AUR build failures cannot corrupt base system state
- **Automatic cleanup** through EXIT traps and stay-awake inhibitors protects against partial states

## Frequently Asked Questions

### What happens if an Omarchy update is interrupted?

The **EXIT trap** (line 20) guarantees cleanup of the stay-awake inhibitor lock regardless of how the script terminates. The **Btrfs snapshot** created in phase 3 enables manual rollback if the filesystem state is corrupted. The **exclusive lock** prevents concurrent operations from creating conflicting states.

### How does Omarchy handle AUR package build failures?

**[`omarchy-update-aur-pkgs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-aur-pkgs)** runs after the base system upgrade completes successfully. Because AUR builds execute in a separate phase, a compilation failure cannot roll back or corrupt the core system packages already installed. **[`omarchy-update-analyze-logs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-analyze-logs)** surfaces specific build errors for user intervention.

### Can I run Omarchy updates automatically via cron?

Yes. The `-y` flag enables fully unattended operation:

```bash
0 2 * * * /usr/bin/omarchy update -y >> /var/log/omarchy-auto.log 2>&1

```

Set `OMARCHY_UPDATE_FORCE=1` if you need to bypass the free-space check in constrained environments, though this is not recommended for production automation.

### Where are Omarchy update logs stored?

Complete output captures to `/tmp/omarchy-update.log` through the `script` utility when `OMARCHY_UPDATE_LOGGED` is initially unset. The log persists after completion for inspection by **[`omarchy-update-analyze-logs`](https://github.com/basecamp/omarchy/blob/quattro/bin/omarchy-update-analyze-logs)** and manual troubleshooting.