Maintenance
Routine maintenance tasks for both systems, including garbage collection, store optimisation, SSD maintenance, and monitoring.
Garbage Collection
Laptop
Managed automatically by nh:
programs.nh.clean = {
enable = true;
dates = "weekly";
extraArgs = "--keep-since 3d --keep 3";
};- Runs weekly as a systemd timer
- Removes generations older than 3 days
- Always keeps at least 3 generations
Manual GC:
# Dry run to see what would be removed
nix store gc --dry-run
# Actually collect garbage
nix store gcServer
nix.gc = {
automatic = true;
dates = "weekly";
options = "--delete-older-than 7d";
};- Runs weekly
- Removes all generations older than 7 days
- No minimum generation count (the server should always be on the latest)
Store Optimisation
Both systems enable automatic store optimisation:
nix.optimise = {
automatic = true;
dates = [ "weekly" ];
};
nix.settings.auto-optimise-store = true;| Setting | Effect |
|---|---|
nix.optimise.automatic | Runs nix store optimise weekly (deduplicates store paths via hardlinks) |
auto-optimise-store | Optimises new paths as they're added to the store |
Both are enabled for belt-and-suspenders deduplication. The weekly job catches any paths that were added without optimisation.
SSD Maintenance (fstrim)
Both systems enable weekly TRIM:
services.fstrim = {
enable = true;
interval = "weekly";
};This runs fstrim -av weekly, which informs the SSD firmware about unused blocks, maintaining write performance and extending drive lifespan.
Server I/O Schedulers
The server sets I/O schedulers per device type via udev rules:
services.udev.extraRules = ''
# HDD
ACTION == "add|change", KERNEL=="sd[a-z]*", ATTR{queue/rotational}=="1", \
ATTR{queue/scheduler}="bfq"
# SSD
ACTION=="add|change", KERNEL=="sd[a-z]*|mmcblk[0-9]*", ATTR{queue/rotational}=="0", \
ATTR{queue/scheduler}="mq-deadline"
# NVMe SSD
ACTION=="add|change", KERNEL=="nvme[0-9]*", ATTR{queue/rotational}=="0", \
ATTR{queue/scheduler}="none"
'';| Device Type | Scheduler | Rationale |
|---|---|---|
| HDD (rotational) | bfq | Budget Fair Queuing; optimises for latency with rotating media |
| SATA SSD | mq-deadline | Simple deadline scheduler; good for SATA SSDs with limited parallelism |
| NVMe SSD | none | NVMe handles its own queuing; any software scheduler adds overhead |
Systemd Timers Overview
All automated maintenance tasks are systemd timers. To see the full schedule:
systemctl list-timers --allServer Timers
| Timer | Schedule | Service |
|---|---|---|
nixos-upgrade.timer | Weekly | System auto-upgrade |
restic-backups-backup.timer | Daily | Restic backup |
nix-gc.timer | Weekly | Nix garbage collection |
nix-optimise.timer | Weekly | Nix store optimisation |
fstrim.timer | Weekly | SSD TRIM |
Laptop Timers
| Timer | Schedule | Service |
|---|---|---|
nh-clean.timer | Weekly | Generation cleanup |
nix-optimise.timer | Weekly | Nix store optimisation |
fstrim.timer | Weekly | SSD TRIM |
Disk Usage Monitoring
# Check overall disk usage
df -h
# Check Nix store size
du -sh /nix/store
# Check number of store paths
ls /nix/store | wc -l
# Check Restic repository size (server)
du -sh /backup
# Check persistent data size (server)
du -sh /persist/*Server-Specific Maintenance
Impermanence Cleanup
Old root subvolumes are automatically cleaned up during the boot rollback script. Subvolumes older than 30 days are deleted:
for i in $(find /btrfs_tmp/old_roots/ -maxdepth 1 -mtime +30); do
delete_subvolume_recursively "$i"
doneNo manual intervention needed.
Container Health
# List running containers
machinectl list
# Check a specific container's status
machinectl status traefik
# View container logs
journalctl -M traefik -f
# Restart a container
sudo machinectl restart traefikChecking for Failed Services
# List all failed units
systemctl --failed
# On the server, also check inside containers
for c in traefik authelia adguard immich vaultwarden opencloud; do
echo "=== $c ==="
machinectl shell $c /run/current-system/sw/bin/systemctl --failed
doneMinimal Server Packages
The server intentionally ships very few packages to minimise attack surface:
environment.systemPackages = with pkgs; [
btop # System monitor
yazi # File manager
helix # Text editor
lynis # Security auditor
agenix # Secrets management CLI
];Documentation, fonts, XDG, man pages, and the dynamic linker stub are all disabled. See Server Overview for the full list of disabled features.