Cloud Tech by Victor
DevOpsIntermediate

Linux Logging & Monitoring with journald

Why journald's default "auto" storage mode can quietly discard logs across a reboot on a fresh system, and how journalctl's unit and priority filters actually narrow down a live incident.

Updated 2026-07-243 min read

Overview

systemd-journald centralizes logging from every unit, the kernel, and early boot into one structured, queryable journal, replacing the older model of scattered plain-text log files. journalctl queries it, -u scopes output to a specific unit (including systemd's own messages about it and any coredump metadata, not just what the service printed itself), -p filters by severity, and -f follows new entries live. What actually determines whether any of this survives a reboot is journald's Storage= setting, and the default, auto, is easy to misjudge: it behaves like persistent only if /var/log/journal already exists, and like volatile (memory-only, wiped on reboot) otherwise, so two systems that never explicitly configured this setting can behave completely differently depending on directory history alone.

Quick Reference

Storage= valueLocationSurvives reboot?
volatile/run/log/journal (memory-backed)No
persistent/var/log/journal (disk)Yes
auto (default)Either, depending on whether /var/log/journal existsDepends on directory history
journalctl optionDoes
-u <unit>Scope to one systemd unit, plus systemd's own messages about it
-p <level>Filter to that severity or more severe
-fFollow the journal live, like tail -f

Syntax

bash
journalctl -u nginx.service --since "1 hour ago"
journalctl -u nginx.service -p err -f

Examples

bash
# Make persistence an explicit choice instead of leaving it to
# whether /var/log/journal happens to already exist.
mkdir -p /var/log/journal
systemd-tmpfiles --create --prefix /var/log/journal
systemctl restart systemd-journald

Auto storage mode can silently discard every log on reboot

Storage=auto, journald's default, behaves like persistent only if /var/log/journal already exists; otherwise every log entry lives only in memory and is gone on the next reboot. A freshly provisioned system with no one having created that directory is quietly running volatile, even though nobody set it explicitly.

Visual Diagram

Common Mistakes

  • Assuming logs are persisted by default and discovering only after an incident-driven reboot that Storage=auto was actually running volatile.
  • Grepping a combined log file for a service name instead of using journalctl -u, missing systemd's own start/stop/failure messages and coredump metadata.
  • Running journalctl -f unfiltered during an incident and having to visually scan every unit's routine output instead of scoping to the relevant unit and severity.
  • Forgetting that creating /var/log/journal mid-session doesn't retroactively persist journal entries already written only to the volatile, memory-backed journal.

Performance

  • Filtering with -u and -p at query time is efficient since the journal is indexed by fields including unit and priority, not a linear text scan of a flat file.
  • Persistent, disk-backed journals grow over time; SystemMaxUse=/RuntimeMaxUse= in journald.conf bound that growth, unbounded journals can otherwise consume meaningful disk space on a long-running system.

Best Practices

  • Explicitly set Storage=persistent (or create /var/log/journal) rather than leaving persistence to depend on whether that directory happens to already exist.
  • Use journalctl -u <unit> over grepping a shared log file, it's scoped by the journal's own unit metadata, not string matching.
  • Combine -u, -p, and -f together when live-debugging a specific service's failures, rather than following the full, unfiltered journal.
  • Set explicit size/retention limits (SystemMaxUse=, MaxRetentionSec=) so a persistent journal doesn't grow unbounded on disk.

Interview questions

What is the difference between journald's "volatile", "persistent", and "auto" storage modes, and which one is the default?

"Volatile" keeps the journal only in `/run/log/journal`, which is memory-backed and wiped on every reboot, nothing survives a restart. "Persistent" writes to `/var/log/journal` on disk, so entries survive reboots (falling back to volatile only during very early boot or if the disk is unavailable). "Auto" is the actual default, and it behaves like "persistent" only if `/var/log/journal` already exists, otherwise it behaves like "volatile", so whether logs survive a reboot on a given system depends entirely on whether that directory happens to have been created, not on any setting an administrator consciously chose.

What does journalctl -u myservice actually show you, beyond just log lines the service itself printed?

`-u`/`--unit=` expands into a filter that captures more than the service's own stdout/stderr, it includes messages logged about the unit by systemd itself (start, stop, failure notifications) and associated coredump information if the process crashed, correlated by the unit's identity rather than by manually grepping a shared log file for its name. This is more reliable than text-searching a combined log, since it's scoped by the actual unit metadata the journal records, not by whatever string happens to appear in a log line.

During a live incident, what does journalctl -f -u myservice -p err do, and why combine those specific options?

`-f` follows the journal in real time, printing new entries as they're appended, `-u myservice` scopes that stream to just the one unit under investigation, and `-p err` filters to only entries at the "err" priority or more severe (more important), suppressing informational noise. Combined, this gives a live, scoped, severity-filtered view of exactly one service's serious problems as they happen, rather than watching an unfiltered firehose of every unit's routine log output and trying to manually spot the relevant failure.

References

ShareXLinkedInReddit
Was this page helpful?
Suggest an improvement