Systemd is the system and service manager used by many modern Linux distributions. It is responsible for bringing the system to a usable state during boot, starting and stopping services, tracking dependencies, reading unit files, managing targets, and exposing tools such as systemctl, journalctl, and systemd-analyze.
If you are new to systemd, the most important idea is this: systemd manages units. A service is a unit, a target is a unit, a socket is a unit, and a timer is a unit. systemctl is the main command used to inspect and control those units.
The examples below were tested on an Ubuntu system running systemd 257. Your service names, default target, boot timings, and enabled units will be different.
systemctl status service, systemctl list-units, systemctl get-default, systemctl list-dependencies target, and journalctl -u service.
Quick Command Summary
| Task | Command |
|---|---|
| Check systemd version | systemctl --version |
| Check system state | systemctl is-system-running |
| Show default target | systemctl get-default |
| List active targets | systemctl list-units --type=target --state=active |
| List running services | systemctl list-units --type=service --state=running |
| List enabled services | systemctl list-unit-files --type=service --state=enabled |
| Check service status | systemctl status ssh.service |
| Show loaded unit file | systemctl cat ssh.service |
| Show dependencies | systemctl list-dependencies multi-user.target |
| Show service logs | journalctl -u ssh.service -n 50 |
| Validate a unit file | systemd-analyze verify file.service |
| Run transient service | systemd-run --unit=name command |
1. Check systemd Version and System State
Use systemctl --version to confirm the systemd version and enabled build features.
systemctl --versionTested output:
systemd 257 (257.4-1ubuntu3.2)
+PAM +AUDIT +SELINUX +APPARMOR +IMA +IPE +SMACK +SECCOMP +GCRYPT -GNUTLS +OPENSSL +ACL +BLKID +CURL +ELFUTILS +FIDO2 +IDN2 -IDN +IPTC +KMOD +LIBCRYPTSETUP +LIBCRYPTSETUP_PLUGINS +LIBFDISK +PCRE2 +PWQUALITY +P11KIT +QRENCODE +TPM2 +BZIP2 +LZ4 +XZ +ZLIB +ZSTD +BPF_FRAMEWORK +BTF -XKBCOMMON -UTMP +SYSVINIT +LIBARCHIVECheck the overall system state:
systemctl is-system-runningTested output:
degradeddegraded means at least one unit is failed or not healthy. It does not necessarily mean the system is unusable. Use systemctl --failed when you need to investigate failed units.
For a focused service-listing guide, see systemctl list services examples.
2. Understand systemd Unit Types
A systemd unit is a named object that systemd can manage. Unit names end with a suffix that shows the unit type.
| Unit type | Example | Purpose |
|---|---|---|
.service |
ssh.service |
A daemon or process managed by systemd |
.target |
multi-user.target |
A group of units or desired system state |
.socket |
ssh.socket |
Socket activation for a service |
.timer |
apt-daily.timer |
Time-based activation, similar to scheduled jobs |
.mount |
home.mount |
Filesystem mount unit |
.path |
cups.path |
Start a unit when a path changes |
.slice |
system.slice |
Resource-management grouping |
.scope |
transient scope | Externally created process grouping |
Unit files are plain text configuration files. Common system unit locations include:
/etc/systemd/system
/run/systemd/system
/usr/lib/systemd/system
/lib/systemd/system/etc/systemd/system is for local administrator changes and overrides. Distribution-provided units are usually under /usr/lib/systemd/system or /lib/systemd/system, depending on the distribution. For filesystem-related units, see mount a partition using systemd, mount filesystem without fstab using systemd, and mount filesystems in a specific order with systemd.
For command reference across Linux administration tasks, see the Linux commands cheat sheet.
3. List Active Targets
Targets group units into a desired state. For example, multi-user.target represents a non-graphical multi-user system state, while graphical.target includes graphical login/display services.
systemctl list-units --type=target --state=active --no-pagerTested output:
UNIT LOAD ACTIVE SUB DESCRIPTION
basic.target loaded active active Basic System
boot-complete.target loaded active active Boot Completion Check
cryptsetup.target loaded active active Local Encrypted Volumes
getty-pre.target loaded active active Preparation for Logins
getty.target loaded active active Login Prompts
graphical.target loaded active active Graphical Interface
integritysetup.target loaded active active Local Integrity Protected Volumes
local-fs-pre.target loaded active active Preparation for Local File Systems
local-fs.target loaded active active Local File Systems
multi-user.target loaded active active Multi-User System
network-online.target loaded active active Network is OnlineNotice that graphical.target and multi-user.target are both active on this host. Graphical systems commonly include the multi-user state as part of the boot dependency chain.
4. Check the Default Boot Target
The default target controls the state systemd tries to reach during boot.
systemctl get-defaultTested output:
graphical.targetShow details for default.target:
systemctl show -p Id -p Names -p FragmentPath -p UnitFileState default.targetTested output:
Id=graphical.target
Names=graphical.target default.target runlevel5.target
FragmentPath=/usr/lib/systemd/system/graphical.target
UnitFileState=staticThis system uses graphical.target as the default. If a server is configured to boot into multi-user.target, default.target normally points or aliases to multi-user.target. The target unit file itself is commonly stored under /usr/lib/systemd/system or /lib/systemd/system. If you are troubleshooting boot choices after a kernel change, see boot with an older kernel using grubby.
Show the multi-user.target unit file path:
systemctl show -p Id -p Description -p FragmentPath multi-user.targetTested output:
Id=multi-user.target
Description=Multi-User System
FragmentPath=/usr/lib/systemd/system/multi-user.targetFor boot recovery workflows, see boot into single-user mode in RHEL/CentOS and boot into rescue mode.
5. List Running Services
Use systemctl list-units to list active service units.
systemctl list-units --type=service --state=running --no-pagerTested output:
UNIT LOAD ACTIVE SUB DESCRIPTION
accounts-daemon.service loaded active running Accounts Service
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
colord.service loaded active running Manage, Install and Generate Color Profiles
containerd.service loaded active running containerd container runtime
cron.service loaded active running Regular background program processing daemon
cups-browsed.service loaded active running Make remote CUPS printers available locally
cups.service loaded active running CUPS Scheduler
dbus.service loaded active running D-Bus System Message Bus
docker.service loaded active running Docker Application Container Engine
fwupd.service loaded active running Firmware update daemon
gdm.service loaded active running GNOME Display Manager
gnome-remote-desktop.service loaded active running GNOME Remote Desktop
ModemManager.service loaded active running Modem ManagerUse this when you want to see currently running daemons. To see enabled services that start at boot, use systemctl list-unit-files.
systemctl list-unit-files --type=service --state=enabled --no-pagerTested output:
UNIT FILE STATE PRESET
accounts-daemon.service enabled enabled
anacron.service enabled enabled
apparmor.service enabled enabled
apport.service enabled enabled
avahi-daemon.service enabled enabled
blk-availability.service enabled enabled
bluetooth.service enabled enabled
cloud-config.service enabled enabled
cloud-final.service enabled enabled
cloud-init-local.service enabled enabled
cloud-init-main.service enabled enabled6. Check Service Status
Use systemctl status service-name.service to inspect a service. This host has ssh.service running.
systemctl status ssh.service --no-pagerTested output:
● ssh.service - OpenBSD Secure Shell server
Loaded: loaded (/usr/lib/systemd/system/ssh.service; enabled; preset: enabled)
Active: active (running) since Sun 2026-06-07 13:55:41 IST; 7h ago
Invocation: 36eb6d30595543eb802114499ea45ed3
TriggeredBy: ● ssh.socket
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 1606 (sshd)
Tasks: 1 (limit: 10052)
Memory: 7M (peak: 20.9M, swap: 12.2M, swap peak: 12.2M)
CPU: 942ms
CGroup: /system.slice/ssh.serviceUseful related commands:
systemctl is-enabled ssh.service
systemctl is-active ssh.serviceTested output:
enabled
activeIf a legacy service name is missing after migrating to newer releases, see unit network.service not found in RHEL 8 for an example of systemd-era service name changes.
7. View a Unit File with systemctl cat
Use systemctl cat to show the unit file and drop-ins that systemd is using.
systemctl cat ssh.service --no-pagerTested output:
# /usr/lib/systemd/system/ssh.service
[Unit]
Description=OpenBSD Secure Shell server
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target nss-user-lookup.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
Type=notify
RuntimeDirectory=sshd
RuntimeDirectoryMode=0755This is safer than opening random files manually because it shows the unit definition systemd actually loaded.
8. Understand Wants, Requires, Conflicts, Before, and After
Systemd dependency directives answer two different questions:
| Directive | Meaning |
|---|---|
Wants= |
Start listed units too, but do not fail this unit just because a wanted unit fails |
Requires= |
Stronger dependency; if the required unit fails to start, this unit is affected |
Conflicts= |
Negative relationship; conflicting units cannot run together |
Before= |
Ordering rule: this unit starts before the listed unit |
After= |
Ordering rule: this unit starts after the listed unit |
A common beginner mistake is assuming After= means dependency. It does not. After=network.target only controls ordering. If you also require another unit to start, combine ordering with Wants= or Requires= as appropriate.
9. View Target Dependencies
Use systemctl list-dependencies to see what belongs to a target.
systemctl list-dependencies multi-user.target --plain --no-pagerTested output:
multi-user.target
anacron.service
apport.service
avahi-daemon.service
console-setup.service
containerd.service
cron.service
cups-browsed.service
cups.path
cups.service
dbus.service
dmesg.service
docker.service
e2scrub_reap.service
grub-common.service
grub-initrd-fallback.service
ModemManager.service
networkd-dispatcher.serviceThis helps explain why starting a target brings up many services. If you are using systemd to run operational scripts around boot or shutdown, see run a script after N minutes of boot, run a script before shutdown, and run a script at shutdown only.
10. Read Service Logs with journalctl
Systemd integrates with the journal. Use journalctl -u to read logs for one unit.
journalctl -u ssh.service -n 5 --no-pagerTested output:
Jun 07 14:27:41 server1 sshd-session[14020]: pam_unix(sshd:session): session opened for user golinuxcloud(uid=1000) by golinuxcloud(uid=0)
Jun 07 14:28:12 server1 sshd-session[14502]: Accepted publickey for golinuxcloud from 10.0.2.2 port 56873 ssh2: RSA SHA256:QctH5c77yvxCJMG6WUQfAfwvfxRR4VBhFK+1rAFsoCY
Jun 07 14:28:12 server1 sshd-session[14502]: pam_unix(sshd:session): session opened for user golinuxcloud(uid=1000) by golinuxcloud(uid=0)
Jun 07 15:35:13 server1 sshd-session[38996]: Accepted publickey for golinuxcloud from 10.0.2.2 port 61916 ssh2: RSA SHA256:QctH5c77yvxCJMG6WUQfAfwvfxRR4VBhFK+1rAFsoCY
Jun 07 15:35:13 server1 sshd-session[38996]: pam_unix(sshd:session): session opened for user golinuxcloud(uid=1000) by golinuxcloud(uid=0)For a deeper log tutorial, see journalctl command examples and how systemd-journald logging works.
11. Analyze Boot Dependencies
systemd-analyze critical-chain shows the chain of units involved in boot timing.
systemd-analyze critical-chain --no-pagerTested output:
The time when unit became active or started is printed after the "@" character.
The time the unit took to start is printed after the "+" character.
graphical.target @1min 54.276s
└─power-profiles-daemon.service @1min 54.024s +250ms
└─multi-user.target @1min 54.015s
└─plymouth-quit-wait.service @11.932s +1min 42.081s
└─systemd-user-sessions.service @11.840s +65ms
└─network.target @11.769s
└─NetworkManager.service @8.197s +3.569s
└─dbus.service @6.391s +1.788s
└─basic.target @6.360s
└─sockets.target @6.360s
└─snapd.socket @6.342s +17msUse this to identify slow boot chains, but remember that not every long duration is a problem.
12. Create and Verify a Simple Service Unit
A basic oneshot service unit looks like this:
[Unit]
Description=GoLinuxCloud demo oneshot service
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/bin/printf systemd-demo-ok\n
[Install]
WantedBy=multi-user.targetBefore installing a custom unit, validate its syntax:
systemd-analyze verify /tmp/glc-systemd-demo.service
echo "verify exit=$?"Tested output:
verify exit=0verify exit=0 means the unit file passed syntax validation. If the unit file has invalid directives or paths, systemd-analyze verify can report warnings or errors before you install it under /etc/systemd/system.
For practical service patterns, see run a systemd service as a specific user or group, run a script at startup with systemd, and run a script before the login prompt appears. If your job is schedule-based rather than boot-state-based, compare it with the crontab command examples.
13. Test a Transient Service with systemd-run
systemd-run starts a transient unit under /run/systemd/transient. This is useful for testing without creating a permanent unit file.
systemd-run --unit=glc-systemd-demo-sleep /bin/sleep 20Tested output:
Running as unit: glc-systemd-demo-sleep.service; invocation ID: 0f3abe383ea64c87acef24ec5f365441Check the transient unit:
systemctl status glc-systemd-demo-sleep.service --no-pagerTested output:
● glc-systemd-demo-sleep.service - [systemd-run] /bin/sleep 20
Loaded: loaded (/run/systemd/transient/glc-systemd-demo-sleep.service; transient)
Transient: yes
Active: active (running) since Sun 2026-06-07 21:29:13 IST; 1s ago
Invocation: 0f3abe383ea64c87acef24ec5f365441
Main PID: 108101 (sleep)
Tasks: 1 (limit: 10052)
Memory: 204K (peak: 1.6M)
CPU: 27ms
CGroup: /system.slice/glc-systemd-demo-sleep.service
└─108101 /bin/sleep 20Stop it when finished:
systemctl stop glc-systemd-demo-sleep.service
systemctl is-active glc-systemd-demo-sleep.serviceTested output:
inactiveFrequently Asked Questions
1. What is systemd in Linux?
systemd is the system and service manager used by many Linux distributions. It starts the system, manages services, handles dependencies, tracks units, and provides tools such as systemctl and journalctl.2. What is a systemd unit?
A systemd unit is a configuration object managed by systemd. Unit types include service, target, socket, mount, timer, path, slice, scope, device, automount, and swap units.3. What is the difference between a service and a target in systemd?
A service unit describes a process or daemon. A target unit groups other units and represents a system state, such as multi-user.target or graphical.target.4. How do I check the default boot target in systemd?
Use systemctl get-default. The default target is commonly represented through default.target, which aliases or links to a real target such as multi-user.target or graphical.target.5. If a systemd system uses multi-user.target as the default boot target, which file is the default target symlink?
The default target is normally represented by /etc/systemd/system/default.target, which points or aliases to the selected target such as multi-user.target. The target unit file itself is commonly under /usr/lib/systemd/system or /lib/systemd/system depending on the distribution.6. How do I check logs for a systemd service?
Use journalctl -u service-name.service. Add -n 50 for recent lines and --no-pager for non-interactive output.Summary
Systemd manages Linux boot and services through units. A .service unit manages a daemon or process, while a .target unit groups units into a system state such as multi-user.target or graphical.target. Use systemctl to inspect services, targets, dependencies, and unit files, and use journalctl to read logs.
For beginners, the safest learning path is to inspect existing units first, validate custom unit files with systemd-analyze verify, and test temporary work with systemd-run before installing permanent units under /etc/systemd/system.

