Debian/Ubuntu: Resolve Massive systemd Journal Log File Disk Usage & Implement Cleanup
Is your Debian/Ubuntu server running out of disk space due to systemd-journald logs? This guide shows you how to troubleshoot, clean up, and configure journald to prevent future log overgrowth.
Introduction
As a seasoned SysAdmin, few sights are as alarming as a df -h output showing your root partition at 95%+ utilization on a production server. More often than not, on modern Debian or Ubuntu systems, the culprit behind rapidly diminishing disk space isn’t always the usual suspects like /var/www or /var/lib/mysql. Instead, systemd-journald, the logging daemon for systemd, can silently accumulate gigabytes—sometimes even hundreds of gigabytes—of log data, especially in environments with high application activity, verbose debugging, or frequent errors from services like Nginx, Docker containers, or custom applications.
This comprehensive guide will walk you through identifying systemd-journald as the source of your disk space woes, immediately reclaiming precious storage, and — critically — configuring journald to prevent recurrence through intelligent log retention policies.
### Symptom & Error Signature
The primary symptom is a server experiencing critically low disk space on its primary partition, typically /. This can lead to various issues, including:
- Inability to write new files or logs.
- Service failures (e.g., Nginx failing to start, Docker images failing to pull).
- System instability and slowness.
- SSH sessions becoming unresponsive.
You’ll likely discover the issue using standard disk usage tools.
Typical Disk Usage Output (df -h):
root@webserver:~# df -h
Filesystem Size Used Avail Use% Mounted on
udev 7.8G 0 7.8G 0% /dev
tmpfs 1.6G 1.7M 1.6G 1% /run
/dev/sda1 98G 92G 1.2G 99% /
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
/dev/sdb1 200G 1.5G 198G 1% /data
tmpfs 1.6G 0 1.6G 0% /run/user/1000
Notice /dev/sda1 is at 99% usage.
To pinpoint journald as the culprit, you’d typically examine /var/log/journal.
Checking journald’s specific disk usage:
root@webserver:~# journalctl --disk-usage
Journals take up 85.5G on disk.
This command directly shows the total disk space consumed by systemd-journald logs. In this example, it confirms a massive 85.5 GB.
Alternatively, you might use du -sh /var/log/journal:
root@webserver:~# du -sh /var/log/journal
85G /var/log/journal
### Root Cause Analysis
systemd-journald is designed to be a robust, persistent logging system, storing logs in a structured, binary format rather than plain text files (though it can forward to syslog for plain text conversion). By default, on most modern Debian/Ubuntu installations, journald is configured for Storage=persistent, meaning logs survive reboots and are stored in /var/log/journal/.
The primary reasons for journald log files growing to massive sizes include:
- Default Configuration Limitations: Out-of-the-box,
journaldon some distributions might not have strict enough limits on the total disk space it can consume (SystemMaxUse) or the minimum free space it must leave on a filesystem (SystemKeepFree). Whilejournalddoes have internal mechanisms to rotate and prune logs, these defaults might be too generous for busy servers or smaller disks. - High Volume Logging:
- Verbose Applications: Applications (e.g., Nginx, Apache, Docker containers, databases) configured for excessive debug logging.
- Frequent Errors/Warnings: Continuous error messages from misconfigured services, failing cron jobs, or problematic applications. A flapping service (starting and stopping repeatedly) can generate an enormous number of log entries.
- Security Events: High volume of security-related logs (e.g., failed SSH login attempts) if not properly filtered or rate-limited.
- Lack of Proactive Management: Without explicit configuration,
journaldmight not prune old logs aggressively enough to keep up with the incoming log volume, especially on systems where disk space is at a premium. - Hardware or Kernel Issues: In rare cases, underlying hardware issues or kernel problems can cause a flood of error messages to be logged, rapidly filling up the journal.
Understanding these root causes is crucial for not just a temporary fix, but a sustainable log management strategy.
### Step-by-Step Resolution
This section outlines the process to immediately free up space and then configure journald to prevent future log bloat.
1. Assess Current Journal Usage
First, confirm journald is indeed the culprit and understand its current footprint.
journalctl --disk-usage
This command provides a concise summary of the disk space consumed by your system’s journal files.
2. Perform Immediate Log Cleanup
To reclaim disk space quickly, you can instruct journald to delete archived journal files based on size or age.
a. Cleanup by Size
This is often the most effective immediate solution. Replace 1G with your desired maximum size for the journal. This command will remove the oldest archived journal files until the total disk usage of the journal falls below the specified limit.
sudo journalctl --vacuum-size=1G
[!IMPORTANT] The
--vacuum-sizeoption does not delete active journal files. It only removes archived (closed) journal files. If your journal is still very large after this, it means the majority of the data is in currently active files. In most cases, specifying a reasonable size (e.g.,1Gor500M) should free up substantial space.
b. Cleanup by Time
You can also remove journal entries older than a specified duration. This is useful if you need to retain logs for a certain period for compliance or debugging.
# Delete all journal entries older than 7 days
sudo journalctl --vacuum-time=7d
# Delete all journal entries older than 1 month
sudo journalctl --vacuum-time=1M
[!NOTE] Combining
--vacuum-sizeand--vacuum-timein a single command will apply both constraints, ensuring both size and age limits are respected. For example:sudo journalctl --vacuum-size=1G --vacuum-time=7d
After running the cleanup command, verify the disk usage again:
journalctl --disk-usage
3. Configure Persistent Journald Log Limits
To prevent journald logs from growing out of control again, you must configure its retention policies. This is done by editing the journald configuration file.
a. Edit the journald.conf File
Open the main configuration file for journald using your preferred text editor.
sudo nano /etc/systemd/journald.conf
b. Set Configuration Parameters
Uncomment and set the following parameters. Here’s an explanation and recommended values for a typical web server:
SystemMaxUse=: The maximum amount of disk space the persistent journal files (in/var/log/journal) may consume. Once this limit is reached, the oldest archived journal files are deleted.- Recommendation:
500Mto2Gfor most web servers, depending on disk size and logging volume. Start conservatively.
- Recommendation:
SystemKeepFree=: The minimum amount of disk space thatjournaldshould leave free on the filesystem containing the journal files.journaldwill delete old entries to stay above this threshold. This is crucial for preventing a full disk.- Recommendation:
1Gto5G. This should be greater thanSystemMaxUseif possible, to ensure critical system operations aren’t impacted.
- Recommendation:
SystemMaxFileSize=: The maximum size of an individual journal file. When a file reaches this size, it is rotated. Smaller files make it easier to manage and transfer individual logs.- Recommendation:
50Mto200M.
- Recommendation:
RuntimeMaxUse=: Similar toSystemMaxUse, but for volatile journal data (in/run/log/journal), which is lost on reboot. This is less critical but good to set if you want to limit RAM/tmpfs usage.- Recommendation:
100M(or omit if you don’t use volatile logs).
- Recommendation:
Storage=: Defines where log data is stored.persistent: Stores logs in/var/log/journal(default, survives reboot).volatile: Stores logs in/run/log/journal(lost on reboot, if/var/log/journaldoesn’t exist).auto: Persistent if/var/log/journalexists, otherwise volatile.none: Disables journal storage entirely.- Recommendation: Keep as
persistentunless you have a specific reason to discard logs on reboot (e.g., highly ephemeral containers).
Here’s an example of a good configuration block for /etc/systemd/journald.conf:
[Journal]
# Uncomment and set the following lines:
Storage=persistent
SystemMaxUse=1G
SystemKeepFree=1G
SystemMaxFileSize=100M
#RuntimeMaxUse=100M # Uncomment if you want to limit volatile logs too
[!WARNING] Do not set
SystemKeepFree=lower than a critical threshold for your system. If your root filesystem only has 10GB free, settingSystemKeepFree=1Gmight be acceptable, but setting it to500Mif you have 100GB of total disk space is risky. Always ensure enough free space for OS operations and temporary files. A common best practice is to setSystemKeepFreeto a value that ensures critical operations can always occur.
c. Restart the systemd-journald Service
For the new configuration to take effect, you must restart the systemd-journald service.
sudo systemctl restart systemd-journald
[!IMPORTANT] Restarting
systemd-journaldwill apply the new configuration. It will not delete existing logs beyond the newSystemMaxUselimit immediately. The cleanup will happen gracefully as new logs come in and older files are rotated. If you need immediate cleanup, repeat step 2.
4. Monitor and Verify
After applying the configuration, it’s crucial to monitor your system’s disk usage and journald’s behavior over time.
- Check
journald’s usage periodically:journalctl --disk-usage - Monitor overall disk space:
df -h - Review your logs to ensure no critical information is being lost if you’ve set very aggressive limits.
If you find that logs are still growing too fast or too much is being pruned, adjust the SystemMaxUse and SystemKeepFree values in /etc/systemd/journald.conf accordingly and restart the service again.
5. Advanced: Identify Chatty Services
If journald is still filling up quickly even after setting limits, you might have one or more services logging excessively. You can identify these services to address the root cause of the high log volume.
# View logs from a specific service (e.g., Nginx)
sudo journalctl -u nginx.service
# View the last 100 entries from Docker containers
sudo journalctl -t docker -n 100
# See log entries with high priority (errors, critical, etc.)
sudo journalctl -p err -b
# Count log entries by service unit
sudo journalctl --disk-usage-by-unit
If a service is excessively verbose, consider adjusting its logging level in its own configuration file (e.g., Nginx error_log level, Docker container logging drivers) rather than solely relying on journald to prune.
By following these steps, you will not only resolve immediate disk space issues caused by systemd-journald but also establish a robust and sustainable log management strategy for your Debian or Ubuntu servers.
