journald Disk Usage: Why a Short Log Line Costs Tens of KB
A systemd bug report opened on January 3, 2026, put a number on something Linux admins had long suspected: systemd-journald writes far more data to disk than the log text it stores. The reporter, running systemd 257.9 on Debian 13 (kernel 6.12.57+deb13-amd64) with the journal on XFS, saw a virtual machine doing about 50 I/O operations per second while logging two short haproxy lines per second. In August, a systemd contributor measured it directly on ext4: a single short log message produced at least 55KB of disk writes. This guide covers what the report found, why the journal format behaves this way, and which settings in journald.conf actually limit how much disk a server's logs use.
journalctl --vacuum-size or --vacuum-time. To keep it under control, set SystemMaxUse, SystemKeepFree and Compress in /etc/systemd/journald.conf, with the size limits as absolute values rather than the defaults, which are capped at 4GB however large the disk is.The Report: 50 IOPS for Two Log Lines a Second
The original report is short. Its expected behaviour reads "Log writes should be within order of magnitude of syslog"; what the reporter saw was a VM doing roughly 50 IOPS for two lines of log a second. The sample entries were routine haproxy request lines of about 150 characters, nothing large or malformed.
The reporter measured at the VM level on purpose. An earlier, near-identical report, issue #15292, had been closed after the objection that iotop is not accurate. Measuring the traffic leaving the VM counts every write after the kernel has merged and cached what it can, which makes that objection hard to raise again.
The thread has grown to 25 comments. One user found journald had written almost 7GB to disk in 15 minutes during slowdowns on their machine. On August 3, 2026, contributor ValdikSS published a measured breakdown: with the journal on a dedicated ext4 loop device, compression off and SyncIntervalSec=10s, a single log message, or ten similar ones, produced at least 55KB of written data, and 14 messages produced 386KB of physical writes. A simulated syslog, appending text to a file with the same syncing, wrote about 21KB in total. A follow-up comment repeated the test on btrfs with copy-on-write disabled for the journal directory, and the per-message writes were larger again.
Why the Journal Writes So Much for So Little
The same contributor found the cause that surprised most readers of the thread: journald writes every new entry to its persistent files straight away. SyncIntervalSec only delays the fsync; it does not batch the data. The journal files are memory-mapped, so writing one small entry dirties whole pages: the entry itself, plus the index and hash-table structures the format updates so that journalctl can filter by unit, priority or boot. Each dirty page goes back to disk as a full block.
Compression does not change this. Per Debian's journald.conf(5) manual page, Compress= is on by default but only applies to data objects larger than 512 bytes, and a typical log line is shorter than that. The reporter confirmed that turning compression off made no meaningful difference. The cost is in the indexing, not the payload.
Two ideas have come up in the thread. A kernel developer posted an experimental patch for iomap-based filesystems such as XFS that dirties only the page actually written rather than the whole folio. Another suggestion was for journald to keep reading through mmap but write with pwrite. Neither had shipped as of the latest comments, so for now the controls are configuration.
The journald.conf Settings That Actually Matter
Every setting below goes in /etc/systemd/journald.conf, or in an override file in /etc/systemd/journald.conf.d/, and takes effect after a restart:
1sudo systemctl restart systemd-journald
Storage= sets where the journal lives. Per the manual page, persistent writes to /var/log/journal; volatile keeps everything in memory under /run/log/journal and loses it at reboot; auto acts like persistent if /var/log/journal exists and like volatile otherwise; none stores nothing locally but can still forward. On a box where logs from before a reboot do not matter, volatile removes the disk writes entirely.
SystemMaxUse= and SystemKeepFree= cap disk use. SystemMaxUse is the most the persistent journal may take; SystemKeepFree is how much space journald must leave for everything else. journald respects both and uses whichever is smaller. The defaults are 10% and 15% of the filesystem, and the manual page says each calculated default is capped at 4GB. SystemMaxFileSize= and SystemMaxFiles= work underneath, limiting the size and number of individual journal files.
A practical starting point for a small VPS:
1[Journal]
2Storage=persistent
3SystemMaxUse=2G
4SystemKeepFree=500M
5SystemMaxFileSize=200M
6Compress=yes
RateLimitIntervalSec= and RateLimitBurst= throttle a single noisy service, not the journal as a whole. If a service logs more messages within the interval than the burst allows, journald drops the rest until the interval ends and logs a message saying how many it dropped. These limit volume; they do not change what each message costs on disk.
The 4GB Ceiling
The 4GB cap catches people who set a percentage. In a 2019 write-up, an admin set SystemMaxUse=50% on a disk of about 30GB and found the journal stuck at exactly 4.0GB, holding only about 20 hours of logs. journald's own startup line showed why: "max allowed 4.0G". Setting an absolute value, SystemMaxUse=16G, raised the limit to 16GB.
The current manual page words the cap as applying to the calculated defaults, but an absolute size removes any doubt either way. To confirm what journald is actually using, read its own log after a restart:
1journalctl -u systemd-journald -n 5
The "Permanent journal is using X (max allowed Y, trying to leave Z free...)" line shows the limit in force.
Freeing Space Immediately with journalctl --vacuum
The settings above limit future growth; they do not shrink a journal that is already too big. For that, journalctl has three vacuum options:
1# Shrink until the archived journal files total under 500MB
2sudo journalctl --vacuum-size=500M
3
4# Delete archived journal files older than two weeks
5sudo journalctl --vacuum-time=2weeks
6
7# Keep only the five most recent archived files
8sudo journalctl --vacuum-files=5
Vacuuming only removes archived files, never the one journald is writing to. Per the Arch Linux wiki, files must be rotated and made inactive before vacuum can trim them; journalctl --rotate does that, and it can go in the same command as a vacuum option:
1sudo journalctl --rotate --vacuum-size=500M
Filtering and Forwarding Instead of Storing
If a central log server already keeps the history, local retention matters less. Per the Arch wiki, ForwardToSyslog= defaults to no because rsyslog and syslog-ng read from the journal themselves; turning it on adds a second write path rather than removing one. Pairing a central collector with Storage=volatile is the way to cut local disk writes.
For one noisy service, two per-unit options help:
- LogFilterPatterns= in the service's unit drop-in, documented in
systemd.exec(5), filters messages by a regular expression on their text. A pattern starting with~discards matching entries before they reach the journal, which suits a service that repeats one useless line. - LogNamespace=, described in the Arch wiki, gives a unit its own journal with its own
journald@<namespace>.conf, so it gets a separateSystemMaxUseand cannot use up the space meant for everything else.
What This Means on a Linux VPS
On a VPS with a small disk and shared storage, these writes are a real cost. Every short line rewrites whole blocks, so a handful of chatty services can produce far more disk traffic than their log text suggests. That means wear on SSD-backed storage, latency for neighbours on the same storage, and charges on any plan that bills for I/O.
Worth checking now:
- A VPS with a small disk, where journal space competes with application data
- A server running several services, where one noisy process can take the whole log budget
- Any server where nobody has run
journalctl --disk-usagesince it was built
Lower priority:
- A server with plenty of cheap disk and no I/O billing
- A box already forwarding everything to a central collector with
Storage=volatile
Summary
The bug report did not find a new defect so much as measure an old one: on ext4, a short log line can cost 55KB of disk writes, against about 21KB in total for a plain text log. Until a fix lands upstream, the controls are in your hands. Set SystemMaxUse and SystemKeepFree as absolute sizes, vacuum with --rotate when you need space back, filter or isolate noisy services, and use Storage=volatile where logs do not need to survive a reboot. Run journalctl --disk-usage, compare it with what /etc/systemd/journald.conf says, and start with the difference.
References
- Excessive IO caused by systemd-journald — systemd issue #40262
- Measured ext4 write breakdown — comment on issue #40262
- Earlier report — systemd issue #15292
- journald.conf(5) — Debian manual pages
- journalctl(1) — Debian manual pages
- systemd.exec(5) — Debian manual pages
- systemd/Journal — Arch Linux Wiki
- Logging a lot in journald — falkus.co
Posts in this series
- Linux VPS Performance Tuning: sysctl & swap 2026
- Systemd Service Hardening: Sandbox a Unit (2026)
- Fail2ban on Ubuntu VPS: Stop SSH Brute Force 2026
- UFW Firewall Rules for a Public VPS: 2026 Setup
- How to Harden SSH on an Ubuntu VPS (2026 Guide)
- Automated Backups with Rsync and Cron on Linux 2026
- TLS Certificates with Certbot on an Ubuntu VPS 2026
- Harden Nginx on Ubuntu: Headers, TLS & Limits 2026
- Automatic Security Updates on Ubuntu: 2026 Setup
- Logrotate for Nginx and App Logs on a Linux VPS
- Systemd Timers: Replace Cron Jobs on a Linux VPS
- Manage Linux Users and sudo Permissions on a VPS
- Linux VPS Disk and Inode Cleanup: du, find, lsof
- journald Logs: Retention, Size Limits and Queries
- How to Install Docker on a Linux VPS
- How to Monitor a Linux VPS with Netdata
- Valkey vs Redis: Choosing a Cache for Your Linux VPS
- SQL Workbench/J: Free Multi-Database Client for a Linux VPS
- How to Install MariaDB on an Ubuntu Linux VPS
- How to Set Up WireGuard on a Linux VPS
- How to Add a Swap File on a Linux VPS
- How to Install Portainer and Manage Docker on a Linux VPS
- journald Disk Usage: Why a Short Log Line Costs Tens of KB