Checking a service's dependencies with systemctl shows which other units systemd pulls in, waits for, or orders ahead of the service before startup. That dependency view is often the fastest way to explain slow starts, unexpected activation chains, or a service that behaves differently after another unit changes.
systemd builds that graph from the unit file, any drop-in overrides, and implicit relationships it adds while loading the unit. Pull-in directives such as Requires=, Wants=, Requisite=, and BindsTo= answer which units are tied to the service, while After= and Before= answer when those units may start relative to each other.
The list-dependencies view only shows units currently loaded into memory by the service manager, so unloaded reverse relationships do not appear until something loads them. Socket-, timer-, and path-activated services may also depend more directly on their companion units than on the service unit alone, so checking the trigger unit can matter when the service itself is inactive.
$ systemctl show -p Requires -p Wants -p Requisite -p BindsTo -p PartOf -p Conflicts -p After -p Before ssh.service Requires=system.slice sysinit.target ssh.socket Requisite= Wants= BindsTo= PartOf= Conflicts=shutdown.target Before=shutdown.target After=sysinit.target system.slice network.target -.mount systemd-journald.socket basic.target auditd.service ssh.socket
Requires=, Wants=, Requisite=, and BindsTo= describe requirement relationships. After= and Before= are separate ordering rules and do not pull units in by themselves.
Replace ssh.service with the exact unit name being investigated, including suffixes such as .service, .socket, .timer, or .target.
$ systemctl --no-pager list-dependencies --all --plain --full ssh.service | sed -n '1,10p' ssh.service ssh.socket system.slice -.slice sysinit.target systemd-tmpfiles-setup-dev-early.service local-fs-pre.target systemd-tmpfiles-setup-dev.service systemd-tmpfiles-setup.service local-fs.target
–all expands dependencies beyond target units, and –plain removes tree glyphs so the output is easier to copy into notes, tickets, or change records.
This tree is limited to units currently loaded into memory by systemd. A unit that has not been loaded yet will not appear in the reverse view even if its unit file declares a relationship.
$ systemctl --no-pager list-dependencies --after --all --plain --full ssh.service | sed -n '1,12p' ssh.service -.mount -.slice auditd.service ssh.socket system.slice sysinit.target dev-mqueue.mount systemd-journald.socket modprobe@dm_mod.service system-modprobe.slice modprobe@drm.service
With list-dependencies, –after shows units ordered before the specified unit, while –before shows units ordered after it.
$ systemctl --no-pager cat ssh.service | sed -n '1,16p' # /usr/lib/systemd/system/ssh.service [Unit] Description=OpenBSD Secure Shell server Documentation=man:sshd(8) man:sshd_config(5) After=network.target auditd.service ConditionPathExists=!/etc/ssh/sshd_not_to_be_run [Service] EnvironmentFile=-/etc/default/ssh ExecStartPre=/usr/sbin/sshd -t ExecStart=/usr/sbin/sshd -D $SSHD_OPTS ExecReload=/usr/sbin/sshd -t ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartPreventExitStatus=255
systemctl cat prints the vendor unit file followed by any drop-ins from /etc/systemd/system/<unit>.d/, which makes it easier to see whether a dependency came from the packaged unit or from a local override.
$ systemctl is-active ssh.socket system.slice sysinit.target systemd-journald.socket basic.target active active active active active
Pick units from the Requires=, Wants=, or After= output that are directly relevant to the startup path being investigated.
A unit listed only in After= is not necessarily a hard requirement. Treat an inactive dependency as a blocker only when it is also tied in by Requires=, Requisite=, BindsTo=, or by the workflow the service actually needs to complete.
$ systemctl --no-pager list-dependencies --reverse --plain --full ssh.socket | sed -n '1,7p' ssh.socket ssh.service sockets.target basic.target initrd.target multi-user.target graphical.target
Reverse checks are especially useful for socket-, timer-, and path-activated workloads because the trigger unit often explains why the service appears unexpectedly.