Disabling unnecessary services#

Why#

Every active service is either a potential source of latency (unpredictable CPU usage), an attack surface, or both. A reference time server should run with the strict minimum of active services, and some of them directly conflict with GNSS-dedicated hardware (the serial port, in particular).

How#

Serial port and time competitors#

# Bluetooth UART daemon (frees ttyAMA0 for the GNSS receiver)
systemctl disable --now hciuart

# System console on the serial port used by GNSS
systemctl disable --now serial-getty@ttyAMA0.service
systemctl mask serial-getty@ttyAMA0.service

# Competing system time daemon (chrony handles this)
systemctl disable --now systemd-timedated
systemctl disable --now systemd-timesyncd 2>/dev/null

Network discovery and unused radios#

systemctl disable --now avahi-daemon.service avahi-daemon.socket
systemctl disable --now bluetooth.service 2>/dev/null
systemctl disable --now wpa_supplicant.service 2>/dev/null
systemctl disable --now ModemManager.service 2>/dev/null

Fully disabling swap#

# 1) Immediate deactivation
swapoff /dev/zram0 2>/dev/null

# 2) Persistence: prevent the device from being generated on next boot
mkdir -p /etc/systemd
cat > /etc/systemd/zram-generator.conf <<'EOF'
# Stratum 1: zram disabled (no swap allowed)
EOF

# 3) Mask generated units, safety net
systemctl mask dev-zram0.swap
systemctl mask "systemd-zram-setup@zram0.service"
systemctl mask rpi-zram-writeback.timer 2>/dev/null
systemctl mask rpi-zram-writeback.service 2>/dev/null

systemctl daemon-reload
swapon --show   # should be empty

Keeping the fallback console#

# KEEP active: HDMI keyboard/screen access in case SSH is lost
systemctl enable --now getty@tty1.service

Pitfalls to avoid#

A plain swapoff doesn’t survive a reboot. Recent Pi OS distributions use zram (compressed swap dynamically generated in RAM on every boot by systemd-zram-generator), not the historical dphys-swapfile. Disabling the active device without neutralizing the generator means swap comes back on next reboot, silently, no error.

  • Disabling getty@tty1 “for security”. That’s a false good idea: without a fallback console, a network or SSH misconfiguration (an overly strict nftables rule, broken sshd) makes the server completely unreachable without physically pulling the SD card. An idle HDMI console costs nothing in resources.
  • Forgetting serial-getty@ttyAMA0. If this service stays active, it directly competes with the GNSS receiver for the serial port, both cannot use the same UART at once.

Verify#

systemctl list-units --type=service --state=running
# Review: no unexpected service should show up

swapon --show
systemctl list-units --type=swap --all
# Should show dev-zram0.swap "masked" or entirely absent

systemctl is-active getty@tty1.service
# Should return "active": the one console kept deliberately

ls -l /dev/ttyAMA0
# The port should be free for gpsd (GNSS/PPS acquisition chapter), not held by a getty

A disk swap, even compressed RAM swap, causes a page fault that can introduce millisecond-scale jitter during chrony’s clock discipline loop, unacceptable for a precision target around a microsecond. That’s why swap is entirely forbidden here rather than merely reduced.