IT Practice Exams

XK0-006 · Security · Updated July 26, 2026

journalctl Commands: Filtering, Persisting, and Rate-Limiting the systemd Journal

On a systemd distribution, log collection is handled by systemd-journald, a daemon that gathers kernel messages, service stdout/stderr, syslog traffic, and boot output into a structured, indexed binary journal — and journalctl is the query tool for reading it. Because the journal is binary rather than flat text, you don’t grep files under /var/log to work with it; you pass journalctl filters for unit, boot, priority, and time range. Two journald behaviors matter as much as the query flags: where the journal is stored (volatile by default on many distributions) and how its built-in rate limiting throttles a flooding service.

journald: what it is and what it stores

systemd-journald ingests log records from multiple sources — the kernel ring buffer, native systemd service output, the syslog socket, and audit-adjacent boot messages — and writes them as structured entries with indexed metadata fields (_SYSTEMD_UNIT, _PID, PRIORITY, boot ID, and dozens more). That metadata is what makes the filtering below possible without text-parsing. Traditional syslog daemons like rsyslog often run alongside journald, reading from it and writing the familiar flat files, but the authoritative structured store on a modern system is the journal. When a monitoring or log-aggregation question asks which component collects kernel, service, and boot messages into a binary store queried by journalctl, the answer is journald.

The core filtering flags

The flags below cover nearly every real-world query. Each is independently useful, and they combine freely:

  • -u <unit> — entries from one systemd unit: journalctl -u nginx.service.
  • -b — entries since the current boot; -b -1 is the previous boot, and journalctl --list-boots enumerates boot IDs.
  • -k — kernel messages only (the journal’s equivalent of dmesg) — the first stop when confirming a failing disk.
  • -f — follow: stream new entries live, like tail -f.
  • -e — open the pager jumped to the end (newest entries).
  • -r — reverse order, newest first.
  • -n <N> — show only the last N lines (default 10 with -n alone).
  • -p <priority> — filter by syslog priority, name or number: -p err (or -p 3) shows err and worse; priorities run emerg(0) through debug(7).
  • --since / --until — time windows: --since "2026-07-25 08:00" --until "09:00", or friendly forms like --since yesterday.
  • -x — augment entries with explanatory catalog text where available.
  • -o <format> — output format: -o verbose dumps every structured field; -o json suits scripting and log shipping.
  • --disk-usage — report journal space consumption; pair with --vacuum-size=500M or --vacuum-time=2weeks to prune.

Combining flags is where the value shows up. Kernel messages since the most recent boot: journalctl -k -b. Everything nginx logged this boot: journalctl -u nginx.service -b. Live errors from a unit you’re debugging: journalctl -u sshd.service -p err -f. Match-the-flag questions punish fuzzy memory — the pairs worth locking in are -f follow, -e end, -r reverse, -k kernel, -u unit, -p priority, -b boot.

Making the journal survive reboots

Here is the trap that catches admins on default installs of several distributions: journald stores the journal in /run/log/journal, and /run is a tmpfs — a RAM-backed filesystem — so every reboot erases the logs. Whether the journal persists is governed by the Storage= setting in /etc/systemd/journald.conf:

Storage= valueBehavior
volatileJournal kept only in /run/log/journal; lost at reboot
persistentJournal written to /var/log/journal, creating the directory if needed
auto (default)Persistent only if /var/log/journal already exists; otherwise volatile
noneNothing stored; entries only forwarded (e.g., to syslog)

So there are two valid fixes for disappearing logs: set Storage=persistent in journald.conf and restart systemd-journald, or simply create the directory (sudo mkdir -p /var/log/journal, then systemctl restart systemd-journald) and let auto do the rest. On an exam question about a journald.conf change, Storage=persistent is the answer being fished for. Persistent journals are also a hardening and forensics concern — post-incident analysis is impossible if the evidence evaporated at reboot, which is why this lands in the security domain alongside auditd.

Rate limiting: RateLimitIntervalSec and RateLimitBurst

journald protects itself from log floods with per-service rate limiting, configured in journald.conf:

RateLimitIntervalSec=30s
RateLimitBurst=1000

The semantics: within each 30-second window, a given service may log up to 1,000 messages. Once a service exceeds the burst within the interval, journald drops that service’s further messages for the remainder of the window and records a single notice stating how many messages were suppressed. When the next interval starts, logging resumes normally. Key discriminations: the limit is enforced per service, not globally — a chatty app cannot silence other units’ logging, and journald itself keeps running; the excess messages are discarded, not queued or delayed for later delivery. Setting either value to 0 disables rate limiting entirely. If a misbehaving application emits tens of thousands of identical lines per minute, expect to see bursts of 1,000 entries punctuated by suppression notices rather than a complete flood.

How the XK0-006 exam tests this

  • An identification question in a monitoring context: which component on a systemd distribution collects kernel, service, and boot messages into a binary, journalctl-queryable store — journald, versus distractors like rsyslog, auditd, or logrotate.
  • A “compose the right command” scenario: kernel entries since last boot (-k -b), or one service’s entries since last boot (-u <unit> -b), with wrong answers pairing plausible flags incorrectly.
  • A matching exercise pairing options with behavior — follow vs jump-to-end vs reverse vs priority filter — where transposed descriptions are the trap.
  • A configuration question on /etc/systemd/journald.conf: which change makes logs persist (Storage=), or what actually happens when a flooding service crosses the RateLimitBurst threshold within RateLimitIntervalSec.

Timer-driven jobs are a common source of the service logs you’ll be querying — the scheduling side is covered in systemd timers vs cron. Logging and log persistence land in the Security domain — the full XK0-006 study guide maps every domain. Filter syntax sticks fastest when you work through practice questions that force you to recall it.

Quick reference

  • journald = the collector/store (structured, binary, indexed); journalctl = the query tool.
  • journalctl -k -b → kernel messages from the current boot; journalctl -u nginx.service -b → one unit, this boot.
  • Memorize the pairs: -f follow, -e jump to end, -r newest first, -p priority threshold, -n line count, -x add explanations.
  • Time-box queries with --since/--until; machine-readable output with -o json.
  • Default storage is effectively volatile on many distros (/run/log/journal, tmpfs): logs vanish at reboot.
  • Fix persistence via Storage=persistent in /etc/systemd/journald.conf, or create /var/log/journal under Storage=auto, then restart systemd-journald.
  • Rate limiting is per service: beyond RateLimitBurst messages in RateLimitIntervalSec, further messages from that service are dropped and one suppression notice is logged; the counter resets next interval.
  • Manage journal size with journalctl --disk-usage, --vacuum-size=, --vacuum-time=.
Choose your exam → Lifetime access
from $59, once