Systemd’s Role in Suspend/Resume

Systemd orchestrates Linux suspend and resume. From systemd-logind deciding when to sleep, to inhibitors blocking it, to pre/post scripts and sleep.conf tuning defaults, learn how systemd coordinates kernel and user-space for reliable power management.

Systemd’s Role in Suspend/Resume
Photo by Sebastian Pociecha / Unsplash

Introduction

On a modern Linux system, the kernel and firmware (ACPI tables in BIOS/UEFI) define the low-level mechanics of power management, but it’s systemd that orchestrates the user-space side. It’s the conductor telling each player when to stop, when to resume, and which notes to hit.

Without systemd’s coordination, suspend and resume would be a chaotic mix of unflushed filesystems, half-dead drivers, and applications waking up to a broken environment.

This post explains how systemd fits into the suspend/resume path, focusing on systemd-logind, inhibitors, configuration files, and the system-sleep hook mechanism.

1. Why Systemd Is In the Middle

The Linux kernel knows how to enter S3 (“suspend to RAM”) or S4 (“hibernate”), but it does not know when. That decision belongs to user space, which is responsible for:

  • Respecting user preferences (power button behavior, lid close).
  • Allowing apps to temporarily block suspend (video player, conference call).
  • Running pre-sleep and post-wake scripts to keep hardware consistent.
  • Choosing the right low-power state (S3 vs S4 vs hybrid).

Systemd provides all of these via systemd-logind and systemd-sleep.

2. systemd-logind: The Authority

At the heart of systemd’s power management is systemd-logind, a daemon started at boot. It watches:

  • Lid switches (/proc/acpi/button/lid or evdev events).
  • Power keys and suspend keys.
  • Idle timers.

When one of these triggers occurs, logind checks:

  1. Is the user authorized to suspend?
  2. Is an inhibitor active that should prevent suspend?
  3. What’s the configured default action (suspend, hibernate, hybrid)?

Only if all checks pass does logind call systemctl suspend (or hibernate, etc.), which then invokes the kernel’s pm_suspend().

3. Inhibitors: Applications Can Say “Not Now”

Systemd exposes an inhibitor API so applications can temporarily block suspend.
This prevents your laptop from suspending while:

  • A video is playing full-screen.
  • A critical firmware update is in progress.
  • You’re burning a DVD or writing to external storage.

Using systemd-inhibit

An application can run itself under systemd-inhibit:

systemd-inhibit --what=sleep --why="Critical update" myscript.sh

As long as myscript.sh runs, logind refuses to suspend.
Inhibitors can also be transient (removed automatically when the process ends).

You can list active inhibitors:

systemd-inhibit --list

This gives you a table showing which apps are blocking sleep.

[ add the output ]

4. /etc/systemd/sleep.conf: Global Defaults

This file sets the default sleep mode. Examples:

[Sleep]
SuspendMode=mem
HibernateMode=disk
HybridSleep=yes
  • SuspendMode= determines which kernel sleep mode is used for “suspend” (commonly mem → S3).
  • HibernateMode= chooses how hibernation works (often platform or shutdown).
  • HybridSleep= enables the “write RAM to disk + suspend” mode.

If you never touch this file, your distro ships sane defaults. But for fine-tuning (e.g., forcing hibernate instead of suspend when the lid closes), this is the knob to turn.

5. The system-sleep Hook Mechanism

Systemd runs any executable scripts placed in:

/usr/lib/systemd/system-sleep/

These scripts are called twice:

  • With argument pre just before the kernel actually cuts power.
  • With argument post immediately after resume.

This is your opportunity to:

  • Unmount or sync special filesystems.
  • Turn off LEDs or backlights.
  • Unload drivers that don’t survive suspend.
  • Re-initialize hardware on resume.

Many distributions already ship some hooks — for example, nvidia-sleep.sh to unload and reload NVIDIA drivers.

Example: Pre-Sleep Script

#!/bin/sh
# Example: unload the NVIDIA kernel module before suspend
if [ "$1" = "pre" ]; then
    modprobe -r nvidia_drm nvidia_modeset nvidia
fi

This prevents the NVIDIA kernel module from hanging on resume.

Example: Post-Wake Script

#!/bin/sh
# Reload the NVIDIA driver after resume
if [ "$1" = "post" ]; then
    modprobe nvidia
    modprobe nvidia_modeset
    modprobe nvidia_drm
fi

This ensures the NVIDIA GPU is usable again after waking.

6. Step by Step: How systemd Handles Suspend

  1. User triggers suspend (lid close, power button, or systemctl suspend).
  2. systemd-logind checks inhibitors. If any block sleep, it cancels the request.
  3. Pre-sleep scripts run from /usr/lib/systemd/system-sleep/ with argument pre.
  4. systemd calls kernel pm_suspend() which starts the ACPI _S3 or _S4 sequence.
  5. Kernel + drivers handle the hardware, freezing user space and powering down devices.
  6. Hardware enters low-power state.

On my Dell XPS 15 9550 with Ubuntu 25.04 I have the following scripts:

drwxr-xr-x  2 root root  4096 Sep 14 23:03 .
drwxr-xr-x 23 root root 12288 Sep 20 23:06 ..
-rwxr-xr-x  1 root root    92 Oct  6  2022 hdparm
-rwxr-xr-x  1 root root  1363 Aug 27 20:59 nvidia
-rwxr-xr-x  1 root root   231 Aug 15  2024 sysstat.sleep
-rwxr-xr-x  1 root root   219 Feb 18  2025 unattended-upgrades

7. Step by Step: How systemd Handles Resume

  1. Wake event (lid open, key press, network packet) triggers firmware to restore power rails.
  2. Kernel resumes first, restoring interrupts and device state using _ON and driver callbacks.
  3. systemd runs post-wake scripts from /usr/lib/systemd/system-sleep/ with argument post. This is where you reload modules, restart daemons, re-enable services.
  4. systemd-logind signals user space thaw. Processes resume from where they paused.
  5. Desktop reappears. Wi-Fi reconnects, GPU modes restored, and everything looks normal to the user.

8. Putting It All Together

  • Kernel + ACPI: low-level power mechanics.
  • systemd-logind: decides when suspend/hibernate happens.
  • Inhibitors: let applications veto suspend temporarily.
  • /etc/systemd/sleep.conf: sets default sleep mode.
  • system-sleep scripts: let admins run pre/post actions.

This layered approach keeps Linux flexible and robust. You can tune global defaults, add custom scripts, or even build daemons that programmatically inhibit suspend during critical work.

9. Best Practices

  • Always test suspend and resume after installing proprietary drivers.
  • Place custom scripts in /usr/lib/systemd/system-sleep/ or /etc/systemd/system-sleep/ with correct permissions.
  • Use systemd-inhibit --list to troubleshoot unexpected “refusal to sleep.”
  • Keep firmware and kernel updated for better ACPI compliance.

Conclusion

Systemd is not just an init system; it’s the traffic controller of your Linux laptop’s sleep/wake life cycle. By understanding how systemd-logind, inhibitors, sleep.conf, and system-sleep scripts work together, you gain full control over suspend/resume behavior.

Whether you’re trying to stop your laptop from sleeping during a presentation, fixing a GPU that misbehaves after resume, or fine-tuning hibernate for battery life, knowing systemd’s role in suspend/resume makes you far more effective at managing Linux power states.

Read next