systemd-analyze reports timing and dependency information collected by the systemd manager. It can measure the current boot, rank unit activation times, identify the time-critical dependency chain, create an SVG timeline, and validate unit files.
Official references:
Establish a Baseline
Confirm that systemd is the active service manager and record its version.
ps -p 1 -o pid,comm,args
systemd-analyze --version
systemctl get-default
Measure the current boot.
systemd-analyze time
Running systemd-analyze without a subcommand is equivalent.
systemd-analyze
A typical result separates several phases:
Startup finished in 6.112s (firmware) + 1.834s (loader) + 3.927s (kernel) + 4.215s (initrd) + 8.406s (userspace) = 24.495s
graphical.target reached after 8.102s in userspace
| Phase | Meaning |
|---|---|
| Firmware | UEFI or system firmware initialization |
| Loader | Bootloader time before starting the kernel |
| Kernel | Kernel initialization before the initrd or system manager |
| Initrd | Initial RAM filesystem initialization |
| Userspace | Systemd unit activation up to the reported target |
Firmware and loader timings are available only on supported boot environments. Containers usually report userspace time only.
The total does not mean that every application is fully initialized or that disks and network services are idle. It measures elapsed time until systemd has spawned the services required by the target and those jobs have reached the states systemd considers started.
For meaningful comparisons, measure several cold boots under similar conditions. Firmware caches, filesystem caches, pending updates, network availability, and attached hardware can change the result.
Rank Unit Activation Times
List loaded units by the time they spent activating.
systemd-analyze blame
Show the first 30 entries without opening a pager.
systemd-analyze blame --no-pager | head -n 30
Treat this list as a set of candidates rather than proof of causation:
- Services start in parallel, so several long activations may overlap.
- A service can appear slow because it waits for another service, device, mount, or network event.
- Units that move directly from inactive to active may not have a measurable activating period.
Type=simpleservices are considered started immediately and normally do not show their real application initialization time.- The list measures activation time, not time spent waiting in systemd’s job queue.
Inspect the dependencies and logs before disabling or modifying a high-ranking unit.
Find the Critical Chain
Display the time-critical dependency chain for the default target.
systemd-analyze critical-chain
Analyze the chain leading to a specific service.
systemd-analyze critical-chain nginx.service
Analyze the chain leading to the graphical target explicitly.
systemd-analyze critical-chain graphical.target
In the output, @ shows when a unit became active relative to boot, and + shows how long that unit spent activating.
graphical.target @8.102s
└─multi-user.target @8.101s
└─example.service @3.400s +4.699s
Use --fuzz to include nearby branches that completed shortly before the latest dependency at each level.
systemd-analyze critical-chain --fuzz=1s
The critical chain also has limits. Socket activation, parallel execution, and jobs that never enter a measurable activating state can make the output incomplete. It does not display every timeout or every possible dependency branch.
Create a Boot Timeline
Generate an SVG chart showing unit activation across the boot timeline.
systemd-analyze plot > boot.svg
Open boot.svg in a browser or vector-image viewer. The chart makes overlapping unit activations easier to see and helps distinguish one long critical path from several unrelated background operations.
Check that the output is an SVG document before sharing it.
file boot.svg
Recent systemd versions can also print the plot data as a table.
systemd-analyze plot --table
If --table is unavailable on the installed version, use the SVG output.
Graph Unit Dependencies
The dot command generates a dependency graph in Graphviz format. Install Graphviz first if the dot renderer is missing.
On Ubuntu or Debian:
sudo apt update
sudo apt install -y graphviz
Render the complete dependency graph as SVG. A full system graph can be very large.
systemd-analyze dot | dot -Tsvg > systemd-dependencies.svg
Limit the graph to relationships leading to one service.
systemd-analyze dot --to-pattern='nginx.service' | dot -Tsvg > nginx-dependencies.svg
Dependency graphs show declared relationships; they do not directly show which process consumed CPU, waited for storage, or stalled on an external network response.
Inspect Boot Logs with Monotonic Time
Display current-boot messages with timestamps measured from the start of the boot.
sudo journalctl -b -o short-monotonic
Show warnings and more severe messages from the current boot.
sudo journalctl -b -p warning --no-pager
Search for common timeout and dependency failures.
sudo journalctl -b --grep='timed out|A start job is running|Dependency failed|Failed to start' --case-sensitive=no
Inspect one candidate service.
systemctl status nginx.service --no-pager --full
sudo journalctl -u nginx.service -b -o short-monotonic --no-pager
Inspect kernel initialization separately.
sudo journalctl -k -b -o short-monotonic
List retained boots and read the previous boot’s logs.
journalctl --list-boots
sudo journalctl -b -1 -o short-monotonic
systemd-analyze reports live timing data from the current manager. Use retained journal entries and saved reports when comparing the current boot with an earlier one.
Inspect Unit Timing and Configuration
Display timestamps, result state, and the source unit file for a candidate service.
systemctl show nginx.service --property=ActiveEnterTimestamp,ActiveEnterTimestampMonotonic,InactiveExitTimestampMonotonic,ExecMainStartTimestampMonotonic,Result,FragmentPath,DropInPaths
Display the complete vendor unit and every applied drop-in.
systemctl cat nginx.service
Display direct and reverse dependencies.
systemctl list-dependencies nginx.service --all
systemctl list-dependencies nginx.service --reverse
Remember that dependency and ordering directives have different roles. Wants= and Requires= describe dependency strength, while After= and Before= determine order when both units participate in the same transaction.
Check for Failed Units
List units in the failed state.
systemctl --failed
Inspect one failure and its journal.
systemctl status example.service --no-pager --full
sudo journalctl -u example.service -b -n 100 --no-pager
A failed unit does not always delay the critical path, but repeated retries, dependency timeouts, and required units can extend boot time.
Validate Unit Files
Verify a custom or modified unit before reloading systemd.
sudo systemd-analyze verify /etc/systemd/system/example.service
After a manual edit, reload the manager and restart the affected service.
sudo systemctl daemon-reload
sudo systemctl restart example.service
Use systemctl edit for local overrides of package-provided units so upgrades do not replace the changes.
sudo systemctl edit example.service
Analyze the User Service Manager
Desktop startup can continue after the system target is reached. Analyze services belonging to the current user separately.
systemd-analyze --user time
systemd-analyze --user blame
systemd-analyze --user critical-chain
systemctl --user --failed
These commands require an active user systemd manager and describe user units rather than system services.
Investigate Network Wait Services
Network-online wait services are common near the top of a blame list. Before disabling one, find which units require network-online.target.
systemctl list-dependencies network-online.target --reverse
Inspect the active wait implementation and its logs. The unit name depends on the network manager.
systemctl status systemd-networkd-wait-online.service --no-pager --full
sudo journalctl -u systemd-networkd-wait-online.service -b --no-pager
For NetworkManager-based systems:
systemctl status NetworkManager-wait-online.service --no-pager --full
sudo journalctl -u NetworkManager-wait-online.service -b --no-pager
Do not disable a wait-online service until you confirm that no required mount, database, backup, or application needs a usable network during boot. Correcting an unused interface, DHCP timeout, or overly broad online requirement is safer than hiding the delay.
Optimize Boot Safely
Use this workflow for each proposed change:
- Record
systemd-analyze time,blame,critical-chain, failed units, and relevant boot logs. - Identify whether the delay belongs to firmware, bootloader, kernel, initrd, or userspace.
- Confirm that a slow userspace unit lies on the critical chain or blocks a required dependency.
- Read the unit file and journal to find the actual wait condition.
- Change one setting at a time with a drop-in or the application’s supported configuration.
- Reboot under comparable conditions and repeat the measurements.
- Restore the original setting if the improvement is not repeatable or removes required behavior.
Disable a service only after confirming that the machine does not need it.
sudo systemctl disable --now example.service
Socket- or timer-activated services may not need to start at boot. Inspect the related units before changing them.
systemctl list-dependencies example.service --reverse
systemctl list-unit-files 'example.*'
systemctl cat example.service
Avoid masking core system units as a performance experiment. Masking blocks manual and dependency-based activation and can make the system unusable.
Save a Report for Comparison
Create a directory and save the main reports after each test boot.
mkdir -p ~/boot-analysis
systemd-analyze time | tee ~/boot-analysis/time.txt
systemd-analyze blame --no-pager > ~/boot-analysis/blame.txt
systemd-analyze critical-chain --no-pager > ~/boot-analysis/critical-chain.txt
systemd-analyze plot > ~/boot-analysis/boot.svg
systemctl --failed --no-pager > ~/boot-analysis/failed-units.txt
sudo journalctl -b -p warning --no-pager > ~/boot-analysis/boot-warnings.txt
Record the kernel, systemd version, and boot ID with the report.
uname -a > ~/boot-analysis/system.txt
systemd-analyze --version >> ~/boot-analysis/system.txt
cat /proc/sys/kernel/random/boot_id >> ~/boot-analysis/system.txt
Some logs may contain hostnames, device identifiers, IP addresses, usernames, command arguments, or application data. Review the report before sharing it.
Troubleshooting
systemd-analyze blame Shows Almost Nothing
Confirm that the system booted with systemd as PID 1. Containers and WSL environments may not provide complete firmware, kernel, or service timing data. Services using Type=simple also do not expose meaningful activation duration.
ps -p 1 -o pid,comm,args
systemd-analyze time
A Long Service Is Missing from the Critical Chain
It may have started in parallel without delaying the target, been socket-activated, or never entered a measurable activating state. Inspect its timestamps, dependencies, and journal directly.
systemctl show example.service --property=ActiveEnterTimestampMonotonic,InactiveExitTimestampMonotonic,Result
systemctl list-dependencies example.service --all
sudo journalctl -u example.service -b -o short-monotonic
Userspace Is Fast but the Total Boot Is Slow
Look at the firmware, loader, kernel, and initrd fields in systemd-analyze time. Systemd service changes cannot reduce time spent before userspace. Firmware settings, device initialization, bootloader timeouts, storage detection, kernel messages, and initrd configuration require separate investigation.
systemd-analyze time
sudo journalctl -k -b -o short-monotonic
Results Change Substantially Between Boots
Repeat several cold boots with the same peripherals and network conditions. Check for DHCP delays, storage errors, update jobs, filesystem checks, and services that contact external systems during startup.
sudo journalctl -b -p warning --no-pager
systemd-analyze critical-chain