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
Warning: Never run 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
Tip: Always review the PKGBUILD before installing AUR packages. AUR packages are user-submitted and could contain malicious code. paru forces a review by default, which is a good security practice. Check the source URLs, build commands, and install scripts.

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
Warning: Downgrading is a temporary measure. Holding packages at old versions on a rolling-release system creates dependency conflicts over time. File a bug report and plan to update once the issue is fixed upstream.

Why Partial Upgrades Break Systems

Arch Linux's package manager does not support partial upgrades. Here is why:

  1. Package A version 2.0 in the repos is compiled against library B version 3.0
  2. You run pacman -Sy (sync database) then pacman -S A (install A only)
  3. Package A 2.0 installs, but library B is still at version 2.0 on your system
  4. 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 ==="
Tip: Always check the Arch Linux news feed (archlinux.org/news) before running 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.