Server

journalctl Recipes You'll Actually Use

By Prabath Thalangama· October 24, 2026· 3 min read
#linux#systemd#troubleshooting

Introduction

journalctl is powerful but the man page is long. These are the invocations that come up again and again — bookmark this and you'll rarely need to look further.

Recipes

By unit

journalctl -u nginx.service                 # everything from this unit
journalctl -u nginx -u php-fpm              # merge two units, time-ordered
journalctl -u 'ssh*'                         # glob
journalctl _SYSTEMD_UNIT=nginx.service      # exact, includes stderr the unit wrote

By time

journalctl --since "2026-08-27 09:00" --until "2026-08-27 09:15"
journalctl --since "1 hour ago"
journalctl --since yesterday
journalctl -u nginx --since "10 min ago"

By boot

journalctl --list-boots            # index, boot ID, first/last timestamp
journalctl -b                      # current boot only
journalctl -b -1                   # the previous boot (post-crash forensics)
journalctl -k -b -1                # kernel messages from the previous boot

By priority

journalctl -p err                  # err and worse (crit, alert, emerg)
journalctl -p warning..err         # a range
journalctl -b -p 3                  # numeric: 0 emerg ... 7 debug

Follow live, cleanly

journalctl -u myapp -f             # tail -f equivalent
journalctl -u myapp -f -o cat      # just the message, no timestamp/host prefix
journalctl -fn 50 -u myapp         # start with the last 50 lines, then follow

By process / user / executable

journalctl _PID=12345
journalctl _UID=1000
journalctl /usr/sbin/sshd          # by executable path — great for auth logs
journalctl _COMM=sudo              # by command name

Machine-readable

journalctl -u myapp --since today -o json-pretty
journalctl -u myapp -o json | jq -r 'select(.PRIORITY <= "3") | .MESSAGE'
journalctl -u myapp --output=export      # for shipping elsewhere

Disk usage and rotation

journalctl --disk-usage
journalctl --vacuum-time=14d       # delete entries older than 14 days
journalctl --vacuum-size=500M      # cap total size
journalctl --verify                # check for corruption

Make it persistent

By default many distros keep the journal only in /run (RAM) — it's gone after a reboot, which is exactly when you want the previous boot's logs.

sudo mkdir -p /var/log/journal
sudo systemd-tmpfiles --create --prefix /var/log/journal
sudo systemctl restart systemd-journald

Then bound it in /etc/systemd/journald.conf:

[Journal]
Storage=persistent
SystemMaxUse=1G
SystemKeepFree=2G
MaxRetentionSec=1month

Verification and troubleshooting

  • -b -1 says "Failed to look up boot" — the journal isn't persistent, so there's no previous boot on disk. Enable persistence (above) now so it's there next time.
  • Empty output for a unit that's clearly logging — the app logs to a file, not stdout/stderr. Check the unit's ExecStart and the app config; or it logs under a different _SYSTEMD_UNIT (a @ templated unit, or a scope).
  • Timestamps look wrong — the journal stores UTC; display uses the system timezone. journalctl --utc to be sure, or fix timedatectl.
  • -f shows nothing but the service is busy — you filtered by .service and the messages are attributed to a child scope. Try _SYSTEMD_UNIT or drop the -u.
  • Journal huge, filling the disk — --vacuum-size for a one-off, then set SystemMaxUse permanently. A single chatty unit (-p debug left on, a crash loop) is the usual cause: journalctl --since "1h ago" -o cat | sort | uniq -c | sort -rn | head.
  • --verify reports corruption — usually an unclean shutdown; rotate past it with journalctl --rotate and vacuum the bad file.
PrabathStuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.