New to Linux? These 4 systemd tools help you fix common issues
I have been running Linux on my main workstation for close to a decade, and I still hit the same wall I hit on day one: something stops working, and the fix involves a system component I never learned. The component, almost every time, is systemd (the service manager that boots Linux, starts daemons, and tracks what is running on the system). Once you learn four or five systemd commands, the wall gets shorter. This post is the cheat sheet I wish someone had handed me on day one.
Most beginner guides focus on systemctl start and systemctl enable (the two commands that turn a service on). Those are the entry point. The four tools below are what you reach for when the entry point fails. They are the difference between restarting your machine and fixing the actual problem in two minutes.
journalctl, for reading the logs
Every service that runs under systemd writes its output to a single log database called the journal. The command to read that database is journalctl. It is the first thing I run when a service refuses to start.
To see the last hundred lines of a specific service, the pattern is:
journalctl -u nginx --no-pager | tail -100
The -u flag filters by unit name (the systemd term for a managed service or resource). --no-pager keeps the output from opening in less, the terminal pager that lets you scroll through long output one screen at a time. Pipe to tail if you only want the most recent lines. To follow new entries in real time, like tail -f on a log file, add -f:
journalctl -u nginx -f
The single most useful flag I never used for the first year was --since. It lets you bound the output to a time window:
journalctl -u nginx --since "1 hour ago"
That one flag saved me hours of scrolling through boot-time noise to find the line that actually mattered.
systemctl status, for diagnosing a service that failed
When a service does not start, systemctl status tells you why. The output is a single screen, packed with the right information: whether the service is running, the last few log lines, the location of the unit file, and the cgroup (a kernel feature that groups related processes together for resource accounting and isolation) the service is in.
systemctl status nginx
If the service failed, the Active: line will say failed in red. The Logs: block at the bottom is the most recent journal output, scoped to that service. It is the fastest way to find a typo in a config file, a missing dependency, or a port that is already in use.
A line I use constantly is systemctl status --no-pager | head -20. I do not need the full log dump; I just need the headline and the first few error lines. If the headline is fine but I need more, I switch to journalctl.
systemd-analyze, for finding what is making boot slow
A Linux machine that takes three minutes to boot is usually slow for one of two reasons: the disk is slow, or too many services are starting in parallel and stepping on each other. The command that tells you which is which is systemd-analyze.
systemd-analyze blame
This prints every unit that ran at boot, sorted by the time each one took. The first few entries are usually the smoking gun. On my workstation, a recent install was taking 45 seconds to boot because of a Bluetooth service that was timing out. blame showed the service at the top, I disabled it with systemctl disable bluetooth.service, and boot dropped to 12 seconds.
systemd-analyze critical-chain is the companion I run next. It shows the dependency tree, which services blocked which, and where the critical path went. If a service at the top of blame is also at the top of critical-chain, disabling it will not help, because something else is waiting for it. That is the difference between fixing a slow boot and breaking the boot entirely.
systemctl list-units, for finding what is actually running
When a port is already in use, or a process is hogging a resource, you usually do not know the systemd unit name. You know the symptom. systemctl list-units is how you go from symptom to unit.
systemctl list-units --type=service --state=running
This prints every active service. The output is paginated by default, so pipe to less or grep for what you want. To filter by a partial name:
systemctl list-units --type=service --state=running | grep -i 'docker'
I keep a shell alias for this exact pattern. The combination of --type=service and --state=running is the cleanest way to see what the system is doing without paging through 200 unit files.
Two more flags that saved my sanity
A pair of journalctl flags earned permanent spots in my muscle memory. The first is -p err, which filters the journal to only error-level entries and above. The default output is noisy, especially on a server that has been up for months, and -p err cuts the noise without hiding the signal.
journalctl -p err --since "today"
The second is -b, which scopes the output to the current boot. If a service failed right after a reboot, -b shows you the relevant log lines without the weeks of accumulated history that came before.
journalctl -b -u nginx
Between the two, I can usually find the failing line in under a minute. Before I learned them, the same search took twenty.
What I would tell past me
If I could send a message back to the version of me who installed Linux for the first time in 2017, I would say four things.
- Learn
journalctlbefore you learn anything else. It is the only tool that works when the GUI is broken, when SSH is hung, and when the system will not boot past the first service. - Run
systemctl statusbefore you runsystemctl restart. Restarting a broken service clears the log line that would have told you what was wrong. systemd-analyze blameon day one. The five-minute audit tells you what you can safely disable and what you cannot. Doing it on a clean install is faster than doing it after three years of accumulated junk.- Do not disable a service because it is slow. Use
critical-chainto confirm nothing else is waiting for it. The cost of disabling the wrong service is a broken boot.
Trade-offs
Systemd is not the only init system (the first process a Linux system runs at boot, traditionally SysVinit or systemd) out there, and the four tools above are systemd-specific. If you ever run a system that uses OpenRC, runit, or s6 (three alternative init systems popular on Alpine, Artix, and some embedded distributions), the equivalent commands exist but the syntax is different. The mental model is the same: a central service manager, a log database, a status command. Learn the model once, and the porting between init systems is a one-day project.
There is also a community of users who actively dislike systemd, for political and technical reasons that go beyond what fits in this post. The trade-off is real: depending on systemd means depending on a project with a single maintainer and a particular design philosophy. If that bothers you, the alternatives work. Most distributions ship with systemd by default, and the four tools in this post cover 95% of what you will need.
Bottom line
If you are new to Linux, learn journalctl, systemctl status, systemd-analyze, and systemctl list-units. That is the minimum kit. After that, the rest of systemd (units, targets, generators, sockets) is interesting but optional until you start running servers. For a desktop user, those four commands will resolve 90% of the things that go wrong on a weekday afternoon.