Goal: a modern Arch Linux install (Btrfs, snapshots via Snapper, gaming-ready) dual-booting with Windows 11. Secure Boot is OFF in this guide. This guide is made for my personal use, and has choices picked by me.
Hardware & choices used in this guide
- CPU: Intel Core i5-12400F
- GPU: AMD Radeon RX-6650 XT (8 GB)
- RAM: 16 GB DDR4-3200 (2×8 GB)
- Filesystem: Btrfs with subvolumes @,@home,@snapshots,@log,@cache
- Snapshot tool: snapper + snap-pac
- Bootloader: GRUB (UEFI) — simple fix for MSI/firmware quirks included
- Audio: PipeWire + wireplumber
- Swap: zram via zram-generator(configured)
- Gaming helpers: gamemode, Vulkan + 32-bit libs, Steam/Lutris compatible
- Preparation (live USB)
- Disk layout & partitioning
- Formatting & labels
- Create Btrfs subvolumes
- Mounting (recommended options)
- Mount Windows ESP temporarily (for os-prober)
- Install base system (pacstrap)
- Generate & edit /etc/fstab (important)
- Chroot — system configuration
- Users & passwords
- GRUB install & MSI boot fix
- Enable services
- Reboot and post-install tasks
- Snapper configuration
- GRUB snapshot integration (grub-btrfs)
- Install KDE, GPU & multimedia packages
- ZRAM (recommended config)
- Gaming extras & performance
- Post-install: AUR helper, firewall & mirror updates
- Optional: SDDM auto-login
- Notes & troubleshooting tips
- Boot Arch ISO in UEFI mode.
- Keyboard layout:
loadkeys us- Verify UEFI mode (should show 64):
cat /sys/firmware/efi/fw_platform_size- Ensure network:
ping -c 3 archlinux.org- Sync clock:
timedatectl set-ntp trueExample using /dev/nvme1n1 (replace with your disk):
- Partition 1: 512M — EFI System (FAT32)
- Partition 2: remaining — Linux filesystem (Btrfs)
Use gdisk (or cfdisk if you prefer a TUI):
gdisk /dev/nvme1n1Format EFI partition (with label ARCH_ESP):
mkfs.fat -F32 -n ARCH_ESP /dev/nvme1n1p1Format Btrfs root partition (with label ARCH_ROOT):
mkfs.btrfs -L ARCH_ROOT /dev/nvme1n1p2Mount the raw Btrfs device, create subvolumes, then unmount:
mount /dev/nvme1n1p2 /mnt
btrfs subvolume create /mnt/@
btrfs subvolume create /mnt/@home
btrfs subvolume create /mnt/@snapshots
btrfs subvolume create /mnt/@log
btrfs subvolume create /mnt/@cache
umount /mntThese names are concise and map to /, /home, /.snapshots, /var/log, /var/cache respectively.
Choose mount options (remember to remove discard=async option from fstab, which is added automatically):
BTRFS_OPTS="rw,ssd,noatime,compress=zstd:1,space_cache=v2"Mount root and create mount points:
mount -o $BTRFS_OPTS,subvol=@ /dev/nvme1n1p2 /mnt
mkdir -p /mnt/{home,.snapshots,var/{log,cache},efi,win-esp}
mount -o $BTRFS_OPTS,subvol=@home /dev/nvme1n1p2 /mnt/home
mount -o $BTRFS_OPTS,subvol=@snapshots /dev/nvme1n1p2 /mnt/.snapshots
mount -o $BTRFS_OPTS,subvol=@log /dev/nvme1n1p2 /mnt/var/log
mount -o $BTRFS_OPTS,subvol=@cache /dev/nvme1n1p2 /mnt/var/cache
mount /dev/nvme1n1p1 /mnt/efiNotes:
- We do not enable discard=asynchere — preferfstrim.timer.
- compress=zstd:1is a good balance for desktop/SSD.
To let os-prober detect Windows (if Windows ESP is on another disk), mount it read-only.
Find the Windows ESP (e.g., /dev/nvme0n1p3) with lsblk -f then:
mount -o ro /dev/nvme0n1p3 /mnt/win-espAfter running os-prober/grub-mkconfig you can umount /mnt/win-esp (but not now).
Install a curated base set (long commands can be broken with \ backslash):
pacstrap /mnt base base-devel linux linux-headers linux-firmware git btrfs-progs grub efibootmgr os-prober ntfs-3g dosfstools intel-ucode nano networkmanager \
pipewire pipewire-alsa pipewire-pulse pipewire-jack wireplumber reflector man man-db man-pages sudo grub-btrfs snapper snap-pac inotify-toolsYou can add extra packages later (via pacman); the above covers essentials for this guide.
Generate fstab:
genfstab -U /mnt >> /mnt/etc/fstabCRITICAL: open /mnt/etc/fstab and ensure every Btrfs line uses exactly:
rw,ssd,noatime,compress=zstd:1,space_cache=v2
Delete any discard=async entries added by genfstab (we prefer scheduled fstrim.timer).
Enter chroot:
arch-chroot /mntSet timezone (Asia/Kolkata):
ln -sf /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
hwclock --systohcLocales: edit /etc/locale.gen and uncomment en_US.UTF-8 and en_IN.UTF-8, then:
locale-genCreate /etc/locale.conf with your locale settings:
echo "LANG=en_IN.UTF-8" > /etc/locale.conf
echo "LC_MESSAGES=en_US.UTF-8" >> /etc/locale.confSet hostname and edit /etc/hosts (replace my-arch-pc with your preferred hostname):
# To set the hostname
echo "my-arch-pc" > /etc/hostnameEdit /etc/hosts and add this line at the end:
nano /etc/hostsAdd:
127.0.0.1   localhost
::1         localhost
127.0.1.1   my-arch-pc
Set root password:
passwdCreate your normal user (replace anirudh with your preferred name) and set its password:
useradd -mG wheel anirudh
passwd anirudhEnable wheel sudoers: Do EDITOR=nano visudo and uncomment this line:
%wheel ALL=(ALL:ALL) ALL
Install GRUB to the EFI and register entry:
grub-install --target=x86_64-efi --efi-directory=/efi --bootloader-id="Arch (GRUB)" --recheckCreate the empty fallback file to satisfy some firmware (MSI):
mkdir -p /efi/EFI/BOOT
touch /efi/EFI/BOOT/bootx64.efiEdit /etc/default/grub and set:
nano /etc/default/grubChange this line:
GRUB_DISABLE_OS_PROBER=false
Then generate config:
grub-mkconfig -o /boot/grub/grub.cfgVerify with efibootmgr and remove /win-esp if you mounted it earlier:
efibootmgr
umount /win-esp
rmdir /win-espEnable networking and scheduled TRIM (recommended):
systemctl enable NetworkManager
systemctl enable fstrim.timerExit chroot, unmount and reboot:
exit
umount -R /mnt
rebootRemove USB and boot into your new system.
Create the root snapper config and set permissions:
sudo snapper -c root create-config /
sudo chmod a+rx /.snapshotsEnable cleanup and timers:
sudo snapper -c root set-config NUMBER_CLEANUP="yes"
sudo systemctl enable --now snapper-timeline.timer
sudo systemctl enable --now snapper-cleanup.timerVerify snapshot creation after a pacman transaction:
sudo pacman -Syu
sudo snapper -c root listYou should see pre and post snapshots created by snap-pac hooks.
Enable the daemon that adds snapshots to the GRUB menu:
sudo systemctl enable --now grub-btrfsdThis makes it easy to boot older snapshots from GRUB.
Enable multilib in /etc/pacman.conf (uncomment [multilib] and Include = /etc/pacman.d/mirrorlist) and update:
sudo nano /etc/pacman.conf
sudo pacman -SyuInstall desktop, drivers and 32-bit libs for gaming:
sudo pacman -S plasma-meta dolphin konsole sddm sddm-kcm bluez bluez-utils
sudo pacman -S mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon libva-mesa-driver lib32-libva-mesa-driver mesa-vdpau lib32-mesa-vdpauNotes:
- Do not need xf86-video-amdgpufor Wayland;mesa+ kernelamdgpudriver + Vulkan packages are the important parts.
- lib32-*packages are required for many Proton/Wine games (32-bit runtimes).
Enable graphical login and Bluetooth:
sudo systemctl enable sddm
sudo systemctl enable bluetooth
rebootInstall zram-generator and configure a sensible zram device:
sudo pacman -S zram-generator
sudo tee /etc/systemd/zram-generator.conf > /dev/null <<'EOF'
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
fs-type = swap
EOF
# Set a reasonable swappiness (tweak to taste, recommended 133 or 180)
echo 'vm.swappiness=180' | sudo tee /etc/sysctl.d/99-zram-swappiness.confApply the sysctl setting and reboot to activate zram:
sudo sysctl --system
rebootAfter reboot, verify zram is active:
zramctlNote: Hibernation is not supported on zram alone. Use a disk swap if you require suspend-to-disk.
- Install GameMode (Feral) and the 32-bit variant:
sudo pacman -S gamemode lib32-gamemode
sudo systemctl enable --now gamemoded
sudo usermod -aG gamemode $USER- Use gamemoderun(or Steam/Lutris launch options) to request optimizations:
gamemoderun %command%
- For Wine/Proton, make sure lib32-mesa,lib32-vulkan-radeonandlib32-libva-mesa-driverare installed.
- If you prefer Wayland, XWayland will run X11 apps; keep mesaand 32-bit libs installed for compatibility.
Many useful packages for gaming and desktop use are in the AUR. Install yay as your AUR helper:
cd /tmp
git clone https://aur.archlinux.org/yay.git
cd yay
makepkg -si
cd ~Install and configure ufw (Uncomplicated Firewall):
sudo pacman -S ufw
sudo systemctl enable --now ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enableCheck status:
sudo ufw status verboseSince you already installed reflector, configure it to automatically update your mirrorlist:
sudo tee /etc/xdg/reflector/reflector.conf > /dev/null <<'EOF'
--save /etc/pacman.d/mirrorlist
--protocol https
--country India
--latest 10
--sort rate
EOFEnable the reflector timer:
sudo systemctl enable --now reflector.timerThis will automatically update your mirrors weekly.
If you're the only user and prefer automatic login to your desktop, you can configure SDDM to skip the login screen.
Security warning: Auto-login bypasses the login screen, meaning anyone with physical access to your computer can access your account. Only enable this on personal machines in secure environments.
Create or edit the SDDM configuration file:
sudo mkdir -p /etc/sddm.conf.d
sudo tee /etc/sddm.conf.d/autologin.conf > /dev/null <<'EOF'
[Autologin]
User=anirudh
Session=plasma
EOFReplace anirudh with your actual username. The Session=plasma value is for KDE Plasma; if you install a different desktop environment later, you may need to change this value.
To find available sessions:
ls /usr/share/xsessions/
ls /usr/share/wayland-sessions/For KDE Plasma on Wayland, you might use Session=plasmawayland instead.
Reboot to test:
rebootTo disable auto-login later, simply delete the configuration file:
sudo rm /etc/sddm.conf.d/autologin.conf- /etc/fstab: Double-check Btrfs mount options — removing- discard=asyncis intentional.
- Snapshots ≠ Backups: Snapshots live on same disk — keep off-device backups for important data.
- If GRUB fails after updates: Rebuild /boot/grub/grub.cfgand ensure ESPs are mounted when doing so.
- Gaming performance: For competitive gaming, consider lowering vm.swappinessto 60-100 for more responsive performance.
- Microcode updates: The intel-ucodepackage provides CPU microcode updates. GRUB should automatically detect and load it.
I hope that whoever is following this guide now has a fully functional Arch Linux system!