How Omarchy Handles System Updates and Migrations: A Complete Technical Breakdown
Omarchy orchestrates system updates and migrations through a single omarchy-update pipeline that combines package upgrades, filesystem snapshots, lock handling, and per-user migration scripts into one atomic, retry-safe workflow.
The omarchy-update command serves as the central driver for all system maintenance in Omarchy. According to the omacom/omarchy source code, this pipeline ensures that package transactions, filesystem snapshots, and configuration migrations execute in a strict, recoverable order—protecting users from partial updates and configuration drift.
The Omarchy Update Pipeline: Step-by-Step Execution
The update process in bin/omarchy-update follows a 14-stage pipeline designed for safety, observability, and re-entrancy.
1. Transcript Capture and Re-entrancy Guard
Every update session automatically captures all output to /tmp/omarchy-update.log by re-executing inside script(1):
# Source: bin/omarchy-update#L10-L13
if [ -z "${OMARCHY_UPDATE_TRANSCRIPT:-}" ]; then
export OMARCHY_UPDATE_TRANSCRIPT=1
exec script -q -c "$0 $*" /tmp/omarchy-update.log
fi
This ensures complete audit trails and simplifies troubleshooting when updates fail.
2. Per-User Locking and Free-Space Validation
Before any destructive operations, Omarchy establishes safety boundaries:
omarchy-update-lock— Creates a lockfile at${XDG_RUNTIME_DIR:-/tmp}/omarchy-update.lockto prevent concurrent update attemptsomarchy-update-requires-free-space— Aborts if root filesystem has less than 10 GiB free (docs/update-process.md#L143-L146)
3. Interactive vs. Unattended Modes
The -y flag controls interaction:
# Interactive (prompts for confirmation)
omarchy update
# Non-interactive (suitable for automation)
omarchy update -y # Sets OMARCHY_UPDATE_UNATTENDED=1
(source: bin/omarchy-update#L24-L27)
4. Pre-Snapshot Cache Pruning
To conserve snapshot space, omarchy-update-pkg-prune runs paccache -rk2—keeping only the two most recent versions of each package in the pacman cache (docs/update-process.md#L121-L122).
5. Filesystem Snapshot Creation
omarchy-snapshot create attempts a Snapper snapshot. Notably, exit code 127 (missing Snapper) is tolerated, allowing installations on systems without Btrfs:
# Source: bin/omarchy-update#L33-L38
omarchy-snapshot create || {
local exit_code=$?
[ $exit_code -eq 127 ] || exit $exit_code
}
6. Sleep Inhibition and Keyring Refresh
The pipeline acquires a systemd inhibitor via omarchy-update-stay-awake start to prevent suspend during updates, then refreshes cryptographic trust:
omarchy-update-keyring— Updates Arch and Omarchy keyringsomarchy-update-dev— Fast-forwards development checkouts when present
7. Package Transaction and Migration Trigger
The core system update executes with explicit overwrite rules for Omarchy-managed files:
# Source: bin/omarchy-update#L44-L48
omarchy-update-system-pkgs # Runs: pacman -Syu --noconfirm --overwrite ...
omarchy-migrate # Executes pending migrations AFTER pacman completes
Critical ordering: Migrations run only after the package transaction succeeds, ensuring schema and binary compatibility.
Omarchy Migration System: Idempotent, File-Based Upgrades
The migration subsystem in bin/omarchy-migrate provides a lightweight, declarative mechanism for evolving system configurations across releases.
How Pending Migrations Are Detected
The script compares migration files against completion markers:
# List pending migrations without applying them
omarchy-migrate --pending
Migration Execution Flow
For each pending script in $OMARCHY_PATH/migrations/*.sh:
- Wait for pacman lock release — Polls
/var/lib/pacman/db.lckuntil absent (bin/omarchy-migrate#L68-L72) - Execute with strict error handling —
bash -euo pipefailensures failures halt the pipeline - Record completion — Empty marker file created at
$HOME/.local/state/omarchy/migrations/<script>.sh - Clean up notifications — Dismisses "Omarchy Migrations" desktop alerts (bin/omarchy-migrate#L99-L103)
Migration Script Requirements
- Location:
${OMARCHY_PATH}/migrations/directory - Format: Self-contained Bash files (
.shextension) - Idempotence: Already-completed migrations are automatically skipped
- Privileges: Scripts may prompt for
sudore-execution if elevated access needed - Success criteria: Exit status 0 required for completion marking
This design guarantees safe, incremental upgrades across arbitrary version jumps—users can skip releases without missing configuration changes.
Post-Update Operations and Service Management
After migrations complete, the pipeline finalizes the update:
| Stage | Command | Purpose |
|---|---|---|
| Hooks | omarchy-hook post-update |
Execute user-defined custom scripts |
| AUR updates | omarchy-update-aur-pkgs |
Sync AUR package builds |
| Toolchain | omarchy-update-mise |
Refresh mise-managed tools |
| Cleanup | omarchy-update-orphan-pkgs |
Remove orphaned packages (optional) |
| Analysis | omarchy-update-analyze-logs |
Scan transcript for failure patterns |
| UI refresh | omarchy-update-status |
Update shell widget indicators |
Reboot and Restart Handling
omarchy-update-restart manages system state transitions:
- Prompts for reboot when kernel or Hyprland updates detected
- Restarts services flagged by
restart-*-requiredmarkers - Releases lock and inhibitor before reboot prompt — Prevents deadlock scenarios
Key Files and Architectural Components
| Component | Path | Function |
|---|---|---|
| Update orchestrator | bin/omarchy-update |
14-stage pipeline driver |
| Migration runner | bin/omarchy-migrate |
Pending detection and execution |
| Migration scripts | migrations/ |
Release-shipped upgrade scripts |
| Documentation | [docs/update-process.md](https://github.com/omacom/omarchy/blob/quattro/docs/update-process.md) |
Human-readable workflow reference |
| Lock implementation | bin/omarchy-update-lock |
Per-user concurrency control |
| Pacman guard | default/systemd/user/omarchy-update-pacman-guard.service |
Prevents direct pacman -Syu bypass |
| Notification helper | bin/omarchy-notification-dismiss |
Cleans up desktop alerts |
Practical Examples
# Standard interactive update
omarchy update
# Automated/unattended update for cron or remote management
omarchy update -y
# Preview what migrations would apply (dry-run style)
omarchy-migrate --pending
# Manual migration execution (rarely needed)
migration_file=$(grep -l "dell-xps13-sidecar-amps" "$HOME/.local/state/omarchy/migrations"/*.sh | head -1)
bash -euo pipefail "$migration_file"
Summary
- Atomic pipeline:
omarchy-updatesequences locks, snapshots, packages, and migrations in a fixed, failure-recoverable order - Idempotent migrations: File-based completion markers in
$HOME/.local/state/omarchy/migrations/ensure safe re-runs across reboots - Filesystem safety: Mandatory 10 GiB free space check and optional Snapper snapshots protect against disk exhaustion and corruption
- Strict ordering: Migrations execute after package transactions complete, preventing binary/schema mismatches
- User experience: Transcript logging, sleep inhibition, and desktop notifications keep users informed throughout the process
Frequently Asked Questions
What happens if Omarchy updates are interrupted mid-process?
The per-user lock at ${XDG_RUNTIME_DIR:-/tmp}/omarchy-update.lock is automatically released when the omarchy-update process terminates, whether through success, failure, or signal. The transcript at /tmp/omarchy-update.log preserves full output for diagnosis. Because migrations use completion markers, re-running omarchy update safely resumes from the last uncompleted step without re-applying finished work.
Can I run pacman -Syu directly instead of omarchy update?
Omarchy explicitly discourages this. The omarchy-update-pacman-guard.service systemd unit prevents direct pacman system upgrades, redirecting users to the omarchy update command. Bypassing the pipeline skips critical safety checks: filesystem snapshots, migration application, free-space validation, and proper lock handling.
How do I know if a migration requires manual intervention?
Run omarchy-migrate --pending to list unapplied migrations. Individual migration scripts may prompt for sudo if they need elevated privileges—this is expected behavior. The migration system deliberately does not auto-elevate, ensuring users consciously authorize privileged configuration changes.
What triggers an automatic reboot after update?
omarchy-update-restart compares installed kernel and Hyprland versions against running instances. If either component changed, a reboot prompt appears after all other update stages complete. Services marked with restart-*-required files are restarted without full system reboot when possible, minimizing downtime for non-kernel updates.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →