Arch Linux Package Management: pacman, AUR and System Maintenance
Arch Linux's package management is one of its greatest strengths and, for newcomers, one of its most intimidating aspects. The combination of pacman for official repositories and the AUR (Arch User Repository) for community packages gives you access to an enormous software catalog with minimal packaging lag. But Arch is a rolling-release distribution, and keeping a system healthy over months and years requires understanding how packages are built, updated, and maintained.
This guide covers everything from daily pacman usage to advanced system maintenance routines that keep Arch running reliably on workstations and servers alike.
pacman: Essential Commands
pacman uses a flag-based syntax that feels terse at first but becomes second nature quickly. The capital letter flags represent operations, and lowercase flags modify them.
Package Installation and Removal
# Sync database and upgrade all packages
sudo pacman -Syu
# Install a package
sudo pacman -S nginx
# Install multiple packages
sudo pacman -S nginx postgresql redis
# Install without confirmation
sudo pacman -S --noconfirm docker
# Remove a package
sudo pacman -R nginx
# Remove package + unneeded dependencies
sudo pacman -Rs nginx
# Remove package + deps + config files
sudo pacman -Rns nginx
# Remove all orphaned packages (dependencies no longer needed)
sudo pacman -Rns $(pacman -Qdtq)
Querying Packages
# Search for a package in repos
pacman -Ss docker
# Show package info from repos
pacman -Si docker
# List installed packages
pacman -Q
# Search installed packages
pacman -Qs docker
# Show info about an installed package
pacman -Qi docker
# List files owned by a package
pacman -Ql docker
# Find which package owns a file
pacman -Qo /usr/bin/docker
# List explicitly installed packages (not dependencies)
pacman -Qe
# List packages installed from AUR (foreign)
pacman -Qm
# List orphaned packages
pacman -Qdt
# Check package for missing files
pacman -Qk docker
Database Operations
# Sync package database only (no upgrade)
sudo pacman -Sy # Warning: don't install packages after -Sy without -u
# Force refresh of all package databases
sudo pacman -Syy
# Download packages without installing
sudo pacman -Sw nginx
# Verify all installed packages
pacman -Qkk
pacman -Sy package (sync database then install a single package). This creates a partial upgrade where some packages are updated and others are not, which can break library dependencies. Always use pacman -Syu to do a full system upgrade, or pacman -Syu package to upgrade and install in one step.
Mirrorlist Optimization
The speed of package downloads depends entirely on your mirror selection. The reflector tool automates finding the fastest mirrors:
# Install reflector
sudo pacman -S reflector
# Find the 10 fastest HTTPS mirrors, sorted by speed, recently synced
sudo reflector --country 'United States,Germany,France' \
--protocol https \
--age 12 \
--sort rate \
--number 10 \
--save /etc/pacman.d/mirrorlist
# Automate with a systemd timer
sudo systemctl enable reflector.timer
# Or create a custom timer
# /etc/systemd/system/reflector.timer
# [Timer]
# OnCalendar=weekly
# Persistent=true
You can also configure reflector's defaults in /etc/xdg/reflector/reflector.conf:
# /etc/xdg/reflector/reflector.conf
--save /etc/pacman.d/mirrorlist
--protocol https
--country US,DE,FR
--latest 10
--sort rate
--age 12
AUR Helpers: yay and paru
The AUR contains tens of thousands of community-maintained packages that are not in the official repositories. AUR helpers automate the process of downloading PKGBUILDs, building packages, and installing them.
Installing yay
# yay must be built from the AUR manually the first time
sudo pacman -S --needed base-devel git
git clone https://aur.archlinux.org/yay-bin.git
cd yay-bin
makepkg -si
cd .. && rm -rf yay-bin
Installing paru
# paru is written in Rust and is actively maintained
sudo pacman -S --needed base-devel git
git clone https://aur.archlinux.org/paru-bin.git
cd paru-bin
makepkg -si
cd .. && rm -rf paru-bin
Using AUR Helpers
# Both yay and paru use pacman-compatible syntax
# Search AUR and official repos
yay -Ss google-chrome
# Install from AUR
yay -S google-chrome
# Update all packages (official + AUR)
yay -Syu
# Show AUR package info
yay -Si visual-studio-code-bin
# Clean unneeded dependencies
yay -Yc
# paru-specific: review PKGBUILD before building
paru -S package-name
# paru shows the PKGBUILD by default for review
# Generate development package updates
yay -Syu --devel
# List AUR packages that need updating
yay -Qua
| Feature | yay | paru |
|---|---|---|
| Language | Go | Rust |
| PKGBUILD review | Optional (--editmenu) | Default (safer) |
| Speed | Fast | Fast |
| Maintainer | Active | Active |
| Batch install | Yes | Yes |
| chroot builds | No | Yes (--chroot) |
| Completions | Yes | Yes |
Building from PKGBUILD
Understanding PKGBUILDs is essential for any serious Arch user. A PKGBUILD is a shell script that defines how to build a package:
# Example PKGBUILD for a Go application
pkgname=myapp
pkgver=1.5.2
pkgrel=1
pkgdesc="My application description"
arch=('x86_64' 'aarch64')
url="https://github.com/user/myapp"
license=('MIT')
depends=('glibc')
makedepends=('go')
source=("$pkgname-$pkgver.tar.gz::https://github.com/user/$pkgname/archive/v$pkgver.tar.gz")
sha256sums=('SKIP') # Replace with actual checksum
build() {
cd "$pkgname-$pkgver"
export CGO_ENABLED=0
go build -ldflags "-s -w -X main.version=$pkgver" -o "$pkgname" .
}
package() {
cd "$pkgname-$pkgver"
install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm644 "$pkgname.service" "$pkgdir/usr/lib/systemd/system/$pkgname.service"
}
# Build and install from PKGBUILD
cd /path/to/pkgbuild/directory
makepkg -si
# Build without installing
makepkg
# Build and install, skip dependency checks (dangerous)
makepkg -si --skippgpcheck
# Generate .SRCINFO (required for AUR submissions)
makepkg --printsrcinfo > .SRCINFO
# Build in a clean chroot (most reliable)
extra-x86_64-build
Custom Repository
For organizations running multiple Arch machines, a custom repository avoids rebuilding AUR packages on every machine:
# Create a custom repository directory
mkdir -p /srv/repo/custom
# Build a package and add it to the repo
cd /path/to/pkgbuild
makepkg -s
cp *.pkg.tar.zst /srv/repo/custom/
# Create/update the repository database
repo-add /srv/repo/custom/custom.db.tar.gz /srv/repo/custom/*.pkg.tar.zst
# Add to pacman.conf on client machines
# /etc/pacman.conf
[custom]
SigLevel = Optional TrustAll
Server = file:///srv/repo/custom
# Or for remote: Server = https://repo.example.com/custom
Cache Management
pacman caches every package it downloads. Over time, this cache grows to consume gigabytes of disk space:
# Check cache size
du -sh /var/cache/pacman/pkg/
# Remove all cached packages except currently installed versions
sudo pacman -Sc
# Remove ALL cached packages (more aggressive)
sudo pacman -Scc
# Better: use paccache for fine-grained control
sudo pacman -S pacman-contrib
# Keep only the last 3 versions of each package
sudo paccache -r
# Keep only the last 1 version
sudo paccache -rk1
# Remove uninstalled package caches
sudo paccache -ruk0
# Automate with a systemd timer
sudo systemctl enable paccache.timer
Package Signing and Security
# Initialize the pacman keyring
sudo pacman-key --init
# Populate with Arch Linux keys
sudo pacman-key --populate archlinux
# Add a custom key (for custom repos)
sudo pacman-key --recv-keys KEY_ID
sudo pacman-key --lsign-key KEY_ID
# Verify database signatures
# In /etc/pacman.conf:
# SigLevel = Required DatabaseOptional
# LocalFileSigLevel = Optional
Downgrading Packages
When an update breaks something, you need to downgrade. There are several methods:
# Method 1: Install from cache
sudo pacman -U /var/cache/pacman/pkg/package-old_version-x86_64.pkg.tar.zst
# Method 2: Use the Arch Linux Archive
sudo pacman -U https://archive.archlinux.org/packages/p/package/package-old_version-x86_64.pkg.tar.zst
# Method 3: Use the downgrade tool (AUR)
yay -S downgrade
sudo downgrade package-name
# Prevent a package from being upgraded (add to pacman.conf)
# IgnorePkg = linux linux-headers nvidia
Why Partial Upgrades Break Systems
Arch Linux's package manager does not support partial upgrades. Here is why:
- Package A version 2.0 in the repos is compiled against library B version 3.0
- You run
pacman -Sy(sync database) thenpacman -S A(install A only) - Package A 2.0 installs, but library B is still at version 2.0 on your system
- Package A fails at runtime because it expects library B 3.0 symbols
This cascading dependency issue is why every Arch wiki page emphasizes: always use pacman -Syu, never pacman -Sy alone.
System Maintenance Routine
A weekly maintenance routine prevents most Arch-related issues:
#!/bin/bash
# arch-maintenance.sh - Weekly system maintenance
set -euo pipefail
echo "=== Arch Linux Weekly Maintenance ==="
# 1. Full system upgrade
echo "[1/8] Upgrading system..."
sudo pacman -Syu
# 2. Update AUR packages
echo "[2/8] Updating AUR packages..."
yay -Sua
# 3. Remove orphaned packages
echo "[3/8] Removing orphans..."
orphans=$(pacman -Qdtq 2>/dev/null || true)
if [ -n "$orphans" ]; then
sudo pacman -Rns $orphans
else
echo " No orphans found"
fi
# 4. Clean package cache (keep last 3 versions)
echo "[4/8] Cleaning package cache..."
sudo paccache -r
sudo paccache -ruk0
# 5. Check for .pacnew and .pacsave files
echo "[5/8] Checking for config changes..."
pacdiff_files=$(find /etc -name "*.pacnew" -o -name "*.pacsave" 2>/dev/null || true)
if [ -n "$pacdiff_files" ]; then
echo " Found files needing attention:"
echo "$pacdiff_files"
echo " Run 'sudo pacdiff' to merge"
else
echo " No .pacnew/.pacsave files"
fi
# 6. Check for failed systemd services
echo "[6/8] Checking failed services..."
failed=$(systemctl --failed --no-legend 2>/dev/null || true)
if [ -n "$failed" ]; then
echo " Failed services:"
echo "$failed"
else
echo " All services healthy"
fi
# 7. Check journal for errors
echo "[7/8] Recent critical errors:"
journalctl -p 3 -b --no-pager | tail -10
# 8. Check disk usage
echo "[8/8] Disk usage:"
df -h / /home /var 2>/dev/null | grep -v tmpfs
echo ""
echo "=== Maintenance complete ==="
pacman -Syu. Major updates occasionally require manual intervention, and the news will tell you what steps to take.
pacman.conf Tuning
# /etc/pacman.conf - Useful options
[options]
# Enable color output
Color
# Show package download progress as a bar
# (Uncomment in pacman.conf)
# ILoveCandy # Makes the progress bar a Pac-Man animation
# Parallel downloads (pacman 6+)
ParallelDownloads = 5
# Verbose package lists during upgrade
VerbosePkgLists
# Check available disk space
CheckSpace
# Packages to never upgrade
IgnorePkg = linux-lts linux-lts-headers
# Groups to never upgrade
# IgnoreGroup =
Arch Linux rewards users who invest in understanding its package management system. The combination of pacman's speed and simplicity with the AUR's breadth gives you access to virtually any software available on Linux, always at the latest version. Maintain your system regularly, read the news before updating, and never do partial upgrades. If you run Docker containers on Arch (which many homelab enthusiasts do), the same principles apply: keep your host system current so that Docker, containerd, and kernel features stay compatible. Tools like usulnet can help you monitor containerized services running on Arch hosts, providing visibility without adding system maintenance overhead.