journalctl is the command-line tool that queries and displays the systemd journal, the structured, indexed log store maintained by the systemd-journald service. In Linux system initialization, it is the primary way to read what happened during boot, which units started or failed, and what the kernel and services reported afterward.
Unlike reading plain text files under /var/log, journalctl works with indexed binary records that carry metadata fields such as the unit name, process ID, boot ID and priority. This lets an administrator ask precise questions, for example all errors from one service during the previous boot, without writing fragile text filters.
How journalctl reads the systemd journal
journalctl is a read-only client of the journal files that systemd-journald writes. The daemon collects messages from the kernel ring buffer, from the standard output and standard error of every service, from the syslog socket and from the native journal API, then stores each message as an entry made of key-value fields.
Fields whose names begin with an underscore, such as _PID, _UID, _SYSTEMD_UNIT and _BOOT_ID, are trusted fields added by journald itself, so a process cannot forge them. Fields without an underscore, such as MESSAGE and PRIORITY, come from the sender. journalctl uses the file indexes and hash tables to match these fields quickly, even when the journal holds millions of entries.
Where the data lives depends on the Storage= setting in journald.conf. The following table summarizes the storage modes and their consequences for what journalctl can show.
| Storage mode | Location | Survives reboot | Typical use |
|---|---|---|---|
| persistent | /var/log/journal | Yes | Servers and workstations that need history |
| volatile | /run/log/journal | No | Diskless or read-only systems |
| auto | Persistent only if /var/log/journal exists | Depends on directory | Default on many distributions |
| none | Nothing stored | No | Forwarding only, to syslog or a remote collector |
Because files are binary and checksummed, journalctl can detect corruption and will skip damaged sections rather than fail completely. The command journalctl --verify checks file consistency and, when Forward Secure Sealing is enabled, can also reveal tampering.
Essential journalctl filters and options
The value of journalctl comes from combining filters: matches on different fields are joined with a logical AND, while repeated matches on the same field are joined with OR. The table lists the options administrators use most often.
| Option | What it selects | Example |
|---|---|---|
| -u unit | Entries from one systemd unit | journalctl -u nginx.service |
| -b [offset] | One boot; -b -1 is the previous boot | journalctl -b -1 |
| -p priority | Priority level or range | journalctl -p err..alert |
| –since / –until | Time window | --since "1 hour ago" |
| -k | Kernel messages only | journalctl -k -b |
| -f | Follow new entries live | journalctl -f -u sshd |
| -o format | Output format such as json or verbose | journalctl -o json-pretty |
| -g pattern | Regular expression on MESSAGE | journalctl -g "timeout" |
Field matches can be written directly, as in journalctl _UID=1000 or journalctl _COMM=sshd. The option -x adds explanatory catalog text to known messages, and -e jumps to the end of the pager. For scripts, --no-pager and -o json produce stable, machine-readable output.
Priorities follow the syslog severity scale from 0 to 7, from emerg to debug. Selecting -p warning returns warning and every more severe level, which is usually the fastest way to reduce noise during troubleshooting.
journalctl compared with other Linux logging tools
journalctl is not the only way to read logs on Linux, and it often coexists with classic syslog daemons. The comparison below shows where each approach fits within the system initialization and logging stack.
| Tool | Data format | Strength | Limitation |
|---|---|---|---|
| journalctl | Indexed binary fields | Precise filtering by unit, boot and field | Requires journal tools to read |
| rsyslog files | Plain text lines | Universal tools such as grep and tail | Little structured metadata |
| dmesg | Kernel ring buffer | Immediate kernel view | Small buffer, lost on reboot |
| systemctl status | Journal excerpt | Unit state plus last lines | Shows only a few recent entries |
In practice, systemctl status is the first glance and journalctl is the full investigation. Within the topic of system initialization, the journal ties together the boot loader handoff after GRUB, the kernel phase, and every systemd unit or systemd timer activation, because each entry carries the same boot ID.
Managing journal size and retention
Journal growth is controlled by size and time limits in /etc/systemd/journald.conf. By default, persistent journals may use up to 10 percent of the file system, capped at 4 GiB, and journald also keeps at least 15 percent of the file system free.
| Setting | Purpose | Typical value |
|---|---|---|
| SystemMaxUse | Maximum disk space for persistent journals | 500M to 4G |
| SystemKeepFree | Free space journald must preserve | 1G or more |
| MaxRetentionSec | Maximum age of entries | 1month or 3months |
| MaxFileSec | Time before a file is rotated | 1week to 1month |
| RateLimitBurst | Messages allowed per interval per service | 10000 per 30s |
Manual cleanup uses vacuum options: journalctl --vacuum-size=500M or --vacuum-time=2weeks removes archived files until the limit is met. The command journalctl --disk-usage reports the current footprint, which is a useful check before changing limits.
Common pitfalls with journalctl
Most problems with journalctl are about missing data or missing permissions, not about the tool itself. The following points cover the mistakes seen most often in administration work.
- Previous boots are missing because storage is volatile; creating
/var/log/journaland restarting journald enables persistence. - Ordinary users see only their own entries; membership in the
systemd-journaloradmgroup grants read access to system logs. - Rate limiting silently drops messages from very chatty services, which journald reports as suppressed messages.
- Time filters use local time unless
--utcis given, which confuses comparisons across servers in different zones. - Copying journal files between hosts works, but they must be read with
journalctl --fileor--directory, not with a text editor.
Stripped to the essentials
A Linux computer keeps a detailed diary of everything it does, from the moment it starts until it shuts down. Every program writes its notes into that diary, and the system stamps each note with who wrote it, when, and during which startup.
journalctl is the search tool for that diary. Instead of reading thousands of pages, you can ask for only the errors from one program yesterday, or only the messages from the last time the machine started. That makes it the first place to look when something breaks.
Where it is applied
An administrator responsible for a web server notices that the site was unavailable for several minutes after a planned kernel update and reboot. Running systemctl status nginx shows the service is active now, so the failure must have happened during startup.
The administrator runs journalctl -b -1 -u nginx.service -p warning to see warnings from the previous boot, then journalctl -b 0 -u nginx.service --since "10:00" for the current one. The entries show that nginx tried to start before the network address was configured and failed to bind its port, then a restart policy brought it up two minutes later.
Adding After=network-online.target and Wants=network-online.target to the unit fixes the ordering. At the next reboot, the journal shows a clean first start, and the outage window disappears.