skip to content

systemd

The init system on nearly every modern Linux distribution: units and targets, the service lifecycle, dependency-driven boot, journald logging, timers, and socket activation. Interviewers ask about systemd because writing a correct unit file and reading journalctl are baseline skills for anyone who ships to Linux.

on this pageshow

explore

questions

page 1 of 2

On a systemd-managed Linux host, a service unit has just failed. Which journalctl filters do you combine to show only that unit's messages, only errors, and only the current boot — and what does each flag do?

level: juniorimportance: must knowfreq 82%

answer

  1. one command, four filters
  2. -u also catches PID 1's lines
  3. -b scopes to this boot
  4. -p is a threshold, not equality
  5. -f follows, --since windows

basics

~20 s

Combine journalctl -u nginx.service to select the unit, -b to scope to the current boot, and -p err to keep priority error and above. Add -f to follow live, -n 100 for the last lines, or --since for a time window.

solid answer

~40 s

One invocation answers it: `journalctl -u nginx.service -b -p err`. `-u` selects a unit and matches both the messages the service itself logged and the lines PID 1 logged about it (started, failed, entered failed state), and it can be repeated to OR several units. `-b` limits the output to the current boot; `-b -1` is the previous one. `-p` is a **threshold**, not an equality test — `-p err` shows priorities 0 through 3, so `crit`, `alert` and `emerg` are included, and `-p 4..6` gives an explicit range. For a time window I add `--since "1 hour ago"` or `--since "2026-08-20 09:00"` with an optional `--until`. `-f` follows live, `-n 200` prints the tail, `-e` jumps to the end, and `-o short-iso` gives unambiguous timestamps.

go deeper

for a junior

Be able to type journalctl -u <unit> -b without pausing, and know that -f follows new entries. Say plainly that the journal is a binary store queried by journalctl, not a text file you tail.

for a middle

Explain that -p is a severity threshold rather than an exact match, that -u also surfaces the service manager's own lines about the unit, and how --since/--until bound a window.

for a senior

Show the diagnosis, not the flags: scope to the boot, widen the priority when a filter comes back empty, and recognise that stdout text lands at info priority so -p err can hide the very error you are hunting.

for a principal

Own the consequence for the fleet: whether services log with meaningful priorities at all decides if a severity filter is usable during an incident, and that is a service-contract decision, not a per-host one.

## What you are querying `systemd-journald` is the log collector on a systemd host. It receives kernel messages, anything a service writes to stdout and stderr (units get `StandardOutput=journal` by default), classic syslog API calls, and native structured log submissions. It stores them in indexed binary files rather than plain text, which is exactly why you query them with `journalctl` instead of `grep`ing a file: the fields are indexed, so filtering by unit or priority is a lookup, not a scan. ## Selecting the unit: -u `journalctl -u nginx.service` restricts output to one unit. The `.service` suffix is optional when it is unambiguous. Two things arrive under that filter: the process's own output, and the lines the service manager itself emitted about the unit — `Starting…`, `Started…`, `Main process exited, code=exited, status=1`, `Failed with result 'exit-code'`. That second group is usually where the verdict lives, which is why `-u` beats matching the raw `_SYSTEMD_UNIT=` field when you are diagnosing a failure. `-u` is repeatable: `journalctl -u nginx -u php-fpm` interleaves both, in time order, which is the cheapest way to correlate two cooperating services. ## Scoping to a boot: -b `-b` means "this boot". `-b -1` is the previous boot, `-b -2` the one before that, and `--list-boots` enumerates what is available. This matters after a crash or a reboot loop: without it you are reading a mixture of boots and can mistake yesterday's stack trace for today's. Past boots exist only if the journal is stored persistently; on a host with a volatile journal, `-b -1` reports that the boot does not exist. ## Priority: -p is a threshold The journal carries the syslog priority scale: 0 emerg, 1 alert, 2 crit, 3 err, 4 warning, 5 notice, 6 info, 7 debug. `-p err` (or `-p 3`) means "err and anything more severe", i.e. 0–3. The single most common mistake is reading it as "exactly err" and then wondering where the `crit` lines went — they were shown, higher up. A range is written `-p 4..6`. There is a real trap here. A program that just prints `ERROR: cannot connect` to stdout is recorded at priority `info`, because that is the default level systemd applies to unprefixed stdout/stderr lines (`SyslogLevel=` in the unit governs it). So `-p err` can show nothing at all while the log is full of the word ERROR. Either drop the priority filter, or make the service log natively with a real priority — a line may also carry a kernel-style `<3>` prefix on stdout, which systemd strips and turns into the priority. ## Time and volume `--since` and `--until` accept absolute stamps (`"2026-08-20 09:00:00"`), calendar words (`yesterday`, `today`), and relative English (`"1 hour ago"`, `"30 min ago"`). `-n 200` prints the last 200 entries, `-e` opens the pager at the end, `-f` follows new entries like `tail -f`, and `-f` combines with every other filter — `journalctl -u api -p warning -f` is the standard "watch this service misbehave" command. For scripts, add `--no-pager`; for timestamps you can paste into a ticket, `-o short-iso` or `-o short-iso-precise` prints ISO-8601 with the timezone offset instead of the local short form. ## Putting it together ```bash # post-mortem on a unit that failed during this boot journalctl -u api.service -b -p warning -o short-iso --no-pager # what happened in the ten minutes around the incident journalctl -u api.service --since "2026-08-20 09:05" --until "2026-08-20 09:15" # tail it live while you reproduce journalctl -u api.service -f -n 50 ``` ## Related flags worth knowing `-k` restricts to kernel messages (the `dmesg` equivalent, but with the boot filter available). `-x` appends catalog explanations to well-known systemd messages. `--user` reads the calling user's own journal instead of the system one. `-t` filters by syslog identifier, which is how you find output from something that is not a unit at all. ## Why interviewers ask "Show me the logs for this failing service since the last boot" should be one command, typed without hesitation. A candidate who dumps the whole journal into `grep`, or who cannot scope to a boot, will spend an incident scrolling.

  • Does `-p err` show only entries whose priority is exactly err?
    No — `-p` sets a maximum numeric priority, so `-p err` returns 0 through 3: `emerg`, `alert`, `crit` and `err`. If you truly want one level, use a range with the same endpoints, `-p 3..3`. Read the flag as "this severity and worse", the same way syslog thresholds have always worked.
  • How would you look at the boot before the current one, and when does that fail?
    `journalctl -b -1`, with `--list-boots` to see what is on disk. It fails when the journal is volatile: with no `/var/log/journal` directory the journal lives in tmpfs under `/run/log/journal` and is discarded at shutdown, so only the current boot exists. Persistent storage is a prerequisite for any cross-reboot forensics.
  • A service prints error text to stdout, but `journalctl -u app -p err` shows nothing. Why?
    Unprefixed stdout and stderr lines are recorded at the unit's `SyslogLevel=`, which defaults to `info`, so a priority filter of `err` excludes them regardless of what the text says. Drop the `-p` filter, set `SyslogLevel=` appropriately, or have the application log natively with real priorities — a `<3>` prefix on a stdout line also works.

saying these in an interview costs you the question

  • Thinks -p err hides crit and emerg entries
  • Greps the whole journal instead of filtering by unit
  • Believes journald writes plain text under /var/log
  • Assumes -b -1 works on a volatile journal
  • Says -f cannot be combined with -u or -p

context

open as a page

On a systemd host, what is the difference between `systemctl reload nginx` and `systemctl restart nginx`, and why does `systemctl reload` fail outright on some units?

level: juniorimportance: must knowfreq 68%

basics

~20 s

systemctl restart stops the service and starts a new process, so the PID changes and in-flight work is dropped. systemctl reload runs only the unit's ExecReload= command, leaving the same process running; a unit that defines no ExecReload= rejects reload with an error.

open as a page

On a systemd host you add a backup.timer unit with an OnCalendar= schedule, but the backup never runs. How does a systemd timer unit actually get its work done, and what has to be in place for the schedule to be active?

level: juniorimportance: must knowfreq 68%

basics

~20 s

A .timer unit only schedules; the work lives in a separate .service unit that it activates — by default the same-named one. You must enable and start the timer itself (systemctl enable --now backup.timer), not the service.

open as a page

Walk through a minimal systemd service unit file: which three sections does it have, and which of Description=, After=, ExecStart=, User= and WantedBy= belongs in each? What does systemd do with a key placed in the wrong section?

level: juniorimportance: must knowfreq 64%

basics

~20 s

[Unit] holds Description= and relationship keys such as After=; [Service] holds how to run the process, including ExecStart= and User=; [Install] holds WantedBy= and is read only when the unit is enabled. A key in the wrong section is ignored with a warning.

open as a page

A systemd service unit declares Requires=postgresql.service but has no After= line. Why can it still start before PostgreSQL is up, and what does After= actually change?

level: middleimportance: must knowfreq 72%

basics

~20 s

Requirement and ordering are separate axes in systemd. Requires= only says the other unit must be pulled in and must not fail; it never says "wait for it". Without After=, both units are started in parallel, so either can win the race.

open as a page

In a systemd unit file, what is the difference between Wants=, Requires= and BindsTo=, and what happens to your service in each case when the unit it points at fails to start or stops later?

level: middleimportance: must knowfreq 78%

basics

~20 s

Wants= starts the other unit but tolerates its failure. Requires= makes your unit fail to start alongside it and stop when it is explicitly stopped. BindsTo= is stricter still: your unit stops whenever the bound unit stops for any reason, including a crash.

open as a page

On a systemd host, `journalctl -b -1` reports that the specified boot does not exist, and the journal only ever covers the current boot. Why is that happening, and how do you make journald keep logs across reboots?

level: middleimportance: must knowfreq 62%

basics

~10 s

The journal is volatile. With the default Storage=auto it lives in tmpfs under /run/log/journal and is discarded at shutdown unless /var/log/journal exists. Create that directory, or set Storage=persistent, then restart systemd-journald.

open as a page

In a systemd service unit, what is the difference between `Restart=on-failure` and `Restart=always`, which terminations count as a failure, and why does neither of them restart the service after an operator runs `systemctl stop`?

level: middleimportance: must knowfreq 72%

basics

~20 s

Restart=on-failure restarts only after an unclean exit — a nonzero exit status, a fatal signal, a timeout or a watchdog trip. Restart=always additionally restarts after a clean exit 0. Neither applies to an operator-issued systemctl stop, which is an explicit job, not a failure.

open as a page

A systemd .socket unit declares ListenStream=8080 and there is a matching .service unit. Describe what systemd does at boot, what happens when the first client connects, and how the daemon ends up serving on a socket it never opened itself.

level: middleimportance: must knowfreq 55%

basics

~20 s

systemd binds and listens on port 8080 itself when the .socket unit starts; the first incoming connection triggers the matching .service, and systemd passes the already-listening descriptor to it as file descriptor 3, so the daemon never binds the port at all.

open as a page

Your team runs its nightly jobs from crontab entries and is considering moving them to systemd timer units. What do timers actually give you that cron does not, and what do you give up?

level: middleimportance: must knowfreq 70%

basics

~20 s

Timers make each job a supervised unit: output lands in the journal, exit status is recorded, the job runs in its own cgroup with resource limits, it can be ordered against other units, and systemctl list-timers shows every schedule on the host. The cost is two files per job and no portability off systemd.

open as a page

On a systemd host you edited /usr/lib/systemd/system/nginx.service directly, and a package upgrade silently reverted your change. Which directories does systemd load unit files from, in what order of precedence, and how should that change have been made so it survives upgrades?

level: middleimportance: must knowfreq 68%

basics

~20 s

systemd loads units from /etc/systemd/system (admin, wins), /run/systemd/system (runtime), and /usr/lib/systemd/system (package-owned, loses). Package upgrades rewrite the last one, so put changes in a drop-in created with systemctl edit instead of editing the vendor file.

open as a page

On a systemd host, how does the system decide which target to boot into by default, how do you inspect and change that choice, and how do you override it for a single boot?

level: juniorimportance: should knowfreq 50%

basics

~20 s

systemd activates default.target at boot, which is a symlink at /etc/systemd/system/default.target falling back to the one shipped under /usr/lib/systemd/system. Read it with systemctl get-default, change it with systemctl set-default, and override one boot with systemd.unit= on the kernel command line.

open as a page

In a systemd socket unit file, what do the ListenStream= and ListenDatagram= directives each set up, and how does systemd know which service unit to start when traffic arrives on that socket?

level: juniorimportance: should knowfreq 45%

basics

~20 s

ListenStream= creates a connection-oriented listening socket (TCP port or AF_UNIX stream path); ListenDatagram= creates a datagram socket such as UDP. The service started is the one with the same base name — myapp.socket activates myapp.service — unless Service= names another.

open as a page

systemd unit files carry suffixes such as .service, .socket, .timer, .mount, .path, .slice and .scope. What does that suffix determine, and what kind of object does each of those unit types manage?

level: juniorimportance: should knowfreq 58%

basics

~20 s

The suffix is the unit type: .service supervises a process, .socket owns a listening socket, .timer carries a schedule, .mount a mount point, .path watches files, .slice groups processes for resource control, and .scope adopts processes started outside systemd.

open as a page

In the systemd journal, what is the difference between a field such as `_SYSTEMD_UNIT=` and one such as `PRIORITY=`, and how do you filter journalctl output by field and display every field of an entry?

level: middleimportance: should knowfreq 44%

basics

~20 s

Every journal entry is a set of key=value fields. Names starting with an underscore, like _PID and _SYSTEMD_UNIT, are added by journald from the sender's verified credentials and cannot be forged; the rest, such as PRIORITY and MESSAGE, come from the client.

open as a page

`systemctl start myapp.service` returns immediately and `systemctl status` reports active (running), but the application does not accept connections for another twenty seconds. What does "active" actually mean under the default Type=simple, and how do you make systemd wait for real readiness?

level: middleimportance: should knowfreq 52%

basics

~20 s

Under Type=simple, systemd calls a unit active as soon as it has forked the main process — it never asks whether the program is ready, or even whether the binary exists. Use Type=exec to wait for a successful exec, or Type=notify so the service reports READY=1 itself.

open as a page

In a systemd .socket unit, what changes when you set Accept=yes instead of the default Accept=no, and what must the paired service unit look like in each case?

level: middleimportance: should knowfreq 35%

basics

~20 s

With Accept=no systemd passes the listening socket to one long-lived service that accepts connections itself. With Accept=yes systemd accepts each connection and spawns a fresh instance of a template unit per connection, passing only that one connection — the classic inetd model.

open as a page

A systemd timer unit can be scheduled with OnCalendar= or with monotonic directives such as OnBootSec= and OnUnitActiveSec=. What is the difference between the two kinds of schedule, and when would you pick a monotonic timer?

level: middleimportance: should knowfreq 55%

basics

~20 s

OnCalendar= fires at wall-clock times and follows the system clock, time zone and DST. Monotonic directives fire a fixed interval after a reference event — boot for OnBootSec=, the triggered unit's last activation for OnUnitActiveSec= — and ignore clock changes.

open as a page

A systemd timer with OnCalendar=daily did not fire because the machine was powered off at the scheduled time. What does Persistent=true in the [Timer] section change about that, and how does systemd know a run was missed?

level: middleimportance: should knowfreq 48%

basics

~20 s

Persistent=true makes systemd record each trigger as a timestamp file on disk. When the timer starts and that timestamp is older than the schedule allows, the job runs once immediately to catch up. It applies only to OnCalendar= schedules.

open as a page

On a systemd host, `systemctl enable myapp.service` refuses with a message that the unit file has no installation config. Which section is missing from the unit file, and what exactly does WantedBy=multi-user.target cause systemd to create on disk?

level: middleimportance: should knowfreq 52%

basics

~10 s

The unit has no [Install] section, so there is nothing telling systemctl where to hook it. WantedBy=multi-user.target makes enable create a symlink to the unit inside /etc/systemd/system/multi-user.target.wants/, which is all that enabling physically does.

open as a page

A systemd unit declares both Requires= and After= on its database unit, and the ordering is confirmed correct, yet the service still fails its first connection at boot. What does After= actually wait for, and how can a unit declare that it is genuinely ready?

level: seniorimportance: should knowfreq 45%

basics

~20 s

After= waits for the other unit to be considered started, which is not the same as ready. For Type=simple that means only that systemd forked the process. A daemon signals real readiness with Type=notify and sd_notify, otherwise the consumer must retry.

open as a page

A systemd service that needs a configured IP address at startup declares After=network.target, yet at boot it still fails with "cannot assign requested address". What does network.target actually guarantee, and what should the unit declare instead?

level: seniorimportance: should knowfreq 52%

basics

~20 s

network.target only means the network management stack has started, not that any interface is configured. A unit that needs real connectivity must declare both Wants=network-online.target and After=network-online.target, and a wait-online service must be enabled to make that target mean anything.

open as a page

On a systemd host, /var is nearly full and /var/log/journal accounts for several gigabytes. How do you reclaim the space now with journalctl, and how do you cap the journal so it cannot grow that far again?

level: seniorimportance: should knowfreq 52%

basics

~10 s

Measure with journalctl --disk-usage, then run journalctl --rotate followed by --vacuum-size= or --vacuum-time=, because vacuuming only removes archived files. Cap growth permanently with SystemMaxUse= and SystemKeepFree= in journald.conf and restart systemd-journald.

open as a page

A systemd service configured with Restart=always is sitting in the failed state, and the journal shows "Start request repeated too quickly" followed by a start-limit-hit result. What has systemd decided, which settings control it, and how do you get the unit running again?

level: seniorimportance: should knowfreq 58%

basics

~20 s

systemd's start rate limiter has tripped: the unit was started more than StartLimitBurst= times (5 by default) within StartLimitIntervalSec= (10s by default), so systemd stopped honouring the restart policy and marked the unit failed. Clear the counter with systemctl reset-failed, then fix the crash.

open as a page

On a systemd host, `systemctl stop myapp.service` takes about ninety seconds every time and the journal then reports that systemd killed the process. Walk through what systemd does during a stop job, and which unit settings you would change.

level: seniorimportance: should knowfreq 50%

basics

~20 s

The service is not reacting to SIGTERM, so systemd waits out TimeoutStopSec= — 90 seconds by default — and then sends SIGKILL. A stop job runs ExecStop= if present, signals the unit's processes with KillSignal=, waits, then escalates. Fix the signal handling rather than shortening the timeout.

open as a page

You put a service behind a systemd socket unit listening on port 8080, and now the service fails at startup with "address already in use" — yet nothing else on the host uses that port. What is going on, and how do you confirm it?

level: seniorimportance: should knowfreq 30%

basics

~20 s

systemd already holds the listening socket, and the daemon is still calling bind() on the same port instead of using the descriptor it was handed. Something does occupy 8080 — PID 1. Either the daemon must adopt the passed descriptor, or drop the socket unit.

open as a page

Socket activation is often described as giving restarts that never refuse a connection. On a systemd host, what exactly keeps clients from seeing "connection refused" while the service restarts, and where does that property break down?

level: seniorimportance: should knowfreq 45%

basics

~20 s

The listening socket is held by systemd, not by the service process, so restarting the service never closes it. Arriving connections sit queued on that socket and are served once the new process inherits the same descriptor and starts accepting.

open as a page

A systemd timer you deployed is not firing when you expected. How do you check what systemd thinks your OnCalendar= expression means, when the timer last and next elapses, and whether the problem is in the timer or in the service it triggers?

level: seniorimportance: should knowfreq 45%

basics

~20 s

Normalize the schedule with systemd-analyze calendar, check arming and elapse times with systemctl list-timers --all and systemctl status on the .timer, then separate the halves: run the paired service by hand with systemctl start and read its status and journal.

open as a page

A configuration-management run adds the drop-in /etc/systemd/system/app.service.d/override.conf containing an [Service] section with a new ExecStart= line, and after daemon-reload the unit refuses to start, complaining it has more than one ExecStart=. Why does that happen, and how do you correctly replace a directive from a drop-in?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Drop-ins merge rather than replace, and list-valued settings such as ExecStart= append, so the unit ended up with two. Reset the list first by assigning the key an empty value, then set the new one — two lines: ExecStart= followed by ExecStart=/new/command.

open as a page

On a systemd host you ran `systemctl stop` and `systemctl disable` on a unit, yet after a reboot it is running again. What does `systemctl mask` do differently, and what does masking look like on disk?

level: middleimportance: nice to knowfreq 42%

basics

~20 s

Disabling only removes the unit's [Install] symlinks, so anything that pulls the unit in as a dependency, or a matching socket, path or timer unit, still activates it. Masking symlinks the unit name to /dev/null under /etc/systemd/system, which makes every activation path fail.

open as a page

showing 1–30 of 35