systemd Service Dependency Calculator
Calculate systemd unit startup order and dependency chain resolution time.
Inputs
e.g. network.target, then disk mount, then database service, etc.
Units that start concurrently and don't block the sequential chain
Critical Path Time (ms)
7,000
Bottleneck Source
sequential dependency chain
Sequential Chain Total (ms)
7,000
Slowest Unit in Chain (ms)
3,500
Slowest Unit's Share of Chain Time
50.0%
Step by step
Values used
Sequential Chain Unit Start Times (ms, comma-separated, in dependency order) = 1200, 800, 3500, 600, 900; Parallel (independent) Units Alongside the Chain (ms, comma-separated) = 400, 2200, 150
Critical path
critical_path = max(sum(sequential_chain_times), max(parallel_unit_times))
Critical Path Time (ms)
= 7,000
Bottleneck Source
= sequential dependency chain
Sequential Chain Total (ms)
= 7,000
Slowest Unit in Chain (ms)
= 3,500
Slowest Unit's Share of Chain Time
= 50.0
How it works
systemd starts units in parallel wherever dependency ordering (After=/Before=/Requires=/Wants=) allows, so total boot time isn't the sum of every unit's start time — it's the length of the longest dependency chain (the critical path), the same concept `systemd-analyze critical-path` reports directly from real boot data. Units with no dependency relationship to a slow chain start concurrently and don't add to total time unless one of them individually takes longer than the chain itself; this calculator models a simple sequential chain (units that must start one after another) alongside independent parallel units, and reports whichever path is actually the bottleneck.
Formula
Critical path
critical_path = max(sum(sequential_chain_times), max(parallel_unit_times))
- s_i
- start time of unit i in the sequential chain
- p_j
- start time of independent parallel unit j
Frequently Asked Questions
How do I find the actual critical path on a real system?
`systemd-analyze critical-path` prints the actual chain of units that determined total boot time, and `systemd-analyze blame` lists every unit sorted by how long it individually took to initialize — the former shows what limited boot time, the latter shows what was simply slow (which may or may not have been on the critical path).
Why would optimizing the slowest unit not always speed up boot?
If that slow unit runs in parallel alongside an even slower dependency chain, it's not actually the bottleneck — speeding it up won't reduce total boot time until the chain it's racing against is also addressed. This is exactly why `systemd-analyze blame`'s 'slowest unit' list and `critical-path`'s actual bottleneck chain can point to different units.
Can I visualize the full boot dependency graph?
`systemd-analyze plot > boot.svg` generates a full Gantt-chart-style SVG showing every unit's start/finish time and overlap, which is the most complete way to see parallelism and identify unexpected serialization between units that shouldn't need to block each other.