You press the power button and stare at the logo for forty seconds
The fans spin up. The disk light blinks. The login screen refuses to appear. You are not stuck. The system is just waiting for something to finish before it hands you control. A slow Fedora boot is almost always caused by one or more services taking too long to start, a long GRUB timeout, or Plymouth waiting for hardware that is slow to initialize. You need to find the exact bottleneck before you change anything.
What is actually happening
Fedora uses systemd to start services. systemd does not run everything at once. It builds a dependency tree and starts units in parallel whenever possible. When one unit hangs or waits for hardware that is slow to initialize, the entire chain pauses. Plymouth hides the terminal output behind a splash screen, so you never see which service is blocking the queue. The delay is usually a single service timing out, a GRUB menu counting down unnecessarily, or a filesystem check running because the disk was not unmounted cleanly.
Think of the boot process like an assembly line. Most workers operate simultaneously. If one worker is waiting for a part that never arrives, the whole line stops. systemd enforces strict ordering rules to prevent race conditions. Those rules are necessary for stability, but they occasionally create artificial delays when a service is misconfigured or polling for hardware that does not exist.
Run journalctl -xe after a slow boot. The x flag adds explanatory context and the e flag jumps to the end. Most sysadmins type this muscle-memory style to catch timeout messages. Read the actual error before guessing.
Profile the boot
You need to see exactly where the time goes before you change anything. Guessing breaks systems. Measuring fixes them.
Run the baseline measurement first. This command prints the total time systemd spent loading the kernel, initializing hardware, and starting services.
systemd-analyze
# WHY: Shows the split between firmware, loader, kernel, and initramfs times.
# WHY: Helps you distinguish between a slow disk and a slow service.
# WHY: Establishes a baseline so you can verify improvements later.
Next, find the slowest units. This command lists every service and target sorted by how long they took to activate.
systemd-analyze blame
# WHY: Sorts units by activation time in descending order.
# WHY: The top three lines usually contain your bottleneck.
# WHY: Ignores units that started instantly or are masked.
Finally, trace the dependency chain. This command shows the exact path of units that delayed reaching the graphical login screen.
systemd-analyze critical-chain graphical.target
# WHY: Reveals which parent unit forced the delay.
# WHY: Shows if a service is waiting on a network interface or a storage mount.
# WHY: Exposes hidden dependencies that blame does not show.
The output will look like a tree diagram. Look for the longest branch. If a service appears at the top of the chain, it is blocking everything downstream.
graphical.target @3.452s
└─multi-user.target @3.452s
└─NetworkManager-wait-online.service @2.101s +1.345s
└─NetworkManager.service @1.890s +200ms
└─dbus.service @1.850s
└─basic.target @1.840s
Run systemd-analyze blame first. Follow the longest chain. Do not touch services that take less than two seconds.
Disable slow or unnecessary services
Once you identify a unit taking more than ten seconds, verify whether your hardware actually needs it. Do not disable units blindly. A botched service removal can leave you without network or sound.
Check the unit state and recent logs first. This command shows whether the service is active, failed, or inactive, plus the last ten log lines.
systemctl status ModemManager.service
# WHY: Confirms the service is not currently handling active connections.
# WHY: Shows recent journal entries to verify it is just polling for hardware.
# WHY: Prevents you from disabling a service that is actively managing your connection.
If the service is safe to remove, disable it and stop it immediately. This command prevents the unit from starting on the next boot and kills the current process.
sudo systemctl disable --now ModemManager.service
# WHY: Removes the symlink from the systemd target directory.
# WHY: The --now flag stops the running instance without a second command.
# WHY: Leaves a clean audit trail in the systemd journal.
Common culprits on modern desktops include bluetooth.service on machines without a radio, ModemManager.service on systems without cellular hardware, and NetworkManager-wait-online.service on single-interface workstations. The wait-online service blocks the boot until the network is fully configured. Most desktop users do not need the network available before the login screen appears. NetworkManager will finish configuring the interface in the background anyway.
Edit configuration files in /etc/. Never edit files in /usr/lib/. Files in /usr/lib/ ship with the package and get overwritten on the next dnf upgrade --refresh. Files in /etc/ survive updates and take precedence. Use systemctl edit <unit> to create safe drop-in overrides. Future-you will thank you.
Reduce the GRUB timeout
If you only run Fedora and never dual-boot, the five-second GRUB countdown is pure dead air. The bootloader waits for a keypress that will never come.
Open the default configuration file. This file controls the bootloader behavior before the kernel loads.
sudo nano /etc/default/grub
# WHY: Opens the human-readable configuration template.
# WHY: Changes here do not apply until you regenerate the binary config.
# WHY: Keeps your customizations separate from package-managed defaults.
Find the GRUB_TIMEOUT line and change the value to 1. Save the file and regenerate the bootloader configuration. This command reads the template and writes the final configuration to the boot partition.
sudo grub2-mkconfig -o /boot/grub2/grub.cfg
# WHY: Compiles the template into the actual GRUB configuration.
# WHY: The -o flag specifies the output path for BIOS systems.
# WHY: Applies your timeout change to the next boot cycle.
On EFI systems, the output path is usually /boot/efi/EFI/fedora/grub.cfg. Check which path exists on your machine before running the command. A missing output file will break the boot menu entirely. Fedora's release cadence is six months. The N-2 release goes EOL when N+1 ships. Plan your bootloader updates alongside your major release upgrades to avoid configuration drift.
Always regenerate the config after touching GRUB settings. The bootloader ignores the template file.
Check for filesystem issues
A dirty filesystem triggers an automatic fsck on every boot. The check can add tens of seconds, especially on large ext4 or btrfs volumes. This happens when the system crashes, loses power, or fails to unmount cleanly.
Check the mount count and check interval for your root partition. This command reads the ext4 superblock metadata.
sudo tune2fs -l /dev/nvme0n1p3 | grep -i 'mount count\|check interval'
# WHY: Shows how many times the filesystem has been mounted since the last check.
# WHY: Reveals the forced check interval in days or mounts.
# WHY: Helps you determine if the filesystem is triggering checks prematurely.
If the count is high or the interval is set to zero, run a manual filesystem check from a live USB environment. Do not run fsck on a mounted root filesystem. Running it on a live system prevents data corruption and avoids the boot-time penalty. Snapshot the system before the upgrade. Future-you will thank you.
Verify it worked
Reboot the machine and run the baseline measurement again. Compare the total time to your previous run.
systemd-analyze
# WHY: Confirms the total boot time dropped after your changes.
# WHY: Validates that no new dependencies were introduced.
# WHY: Gives you a hard number to track over time.
If the time did not improve, check the journal for new timeout messages. Services sometimes restart themselves or trigger fallback chains when disabled. Trust the package manager. Manual file edits drift, snapshots stay.
Common pitfalls and what the error looks like
Disabling systemd-journald.service or systemd-logind.service will drop you to an emergency shell. You will see Dependency failed for Graphical Interface. followed by a prompt asking you to press Enter to continue. Press Enter, fix the service with sudo systemctl enable <unit>, and reboot.
Editing /usr/lib/systemd/system/ directly creates a drift problem. Package updates will overwrite your changes. Always use systemctl edit <unit> or place overrides in /etc/systemd/system/. The override directory takes precedence and survives upgrades.
Forgetting to run grub2-mkconfig after editing /etc/default/grub means your timeout change never applies. The bootloader ignores the template file. Always regenerate the config after touching GRUB settings.
If you see [FAILED] Failed to start NetworkManager-wait-online.service during boot, your network configuration probably references a missing interface name. Check /etc/NetworkManager/conf.d/ for stale device rules. Run journalctl -xeu NetworkManager-wait-online.service to isolate the exact interface causing the timeout.
Reboot before you debug. Half the time the symptom is gone.
When to use this vs alternatives
Use systemd-analyze blame when you need to identify which service is consuming the most startup time. Use systemd-analyze critical-chain when you need to see the dependency path causing the delay. Use systemctl disable --now when you want to permanently remove a service from the boot sequence. Use grub2-mkconfig when you change bootloader settings and need to apply them to the disk. Use a live USB fsck when the root filesystem is marked dirty and blocking the boot. Stay on the default systemd configuration if your boot time is under fifteen seconds and you only want minor tweaks.