Every service on a VPS generates logs — Nginx access logs, MySQL slow queries, SSH authentication attempts, kernel messages, and application output. Without a management strategy, these logs silently consume disk space until they fill your partition, crash your services, and turn a routine maintenance problem into an emergency. This guide covers configuring journald and logrotate to control log growth, retain useful history, and keep your VPS running smoothly.
Why Log Management Matters on a VPS
A VPS typically has limited disk space — often 20 GB to 80 GB for entry-level plans. Logs are the silent culprit behind “No space left on device” errors. Uncontrolled logging can fill a 20 GB root partition in weeks, especially if you run a busy web server or database. Beyond storage, older logs help you diagnose incidents, detect security breaches, and tune performance — but only if they are rotated and archived instead of deleted or overwritten.
For more on performance tuning on a VPS, browse our performance optimization guides.
Understanding journald: Systemd’s Logging Daemon
Modern Linux distributions use systemd-journald to collect and store log entries from the kernel, systemd units, and services. Unlike traditional syslog, journald stores logs in a structured binary format with metadata (priority, facility, PID, boot ID). This makes filtering and querying more powerful.
Key journald Configuration
The configuration file is /etc/systemd/journald.conf. These are the most important settings for a VPS:
| Parameter | Default | VPS Recommendation | Notes |
|---|---|---|---|
SystemMaxUse | 10% of partition | 500M | Max disk space for journal |
MaxRetentionSec | Unlimited | 2week | Auto-delete entries older than this |
RuntimeMaxUse | 10% of /run | 50M | Max in-memory journal |
ForwardToSyslog | yes | no | Disable to avoid duplicate logs |
Compress | yes | yes | Keep compression enabled |
# Example /etc/systemd/journald.conf for a VPS
[Journal]
SystemMaxUse=500M
MaxRetentionSec=2week
RuntimeMaxUse=50M
ForwardToSyslog=no
Compress=yes
After editing, restart journald: sudo systemctl restart systemd-journald. Verify the limit with journalctl --disk-usage.
Querying Logs with journalctl
Journalctl is the command-line interface for reading journald logs. These are the most useful queries on a VPS:
# Last 50 lines (like tail)
journalctl -n 50
# Follow new entries (like tail -f)
journalctl -f
# Logs from last boot
journalctl -b -1
# Logs for a specific unit
journalctl -u nginx.service
# Logs from the last hour
journalctl --since "1 hour ago"
# Logs by priority (0=emerg, 2=crit, 3=err)
journalctl -p err -b
# Export logs to text for analysis
journalctl -u nginx.service --since "2025-01-01" --until "2025-01-02" > nginx-jan1.log
These queries are your first line of defense when debugging a VPS issue. Filtering by unit and priority reduces noise significantly.
Configuring logrotate for Traditional Log Files
Many applications still write to traditional text log files (Nginx, Apache, MySQL, custom scripts). Logrotate handles rotation, compression, and deletion of these files based on policies you define.
The main configuration file is /etc/logrotate.conf, and service-specific overrides go in /etc/logrotate.d/. Here is a practical VPS configuration:
# /etc/logrotate.conf - global defaults
weekly
rotate 4
create
compress
delaycompress
missingok
notifempty
# Include custom configs
include /etc/logrotate.d
Nginx Log Rotation Example
# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 $(cat /var/run/nginx.pid)
fi
endscript
}
This rotates Nginx logs daily, keeps 14 days of history, compresses older logs, and sends the USR1 signal to Nginx so it opens new log files without dropping connections.
MySQL Slow Query Log Rotation
# /etc/logrotate.d/mysql
/var/log/mysql/mysql-slow.log {
daily
rotate 7
compress
missingok
notifempty
create 640 mysql adm
postrotate
mysqladmin flush-logs -u root -pPASSWORD
endscript
}
Testing and Debugging Logrotate
Always test logrotate configuration before relying on it:
# Dry run (no changes)
sudo logrotate -d /etc/logrotate.conf
# Force a rotation
sudo logrotate -f /etc/logrotate.conf
# Check last rotation time
cat /var/lib/logrotate/status
The dry-run mode shows exactly what would happen without touching your files. Use it every time you edit a logrotate config.
Disk Space Monitoring and Alerts
Even with logrotate and journald limits, you should monitor disk usage. Add this simple check to your crontab:
# Check disk usage daily and alert if over 80%
0 6 * * * df -h / | awk '""NR==2 && +5>80 {print "Disk usage critical: "+5"%"}' | mail -s "VPS Disk Alert" [email protected]
For a more comprehensive monitoring setup, combine this with Uptime Kuma or Prometheus exporters. See our VPS guides and tutorials for more maintenance workflows.
journald vs. syslog: When to Use Each
On a modern VPS, you do not have to choose one exclusively. Journald is the default log collector, but many legacy tools and third-party monitoring agents expect plain-text log files. A practical hybrid approach:
- Let journald collect system logs and unit logs from systemd services.
- Use logrotate for application-generated log files (Nginx, MySQL, PHP-FPM, custom scripts).
- Forward critical journald logs to a central syslog server if you operate multiple VPS instances.
- Set
SystemMaxUseandMaxRetentionSecin journald, and configure logrotate for all text logs.
This combination gives you the query power of journalctl for recent events and the reliable archival of logrotate for long-term storage.
Conclusion
Log management is not exciting, but it is essential. A few minutes spent configuring journald limits and logrotate rules will save you from the “disk full” panic that inevitably hits at 2 AM. Set your limits, test your rotation, and monitor your usage — your future self will thank you.

Leave a Reply
You must be logged in to post a comment.