System and users
journalctl
Read and filter the systemd journal, the log store for services, the kernel and the boot process.
journalctl [OPTION...] [MATCH...]
About these examples: the build sandbox is a container with no systemd journal, so the
examples on this page were not run and show no output; each says so. The one exception shows
what journalctl prints in a container like this one.
On a systemd system, everything a service writes to stdout or stderr, everything sent to syslog,
and the kernel's messages are collected by systemd-journald into a binary, indexed journal.
journalctl reads it. Because every entry carries structured fields (unit, PID, priority, boot
ID, timestamp), filtering is done with options rather than with grep on text files: -u for
a unit, -b for a boot, -p for a severity, --since/--until for a time window.
Output goes through a pager (less) when it is a terminal, oldest entries first. -e jumps to
the end, -r reverses the order, -n limits the count and -f follows new entries like
tail -f. Ordinary users see their own user-session logs; reading system logs needs root or
membership in the adm or systemd-journal group.
Examples
Show the logs of one service
journalctl -u nginx
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-u filters to entries from that unit, across all boots still in the journal, oldest first,
in the pager. Repeat -u to interleave several units in time order.
Follow a service's log live
journalctl -u nginx -f
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-f prints the last ten entries and then waits for new ones, like tail -f. Press Ctrl-C to
stop. Useful in a second terminal while you restart the service.
Show the last lines without a pager
journalctl -u nginx -n 50 --no-pager
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-n 50 keeps the 50 most recent entries and --no-pager prints them straight to the
terminal, which is what you want in scripts and when pasting into a ticket.
Show messages from the current or previous boot
journalctl -b
journalctl -b -1 -e
journalctl --list-boots
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-b limits output to the current boot; -b -1 is the previous one, the place to look after
an unexpected reboot, and -e jumps to its end. --list-boots shows which boots the journal
still holds. Previous boots are only kept if the journal is persistent (/var/log/journal
exists).
Show only errors and worse
journalctl -p err -b
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-p err shows priority err and everything more severe (crit, alert, emerg). Levels
can be names or numbers 0 to 7; a range such as -p warning..err is also accepted.
Show a time window
journalctl -u nginx --since '2026-03-14 08:00' --until '2026-03-14 09:00'
journalctl --since '1 hour ago'
journalctl --since today
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
--since and --until take absolute times, today, yesterday, or relative forms like
1 hour ago and -30min. Narrowing by time first is much faster than paging through
everything.
Show kernel messages
journalctl -k
journalctl -k -b -1
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-k shows only kernel messages from the current boot, the same content as dmesg but with
wall-clock timestamps. Add -b -1 for the previous boot, which dmesg cannot show, as long as
the journal is persistent.
Search message text
journalctl -u nginx -g 'upstream timed out' --since today
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-g (--grep) filters on the message with a regular expression; it is case-insensitive
unless the pattern contains uppercase. Combining it with -u and --since keeps the search
fast.
Get structured output for tools
journalctl -u nginx -n 3 -o json --no-pager | jq -r '._PID + " " + .MESSAGE'
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-o json prints one JSON object per entry with every field (MESSAGE, _PID,
PRIORITY, _SYSTEMD_UNIT and more), ready for jq. -o json-pretty is the readable
version of the same.
Print only the message text
journalctl -u myapp -o cat --since today
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
-o cat drops the timestamp, host and unit prefix and prints only the message, which is
handy when the application already writes its own timestamps or JSON lines.
See how much disk the journal uses
journalctl --disk-usage
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
Prints one line with the total size of active and archived journal files.
Shrink the journal
sudo journalctl --vacuum-time=2weeks
sudo journalctl --vacuum-size=500M
Not run in the sandbox: needs a systemd journal and root; not available in the build sandbox. No output is shown because none was captured.
Vacuuming deletes archived journal files older than the given age or until the total fits
the size. The active file is not touched, so run journalctl --rotate first if you need to
reclaim everything. For a permanent cap, set SystemMaxUse= in /etc/systemd/journald.conf.
Read your own user services' logs
journalctl --user -u sync.service -n 20
Not run in the sandbox: needs a systemd journal; not available in the build sandbox. No output is shown because none was captured.
Units started with systemctl --user log to your user journal, read with --user.
See what journalctl says when there is no journal
journalctl -n 5
No journal files were found. -- No entries --
This one did run, inside the build container. There are no journal files because no
journald is running, so journalctl reports that and exits successfully with nothing to
show. Logs of containerized programs go to the container runtime instead (docker logs).
Common pitfalls
Expecting logs from before the last reboot on a fresh install. Many systems keep the journal in memory only (
/run/log/journal); create/var/log/journal(or setStorage=persistent) to keep it across boots.Running
journalctl -u nginxas a normal user and seeing nothing. Without root or theadm/systemd-journalgroup you only see your own logs; there is a hint at the top of the output.Piping
journalctlintogrepover the whole journal. Filter by unit and time first (-u,--since), then use-gor grep on the much smaller result.Expecting
--vacuum-*to free space immediately. It only removes archived files; rotate first.
GNU vs BSD and macOS
The examples above ran the GNU/Linux version. These are the differences that matter on macOS and the BSDs (written from their documentation, not run here).
journalctlexists only on Linux systems running systemd. macOS haslog showandlog stream; the BSDs and systems without systemd use syslog text files under/var/log.
Options worth knowing
A selection, described in our own words. For the full list, see journalctl(1) or journalctl --help.
| Option | What it does |
|---|---|
-u, --unit UNIT | Show entries from this unit; repeatable. |
--user-unit UNIT | Show entries from this user unit. |
-f, --follow | Keep printing new entries as they arrive. |
-n, --lines N | Show the N most recent entries. |
-e, --pager-end | Jump to the end in the pager. |
-r, --reverse | Show the newest entries first. |
-b, --boot[=ID] | Show entries from a boot: current by default, -1 for the previous. |
--list-boots | List the boots recorded in the journal. |
-k, --dmesg | Show only kernel messages. |
-p, --priority LEVEL | Show entries at this priority or more severe, or a range. |
-g, --grep PATTERN | Show entries whose message matches a regular expression. |
-S, --since TIME | Show entries at or after TIME. |
-U, --until TIME | Show entries at or before TIME. |
-o, --output FORMAT | Output format: short, short-iso, cat, json, json-pretty, verbose and others. |
-x, --catalog | Add explanatory help text to messages that have it. |
--no-pager | Print directly instead of through a pager. |
--user | Show the current user's journal. |
--system | Show the system journal. |
--disk-usage | Show how much disk the journal files take. |
--vacuum-time TIME | Delete archived journal files older than TIME. |
--vacuum-size SIZE | Delete archived journal files until the total is below SIZE. |
--rotate | Archive the active journal files and start new ones. |
-D, --directory DIR | Read journal files from DIR instead of the default location. |
-i, --file FILE | Read this journal file. |
Related
systemctlStart, stop, enable and inspect services and other units managed by systemd.grepPrint the lines of files (or standard input) that match a pattern.tailPrint the last lines of files, or follow a file as it grows with -f.lessPage through a file or command output one screen at a time, with search and scrolling in both directions.jqQuery, filter and reshape JSON from the command line with a small expression language.