Log rotation and compression using logrotate
- Level: Intermediate
- Estimated time: ~20 minutes
- Goal: Configure logrotate to automatically compress and rotate application log files to prevent disk space exhaustion.
Introduction
Logs – are a critical part of managing any production application: without them, reliably understanding what went wrong and what to do about it would be very difficult. A busy application can generate thousands of entries per minute, and all of them are typically stored in files. We need to compress and delete old logs in a timely manner to avoid running out of disk space. In this tutorial, we will configure logrotate on a Linux server.
What is logrotate?
logrotate is a Linux utility designed to simplify the administration of systems that generate large numbers of log files. It allows logs to be automatically compressed, rotated, and deleted. It is typically run daily, weekly, or monthly via cron or a systemd timer.
Prerequisites
Before you begin, make sure the following conditions are met:
- Operating system: Ubuntu 20.04/22.04/24.04 LTS, Debian 11/12, or CentOS/RHEL 7+
- logrotate: version 3.x (check in step 1)
- Access: sudo or root access to the server
- Required knowledge: confident use of the Linux command line and basic file editing
Step 1: Verify logrotate installation
To verify the installation, simply run:
logrotate --version
Expected output:
logrotate 3.19.0 Default mail command: /usr/bin/mail Default compress command: /bin/gzip Default uncompress command: /bin/gunzip Default compress extension: .gz Default state file path: /var/lib/logrotate/status
If the command is not found – logrotate is not installed. Install it:
Debian/Ubuntu:
sudo apt install logrotate
CentOS/RHEL:
sudo yum install logrotate
Step 2: Understanding the configuration structure
The main config is located at /etc/logrotate.conf – we will leave it unchanged for now. Our rules for specific services will go in /etc/logrotate.d/ – a separate file should be placed there for each service.
Before adding anything, check whether a config for your service already exists:
ls /etc/logrotate.d/
For popular services such as nginx or Apache, configs are usually already present. If nginx or apache2 is already there – open that file and adjust the rotation count and compression settings to suit your needs, rather than creating a duplicate.
Step 3: Adding a service configuration
Suppose there is a custom application and its logs are located at /opt/myapp/*.log.
Create and open the file:
sudo nano /etc/logrotate.d/myapp
Paste the following inside:
/opt/myapp/*.log { daily missingok rotate 14 compress delaycompress notifempty create 0640 www-data adm sharedscripts postrotate systemctl reload myapp > /dev/null 2>&1 || true endscript }
This config instructs logrotate to:
- daily – rotate logs daily; you can also specify
weeklyormonthly. - missingok – not fail with an error if the log file is missing.
- rotate 14 – keep 14 rotated copies before deletion.
- compress – compress rotated logs using gzip.
- delaycompress – do not compress the most recent rotation; useful if the application still holds the file open.
- notifempty – skip rotation if the log file is empty.
- create 0640 www-data adm – create a new empty log file with the specified permissions, owner, and group. The owner should match the user under which the application runs (in Debian-based systems often
www-data, in RHEL-based systems usuallyapacheornginx). - sharedscripts – run the postrotate script once, even if multiple files matched.
- postrotate – signal the application to reopen its file handles after rotation.
If the directory /opt/myapp/ or the log files do not yet exist at the time of the first run, that's not a problem. The missingok directive will cause logrotate to silently skip the file without throwing an error. Log rotation will start automatically as soon as the application creates the logs.
Step 4: Testing the configuration
4.1 Dry run
After writing the configuration, it should be verified. The -d flag runs logrotate in debug mode – nothing is actually changed:
sudo logrotate -d /etc/logrotate.d/myapp
The -d mode outputs diagnostic information but does not modify any files.
4.2 Forced real run
If the dry run looks correct – force an actual rotation using the -f flag:
sudo logrotate -f /etc/logrotate.d/myapp
Important: The -f flag triggers an actual rotation. Run it only after the test run looks correct.
Step 5: Verifying the result
After the first few rotations, check the log directory:
ls -lh /opt/myapp/
Expected output:
total 28K -rw-r----- 1 www-data adm 0 Jan 17 12:00 app.log -rw-r----- 1 www-data adm 12K Jan 17 11:59 app.log.1 -rw-r----- 1 www-data adm 11K Jan 16 12:00 app.log.2.gz -rw-r----- 1 www-data adm 9K Jan 15 12:00 app.log.3.gz
The most recent rotation (app.log.1) remains uncompressed due to delaycompress. Everything older is gzipped. That is exactly what we wanted.
Step 6: Verifying the automatic schedule
logrotate runs automatically – via cron or a systemd timer, depending on the distribution.
Cron-based systems
cat /etc/cron.daily/logrotate
If the file exists – that is the file that runs logrotate daily.
Systemd-based systems
On newer systems, logrotate may be run via a systemd timer instead of cron.
Check:
systemctl list-timers | grep logrotate
You should see a timer with the last and next run times, something like:
Thu 2026-01-18 00:00:00 UTC 23h left Wed 2026-01-17 00:00:11 UTC 47 min ago logrotate.timer
If the logrotate.timer is missing from the output – the timer is disabled. Enable it:
sudo systemctl enable logrotate.timer
sudo systemctl start logrotate.timer
State file
You can check when logrotate last ran through its own state file:
cat /var/lib/logrotate/status
This is logrotate's own rotation history. After the first real run, you will see each log file with the date of its last rotation:
"/opt/myapp/app.log" 2026-1-17 "/var/log/nginx/access.log" 2026-1-17
If any log is not rotating when expected – this is the first place to look.
Rollback
To undo everything done, simply delete the config file from /etc/logrotate.d/:
sudo rm /etc/logrotate.d/myapp
This will stop log processing for your application. Already rotated files are not deleted.
To remove logrotate entirely:
Debian/Ubuntu:
sudo apt remove logrotate
CentOS/RHEL:
sudo yum remove logrotate
Important: Removing logrotate will disable log rotation for the entire system, including nginx, rsyslog, and other services that rely on it.
Conclusion
That is all. One well-written file in /etc/logrotate.d/, verified with -d – and it's done. Logs stay clean, the disk stays healthy, and you don't have to think about it anymore.
Document Version: 1.2
Last Updated: March 2026
Owner: Technical Documentation Team