journalctl Command Reference
Concept
journalctl is the query tool for the systemd journal: a structured, indexed log store. Filter by unit, time, boot, priority, PID, or executable instead of grepping a pile of text files.
This page is the command card. Storage, persistence, vacuuming, and “why did last boot vanish?” live in journalctl Deep Dive and journald and Persistent Storage.
Why it matters
systemctl statusonly shows a teaser. The rest is here- Time and unit filters beat
grep -Ron/var/logfor anything systemd-managed -b -1is the fastest “what died on the previous boot?” you will ever get- Priority and
_PID=cut noise when an incident has three overlapping services
Default output is current boot, oldest first, all priorities. That is the wrong window for almost every incident.
Mental Model
journal records
_SYSTEMD_UNIT= / SYSLOG_IDENTIFIER=
PRIORITY= 0 emerg … 7 debug
__REALTIME_TIMESTAMP=
_BOOT_ID=
_PID= _COMM= _EXE=
You almost always constrain THREE things:
who (-u, _PID=, path-to-binary)
when (--since / --until / -b)
how bad (-p)
-p err means err and worse, not “only err”.
Key Commands
# Failed units this boot, then their logs
systemctl --failed
journalctl -b -p err --no-pager
# One unit, recent, follow
journalctl -u nginx.service --since "1 hour ago"
journalctl -u nginx.service -f
# Previous boot vs this boot
journalctl --list-boots
journalctl -b -1 -p warning
journalctl -b -u sshd
# Time box an incident
journalctl --since "2026-09-18 07:40" --until "2026-09-18 08:10" -p info
journalctl --since "10 min ago" -u myapp
# Kernel / OOM
journalctl -k -b
journalctl -b -p err | grep -iE 'oom|killed process|ext4|xfs|nvme|i/o error'
# By process or binary
journalctl _PID=1234
journalctl /usr/sbin/sshd --since today
# Newest first, limited, script-friendly
journalctl -u myapp -r -n 80 --no-pager
journalctl -o short-iso -u myapp --since "-30min" --no-pager
journalctl -o json-pretty -n 5 -u myapp
# Disk usage and trim (do this on purpose, not as muscle memory)
journalctl --disk-usage
journalctl --vacuum-size=500M
journalctl --vacuum-time=14dUseful extra switches: -x (explanation text on some messages), -o verbose (see every field once so you know what you can filter on), --utc.
Common Failure Modes & Symptoms
| Need | Invocation |
|---|---|
| Why is this unit failed? | journalctl -u UNIT -b -p err -x --no-pager |
| What happened just before the crash? | --since 10 min before the timestamp + -u |
| Kernel / storage / OOM | journalctl -k -b and -p err |
| “It worked last boot” | --list-boots then -b -1 vs -b |
| Flooded output | -p warning, tighter --since, drop -f until filtered |
| Empty history after reboot | Journal not persistent — see persistence note |
| Permission denied | Not in systemd-journal / adm; use root or fix groups |
| Clock jump scrambled order | --utc and compare timedatectl |
Investigation Tips
- Pin a time window first. A busy node’s current-boot journal is not a page you read linearly.
- Start with
systemctl status UNIT -l --no-pagerthen jump tojournalctl -u UNIT --since …. - Compare
-band-b -1before you assume a config change “today” is the cause. Some units fail only on cold boot (network ordering, decrypt, DNS). -o verboseonce per incident type teaches you fields likeSYSLOG_IDENTIFIERandCODE_FUNCthat-umisses when a process logs under another name.journalctl -u UNIT -u UNIT2merges streams on one timeline. Use that for proxy + app + database instead of three terminals.- Vacuuming is capacity management, not troubleshooting. Snapshot
--disk-usagebefore you shrink anything during an incident.
Related Notes
- journalctl Deep Dive
- journald and Persistent Storage
- systemctl Deep Dive
- systemctl Command Reference
- Logging Architecture
- logrotate
- Troubleshooting Methodology
Personal Lessons Learned
- I used to
journalctl -u foowith no time bound and page for ten minutes.--since "20 min ago" -p infois the default I type now. - The “missing logs after reboot” incident was volatile journal on a cloud image. Persistence is a design choice, not a default you can assume.
- Merging
-u nginx -u myappshowed the 502 was the app crashing 200 ms before nginx logged it. Separate greps hid the order.