How Omarchy Manages System Snapshots with Snapper: Complete Technical Guide
Omarchy integrates Snapper to automatically create versioned Btrfs snapshots before system updates, enforce retention policies via immediate cleanup, and restore system states through the Limine bootloader.
Omarchy is an opinionated Arch Linux distribution that treats system snapshots as a critical safety net for seamless updates. By leveraging Snapper on Btrfs filesystems, the distribution automates the creation, cleanup, and restoration of system states without manual intervention. This deep dive examines the exact implementation details found in the omacom/omarchy repository, showing how the distribution configures Snapper during installation and manages snapshots throughout the system lifecycle.
Initial Snapper Configuration in install/config/snapper.sh
During installation, Omarchy executes install/config/snapper.sh to initialize the snapshot environment. This script creates the /etc/snapper/configs/root configuration from a default template if none exists, writes environment settings to /etc/conf.d/snapper, and manages systemd timer states. Critically, it disables the snapper-timeline.timer to prevent automatic timeline snapshots that consume disk space, while enabling snapper-cleanup.timer and limine-snapper-sync.service to ensure orphaned snapshots are pruned and boot entries stay synchronized with the Limine bootloader.
The configuration specifically avoids background timeline snapshots, relying instead on explicit, event-driven snapshots triggered by system updates. This design prevents snapshot accumulation while ensuring a recent restore point always exists before package modifications.
The omarchy-snapshot Command Interface
The user-facing omarchy-snapshot command, located at bin/omarchy-snapshot, provides the primary interface for snapshot management through two distinct actions: create and restore.
Creating Versioned Snapshots
When invoked with the create argument, the script first verifies that the snapper binary exists, exiting with code 127 if absent—allowing calling scripts to gracefully skip snapshot operations on non-Btrfs systems. It then iterates through all configured subvolumes using snapper --csvout list-configs, creating numbered snapshots labeled with the current Omarchy version via snapper -c "$config" create -c number -d "$DESC".
Immediately after creation, the script triggers snapper … cleanup number to enforce the NUMBER_LIMIT retention policy defined in the template, ensuring older snapshots are pruned before disk space becomes critical.
# Run the snapshot command directly before manual changes
omarchy-snapshot create
# Used in update scripts to ignore exit if Snapper is missing
omarchy-snapshot create || (( $? == 127 ))
Restoring from Snapshots
The restore action delegates to limine-snapper-restore, which surfaces available snapshots in the Limine bootloader menu at boot time. This enables point-in-time recovery without requiring chroot environments or live USB media.
# Prepare Limine to show snapshot menu on next boot
omarchy-snapshot restore
Post-Upgrade Migration Scripts
Omarchy includes dedicated migration scripts to maintain Snapper state consistency across distribution upgrades, ensuring services remain enabled and legacy artifacts are removed.
Service State Validation (1781984677.sh)
migrations/1781984677.sh validates that install/config/snapper.sh exists and ensures both snapper-cleanup.timer and limine-snapper-sync.service remain enabled after system updates. This prevents package updates from accidentally disabling the automated cleanup workflow.
Legacy Timeline Cleanup (1784809452.sh)
migrations/1784809452.sh detects and removes "leaked" timeline snapshots created under previous Omarchy defaults. The script deletes these legacy snapshots in batches of up to 20 to prevent I/O thrashing while reporting any failures for manual review.
Automated Pre-Update Safety Workflow
Omarchy's update scripts automatically invoke omarchy-snapshot create before package modifications, ensuring every update has a rollback point. The exit code 127 handling is particularly important for compatibility:
# Check configured Snapper subvolumes manually
sudo snapper --csvout list-configs | awk -F, 'NR>1 {print $1}'
# Manually trigger cleanup of old snapshots exceeding NUMBER_LIMIT
sudo snapper -c root cleanup number
This integration ensures that users can always boot into a previous system state if an update introduces instability, with the Limine bootloader presenting a clear menu of available snapshots.
Summary
- Omarchy configures Snapper during installation via
install/config/snapper.sh, disabling timeline snapshots but enabling cleanup timers and Limine synchronization services. - The
omarchy-snapshotcommand creates versioned snapshots across all configured subvolumes and immediately cleans up excess images according to the NUMBER_LIMIT policy defined in the template. - Exit code 127 handling allows graceful degradation when Snapper is unavailable, permitting the update pipeline to function on non-Btrfs systems.
- Migration scripts
1781984677.shand1784809452.shmaintain service state consistency and remove legacy timeline snapshots after distribution upgrades. - Restoration occurs through the Limine bootloader menu via the
restoreaction, providing hardware-level rollback capabilities without manual chroot operations.
Frequently Asked Questions
Where does Omarchy store its Snapper configuration?
Omarchy creates the primary configuration at /etc/snapper/configs/root during installation using the template provided in install/config/snapper.sh. The script also writes environment variables to /etc/conf.d/snapper and manages systemd timer states to ensure the cleanup service runs while disabling automatic timeline snapshots that could fill the disk.
How does Omarchy handle snapshot retention and cleanup?
The distribution enforces retention through immediate post-creation cleanup. After each snapshot is created via omarchy-snapshot create, the script executes snapper -c "$config" cleanup number using the NUMBER_LIMIT value defined in the Snapper template. Additionally, migrations/1784809452.sh removes legacy timeline snapshots that may have accumulated under older Omarchy configurations.
What happens if Snapper is not installed during an update?
The bin/omarchy-snapshot script checks for the snapper binary before execution and exits with code 127 if absent. The update scripts catch this specific exit code using the pattern omarchy-snapshot create || (( $? == 127 )), allowing the update to proceed normally on systems without Btrfs or Snapper support.
How do I restore my system to a previous snapshot?
Run omarchy-snapshot restore from the command line, which delegates to limine-snapper-restore. This prepares the Limine bootloader to display available snapshots at the next boot, allowing graphical selection of the desired system state without requiring live USB media or manual chroot operations.
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 →