
September 10, 2026
12 min read
By Kokil Thapa | Last reviewed: September 2026
A full root partition at 3 a.m. is one of the fastest ways to take down a live site. Log rotation and disk space management on Linux exist to stop that failure mode before it starts. Application logs, web server access logs, database binary logs, and systemd journals all grow without bound unless you cap them. On production Ubuntu servers I maintain for Linux system administration clients, disk-full incidents from logs still rank among the top preventable outages. This guide covers the tools, configs, and commands that actually work in 2026.
What causes disk space problems from logs on Linux servers?
Logs are append-only by design. Every HTTP request, PHP error, cron run, and database write can add lines to disk. The problem compounds quietly. A busy Laravel app behind Apache can generate hundreds of megabytes of access logs per day. MySQL binary logs on a replication host can grow into tens of gigabytes if nobody trims them.
Three categories dominate disk consumption on web servers:
- System and service logs — syslog, auth.log, kern.log, and journald entries under /var/log and /var/log/journal
- Web stack logs — Apache or Nginx access and error logs, PHP-FPM slow logs, application logs in storage/logs
- Database and backup artefacts — MySQL binary logs, PostgreSQL WAL segments, stale SQL dumps left in /tmp or /home
I've seen a legal-tech portal lose its booking form because /var hit 100% capacity. Apache could not write error logs, PHP sessions failed, and MySQL rejected writes. The fix took ten minutes once we found the culprit. Prevention would have cost zero.
Understanding where logs land is step one. Step two is enforcing retention before the partition turns red. That split between discovery and policy is what separates stable servers from pager-duty weekends.
How does logrotate handle log rotation on Linux?
logrotate is the standard rotation engine on Debian and Ubuntu. It runs daily via cron or a systemd timer. It reads global rules from /etc/logrotate.conf and per-service snippets from /etc/logrotate.d/.
A typical rotation cycle does four things:
- Renames the active log file (for example access.log becomes access.log.1)
- Optionally compresses older files with gzip
- Creates a fresh empty log file with correct ownership
- Signals the service to reopen log handles via postrotate scripts
Global defaults in /etc/logrotate.conf
Ubuntu ships sensible defaults. Most custom configs inherit from them:
weekly
rotate 4
create
include /etc/logrotate.d
That means four weekly rotations before deletion unless a snippet overrides the schedule. For high-traffic web servers, weekly is too slow. Daily rotation with a size trigger is safer.
Apache logrotate example
On servers running Apache with PHP-FPM 8.3 or 8.4, I use a dedicated snippet at /etc/logrotate.d/apache2-custom:
/var/log/apache2/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 640 root adm
sharedscripts
postrotate
systemctl reload apache2 > /dev/null 2>&1 || true
endscript
}
Key directives explained:
- daily — rotate every day, not weekly
- rotate 14 — keep fourteen archived files (~two weeks)
- compress / delaycompress — gzip old logs but leave yesterday's uncompressed for easy tailing
- postrotate — reload Apache so it writes to the new file handle
Without postrotate, Apache keeps writing to the renamed inode. The new access.log stays empty while the rotated file keeps growing. That is a classic misconfiguration I still find on inherited servers.
Laravel application logs
Laravel writes to storage/logs/laravel.log by default. Framework logs are not covered by system logrotate unless you add them. For Deployer-managed releases on sites like Notary Kathmandu, the log path lives in the shared storage directory:
/var/www/example.com/shared/storage/logs/*.log {
daily
size 50M
rotate 7
compress
missingok
notifempty
copytruncate
}
copytruncate copies the log then truncates the original in place. Laravel and PHP-FPM do not need a reload signal. The trade-off is a small race window during copy. For most apps under moderate load, that is acceptable.
For structured application logging patterns in Laravel itself, see the guide on Laravel activity log with Spatie. Application-level audit trails and server-level rotation solve different problems. You need both on compliance-sensitive portals.
Test any new config before trusting it:
sudo logrotate -d /etc/logrotate.d/apache2-custom
sudo logrotate -f /etc/logrotate.d/apache2-custom
The -d flag dry-runs with verbose output. The -f flag forces an immediate rotation. Run both after every config change.
How do you manage systemd journal disk usage?
Modern Ubuntu servers store a large share of logs in the systemd journal, not plain files. The journal lives under /var/log/journal and can balloon silently. journald has its own retention controls separate from logrotate.
Check current journal size:
journalctl --disk-usage
Set limits in /etc/systemd/journald.conf:
[Journal]
SystemMaxUse=500M
SystemKeepFree=1G
MaxRetentionSec=30day
Compress=yes
Apply changes:
sudo systemctl restart systemd-journald
One-time cleanup for emergencies:
sudo journalctl --vacuum-size=200M
sudo journalctl --vacuum-time=14d
On shared EC2 hosts where multiple Laravel sites run under one account, I cap the journal at 500 MB. That leaves headroom for Apache logs and MySQL data on a 40 GB root volume. Budget-conscious hosting setups in Nepal often use modest VPS disks. Journal limits are not optional there.
Which tools find what is consuming disk space on Linux?
Rotation policies fail if you never look at disk usage. These commands belong in every admin's toolkit and in scheduled monitoring scripts.
Partition-level check
df -hT
df -h /var
Watch the Use% column on /var, /, and any separate /home or /data mounts. Above 85% warrants investigation. Above 95% is an incident.
Directory-level drill-down
sudo du -xh /var --max-depth=1 | sort -hr | head -20
sudo du -xh /var/log --max-depth=1 | sort -hr | head -20
Find individual monster files:
sudo find /var/log -type f -size +100M -exec ls -lh {} \;
sudo lsof +L1
lsof +L1 finds deleted files still held open by processes. The disk space is not freed until the process restarts. That happens after a logrotate without postrotate, or when a developer deletes a log manually while Apache keeps the handle.
Compare log management approaches
| Tool | Log type | Best for | Config location |
|---|---|---|---|
| logrotate | Plain text files | Apache, Nginx, PHP, app logs | /etc/logrotate.d/ |
| journald | Binary systemd journal | Service stdout, kernel, auth | /etc/systemd/journald.conf |
| MySQL expire_logs_days | Binary replication logs | MySQL 8.4 replication hosts | my.cnf or SET GLOBAL |
| Application logger | Structured app logs | Laravel Monolog channels | config/logging.php |
| Central aggregation | Shipped remote logs | Multi-server fleets | Loki, Fluent Bit agents |
For multi-server setups, file rotation alone is not enough. You also need shipping and central retention. The guides on log aggregation with Loki and Grafana and log aggregation for small teams cover that next step. On a single VPS running WooCommerce or a law-firm portal, local logrotate plus journald caps solve 90% of cases.
How do you automate monitoring and prevent log-related disk full events?
Rotation configs are static. Traffic is not. A viral blog post or brute-force auth storm can produce a week's worth of logs in hours. Automation closes that gap.
Cron-based disk checks
A simple guard script in /usr/local/bin/check-disk.sh:
#!/bin/bash
THRESHOLD=85
USAGE=$(df /var --output=pcent | tail -1 | tr -dc '0-9')
if [ "$USAGE" -ge "$THRESHOLD" ]; then
du -xh /var/log --max-depth=1 | sort -hr | head -10 > /tmp/disk-alert.txt
mail -s "Disk alert: /var at ${USAGE}%" admin@example.com < /tmp/disk-alert.txt
fi
Schedule it via cron. For systemd timer alternatives, see cron jobs explained and systemd service management.
MySQL binary log rotation
Replication and point-in-time recovery need binary logs. Uncapped binlogs have filled more disks than Apache ever did. On MySQL 8.4 LTS hosts:
expire_logs_days = 7
max_binlog_size = 100M
Verify with:
SHOW BINARY LOGS;
PURGE BINARY LOGS BEFORE DATE(NOW() - INTERVAL 7 DAY);
The dedicated guide on MySQL binary logs for replication and backup goes deeper. Binlog retention and automated database backups must be planned together. Purging logs you have not backed up destroys recovery options.
Monitoring with alerts
Netdata, Prometheus node_exporter, or a simple Nagios check on disk percentage all work. I prefer alerting at 80% with a top-ten /var/log breakdown included in the notification. That gives you time to act before writes fail. Read the setup walkthrough for Linux server monitoring with Netdata if you want a lightweight agent on Ubuntu 24.04.
PHP-FPM and opcache log paths
PHP-FPM slow logs and error logs live outside Apache's rotation scope unless configured. Add /var/log/php8.3-fpm.log or your pool-specific paths to logrotate. After Deployer symlink swaps on Adventure Third Pole Trek and sister sites, verify that shared log paths still match your rotation snippets. A changed release path silently breaks coverage.
For ongoing server hygiene beyond logs, support and maintenance contracts typically include disk audits, rotation reviews, and backup verification. Logs are one slice of a wider reliability picture that also covers testing and optimization work.
Log analysis without filling disk
SEO log file analysis for crawl diagnostics can tempt teams to retain months of raw access logs. That is valid for insight but expensive on disk. For technical SEO work, see SEO log file analysis. Rotate aggressively locally and ship compressed archives to object storage if you need long retention.
When parsing large JSON log exports locally, the JSON formatter tool helps inspect individual entries without loading them into a spreadsheet. It does not replace rotation policy, but it speeds up incident triage.
Key Takeaways
- Configure logrotate for every custom log path — Apache, PHP-FPM, Laravel storage/logs, and MySQL slow query logs are not always covered by defaults.
- Cap systemd journal size with SystemMaxUse in journald.conf; run journalctl --vacuum-size after emergencies.
- Always include postrotate reload scripts for Apache and Nginx, or use copytruncate for apps that cannot signal log reopen.
- Monitor /var at 80–85% with automated alerts that include a du breakdown of /var/log top consumers.
- Set MySQL binary log expiry explicitly; binlogs are a common hidden cause of full disks on replication hosts.
- Test configs with logrotate -d before deployment, and audit rotation coverage after every deployment path change.
People Also Ask
How often should logs rotate on a production web server?
Daily rotation is the baseline for Apache and Nginx access logs on any site with meaningful traffic. Add a size trigger (for example size 100M) so a traffic spike rotates early instead of waiting until midnight. Keep 7–14 compressed archives depending on compliance needs and available disk.
What happens if I delete a log file while the service is running?
The disk space is not freed. The process holds an open file descriptor to the deleted inode and keeps writing to it. Use logrotate with postrotate, or truncate with copytruncate, or restart the service. Check orphaned handles with lsof +L1.
Can logrotate compress logs automatically?
Yes. Add compress and delaycompress to any logrotate stanza. gzip reduces archived logs by 80–95% for typical text access logs. delaycompress skips compressing the most recent archive so you can tail yesterday's file without gunzip.
Is journald or logrotate enough on its own?
No. journald manages systemd's binary journal only. Apache, Nginx, PHP, Laravel, and MySQL write plain files that logrotate must handle separately. Production servers need both tools configured with explicit retention limits.
Build reliable servers before logs take them down
Log rotation and disk space management on Linux is not glamorous work. It is the kind of boring infrastructure that keeps Laravel booking apps, WooCommerce stores, and legal portals online when traffic spikes. Configure logrotate snippets, cap journald, expire MySQL binlogs, and alert on disk usage before you need emergency cleanup at 3 a.m.
If your production server has never had a rotation audit, assume gaps exist. For hands-on help configuring Ubuntu servers, rotation policies, and monitoring on sites you depend on, see the Linux system administration service or review deployed work in the portfolio. Need a full reliability review across hosting, backups, and logs? Contact us to discuss your server setup.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

