journalctl and /var/log Explained
Every meaningful system and service event on Linux gets logged somewhere, and on most modern distributions that “somewhere” is split between the systemd journal, queried with journalctl, and traditional plain-text files under /var/log. Knowing where to look, and how to filter effectively, turns “something broke and I don’t know why” into a quick diagnostic step rather than a guessing game.
The systemd journal
On systemd-based distributions (the majority of current Linux systems), systemd-journald collects kernel messages, output from every systemd-managed service, and anything logged through the standard logging interface, storing it in a structured, indexed binary format queried with journalctl.
journalctl
Run alone, this dumps the entire journal, oldest entries first, piped through a pager. In practice you almost always want to filter it down.
Filtering by service
journalctl -u nginx
journalctl -u ssh
-u filters to a specific systemd unit, which is the single most useful filter for diagnosing a particular service’s behavior rather than scrolling through unrelated system noise.
Following logs live
journalctl -f
journalctl -u nginx -f
-f follows the journal in real time, printing new entries as they appear, directly analogous to tail -f on a traditional log file. This is the standard way to watch what happens as you restart a service or trigger the behavior you are trying to diagnose.
Filtering by time
journalctl --since today
journalctl --since "1 hour ago"
journalctl --since "2026-08-01" --until "2026-08-05"
journalctl -u nginx --since "10 minutes ago"
--since and --until accept fairly natural time expressions, and combine freely with other filters like -u to narrow down to a specific service within a specific window.
Filtering by severity
journalctl -p err
journalctl -p warning
-p filters by priority level, and includes everything at or above the level specified, so -p err shows error, critical, alert, and emergency entries, but not warning or informational ones. This is useful for cutting through routine informational noise when you specifically want to know what has gone wrong.
Kernel messages
journalctl -k
-k (short for --dmesg) shows only kernel ring buffer messages, the same information the traditional dmesg command shows, useful for hardware and driver-level issues.
Logs from the current boot only
journalctl -b
journalctl -b -1 # the previous boot
-b restricts output to the current boot session, which is helpful after a crash or unexpected reboot, letting you separate “what happened during this boot” from the full historical log. -b -1 shows the boot before the current one, useful for investigating what happened right before an unexpected restart.
Making the journal persistent
On many distributions, the journal defaults to volatile, in-memory storage, meaning the entire history is lost on every reboot. To persist logs across reboots:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
Creating that directory is enough to signal systemd-journald to switch to persistent, on-disk storage going forward.
Managing journal size
Left unmanaged, the journal can grow to consume significant disk space over time. Default limits usually prevent runaway growth, but they can be tuned in /etc/systemd/journald.conf:
[Journal]
SystemMaxUse=500M
MaxRetentionSec=2week
To reclaim space immediately rather than waiting for automatic cleanup:
journalctl --vacuum-size=500M # shrink journal to at most 500MB
journalctl --vacuum-time=2weeks # remove entries older than 2 weeks
Traditional logs under /var/log
Not everything logs through the journal. Many services, particularly ones not tightly integrated with systemd, or ones that predate journald’s widespread adoption, still write their own plain-text log files directly under /var/log:
ls /var/log
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
less /var/log/auth.log # authentication attempts, sudo usage, SSH logins (Debian/Ubuntu)
less /var/log/secure # equivalent on Fedora/RHEL
For these files, the same tools covered elsewhere on this site apply directly: tail -f to follow live, grep to search, less to page through, and sed/awk for more involved filtering and extraction.
Choosing where to look
As a practical rule: for anything managed as a systemd service, journalctl -u servicename is almost always the fastest path to relevant logs. For applications that maintain their own dedicated log files, such as web servers logging access requests in a specific format expected by log analysis tools, /var/log is often still the primary or only source, even on a fully systemd-based distribution. When in doubt, journalctl -u servicename is a reasonable first check, since it will show you directly whether that service is even attempting to log through the journal at all.
Frequently Asked Questions
What is the difference between journalctl and /var/log files?
journalctl queries the systemd journal, a structured, indexed, binary log store maintained by systemd-journald that captures kernel messages, systemd unit output, and anything services log through the standard logging interface. /var/log holds traditional plain-text log files, some still actively used (like /var/log/nginx/access.log for services that log directly to a file rather than through the journal), and some that are legacy holdovers from before systemd-based logging became standard. On most current systemd-based distributions, the journal is the primary, most complete source for system and service logs, while /var/log still matters for applications that write their own dedicated log files outside the journal.
How do I see logs for a specific service?
Use journalctl -u servicename, substituting the systemd unit name, for example journalctl -u nginx or journalctl -u ssh. This filters the journal to only entries logged by that specific unit, which is far more useful than scrolling through the entire system journal looking for relevant lines. Combine with -f to follow the log live as new entries arrive: journalctl -u nginx -f.
How do I follow logs in real time, like tail -f?
journalctl -f follows the journal live, printing new entries as they arrive, directly analogous to tail -f on a plain-text log file. Combine it with a unit filter to follow a specific service’s logs rather than the entire system journal: journalctl -u servicename -f. For traditional log files under /var/log, tail -f /var/log/filename.log does the same thing for that specific file.
How do I see only errors or logs from today?
journalctl -p err shows only entries at error priority or higher (which also includes critical, alert, and emergency, since journalctl -p includes everything at or above the specified severity by default). journalctl —since today limits output to entries logged since midnight today, and —since and —until accept fairly flexible time expressions, such as journalctl —since “1 hour ago” or journalctl —since “2026-08-01” —until “2026-08-05” for a specific date range.
Why do my logs disappear after a reboot?
By default on many distributions, the systemd journal is configured to store logs only in memory (volatile storage), which means the entire journal history is lost on reboot. To persist logs across reboots, create the persistent journal directory and restart the logging service: sudo mkdir -p /var/log/journal followed by sudo systemctl restart systemd-journald. Once that directory exists, systemd-journald automatically switches to writing logs there instead of only to memory, and journal history survives subsequent reboots.
How do I stop the journal from growing indefinitely and filling up disk space?
The journal is configured with size and time limits by default, but they can be adjusted in /etc/systemd/journald.conf, using settings like SystemMaxUse (a maximum total size for journal files) and MaxRetentionSec (a maximum age for retained entries). To manually reclaim space immediately rather than waiting for automatic cleanup, journalctl —vacuum-size=500M shrinks the journal to at most 500MB, and journalctl —vacuum-time=2weeks removes entries older than two weeks. After changing settings in journald.conf, restart the service with sudo systemctl restart systemd-journald for the new limits to take effect.