How to Analyze Boot Time with systemd-analyze on Fedora

Use systemd-analyze commands to measure total boot time and identify slow services on Fedora.

You press the power button and watch the Fedora logo spin for forty seconds

Six months ago it took ten. You open a terminal, type systemd-analyze, and stare at a breakdown that says userspace: 38.213s. That number tells you nothing about which service is actually holding up the line. The boot process is not a checklist. It is a dependency graph that fans out in parallel, and one stubborn unit can block the entire desktop session. You need to find the exact service delaying the login screen, understand why it is waiting, and safely remove it from the critical path.

What's actually happening

Systemd does not boot services in alphabetical order. It reads unit files, builds a directed acyclic graph, and starts everything that has no pending dependencies at the same time. The systemd-analyze tool measures four distinct phases. Firmware handles the BIOS or UEFI handoff. Loader covers GRUB or systemd-boot. Kernel measures the time from decompression until the root filesystem mounts. Userspace covers everything after the init process takes over. When you see a long userspace time, the bottleneck is almost always a service waiting on a network interface, a storage device that never appeared, or a legacy compatibility layer polling for hardware that does not exist.

The tool reports monotonic time, not wall-clock time. Monotonic time ignores system clock adjustments and sleep states. It measures the exact duration from when the kernel hands control to systemd until the target you specify reaches an active state. This matters because a machine that sleeps during boot will report accurate service durations even if the hardware clock was wrong. You are looking for the unit that sits at the end of the longest dependency chain. That unit dictates when the graphical target can start. Everything else runs in parallel and does not affect your perceived boot speed.

Run journalctl -b first. Read the actual error before guessing.

The fix or how-to

Start by establishing a baseline. Run the base command to see the phase breakdown.

systemd-analyze time
# Shows the exact wall-clock duration for each boot phase
# Helps you confirm whether the delay lives in firmware, kernel, or userspace
# The firmware and loader times are hardware dependent and rarely tunable

If userspace dominates the timeline, you need the blame list. This command sorts every loaded unit by how long it took to reach the active state.

systemd-analyze blame
# Lists units sorted by activation duration in descending order
# Focus on the top five entries. Ignore timers that show 0s.
# Units with names ending in .timer are scheduled tasks, not boot blockers.
# Services showing 10s+ are usually waiting on external conditions.

The blame list shows duration, but it does not show dependencies. A service might take two seconds to start, but if it sits at the top of a chain that blocks the display manager, those two seconds feel like twenty. The critical chain command maps the exact path from systemd to the graphical target.

systemd-analyze critical-chain graphical.target
# Traces the dependency tree that determines the boot deadline
# Each line shows the unit name and the time it waited for its parent
# Look for the longest gap between parent and child. That gap is your bottleneck.
# The indentation reveals the exact dependency hierarchy systemd resolved.

You will often see systemd-logind.service or NetworkManager-wait-online.service sitting at the end of the chain. These are not broken. They are waiting for conditions that your hardware does not trigger quickly. Fedora ships with NetworkManager-wait-online enabled by default to guarantee network availability for cloud images and servers. On a desktop, it usually just stalls the login screen. Disable it if you only need network after you log in.

sudo systemctl disable --now NetworkManager-wait-online.service
# Stops the unit immediately and prevents it from starting on next boot
# The --now flag combines stop and disable into a single transaction
# sudo is required because unit management modifies system state
# The service will no longer block the graphical target.

Reboot before you debug. Half the time the symptom is gone.

Verify it worked

Once you identify the culprit, adjust the unit configuration. Disable the service if it is not required for your workflow. Reboot and run the blame command again. The duration should drop or the unit should disappear from the top of the list.

systemctl is-enabled NetworkManager-wait-online.service
# Returns "disabled" if the previous command succeeded
# Confirms the unit will not start automatically on next boot
# Use this instead of reading unit files manually.

Run the critical chain command again and compare the output to your baseline. The total time at the top of the tree should match your new userspace duration. If the chain still shows a long wait, check for secondary blockers like plymouth-quit-wait.service or systemd-user-sessions.service. These units often mask the real delay by waiting for the display manager to finish. Disable plymouth temporarily to see the raw text output and confirm the actual service order.

sudo systemctl mask plymouth-quit-wait.service
# Creates a symlink to /dev/null so systemd ignores the unit entirely
# Masking is safer than disabling when a unit is pulled in by multiple targets
# The boot splash will disappear, but you will see real service progress.

Trust the package manager. Manual file edits drift, snapshots stay.

Common pitfalls and what the error looks like

Boot time analysis trips up on three common illusions. The first is plymouth masking the real timeline. The graphical boot splash hides service failures and stalls. Disable it temporarily to see the raw text output. The second is measuring the wrong boot. systemd-analyze defaults to the current boot. If you want to compare against yesterday's session, you must specify the boot ID. The third is confusing activation time with execution time. A service might take ten seconds to start because it is waiting for a udev event, not because the binary is slow. The critical chain output shows the wait time explicitly. Read the parentheses. They tell you how long the unit sat idle before its dependencies resolved.

You will also encounter fake blockers like dev-disk-by\x2duuid-*.mount. These appear when a secondary drive is missing or sleeping. The system waits for the mount point to appear before proceeding. Add nofail to the fstab entry for non-essential drives. Never edit the raw unit files in /usr/lib/systemd/system/. Package updates will overwrite them. Create overrides in /etc/systemd/system/ instead. Use systemctl edit --full <unit> to generate a safe override directory. This keeps your changes isolated from upstream package management.

If you see [FAILED] Failed to start NetworkManager-wait-online.service during boot, your network configuration probably references a missing interface name. Check ip link and update the connection profile. SELinux denials will not block boot services, but they will show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Most boot delays are configuration issues, not security policy blocks.

Run journalctl first. Read the actual error before guessing.

When to use this vs alternatives

Use systemd-analyze time when you need to isolate which boot phase is consuming the most wall-clock seconds. Use systemd-analyze blame when you want a ranked list of every service and how long it took to reach an active state. Use systemd-analyze critical-chain when you need to trace the exact dependency path that delays the graphical login screen. Use journalctl -b -1 when you suspect a service crashed or failed during the previous boot cycle. Stay on the default systemd-analyze workflow if you only need to verify that a recent configuration change improved startup speed.

Where to go next