Log rotation and compression using logrotate | INTROSERV
EUR
european

EUR

usa

USD

English En
Ex. VAT Ex. VAT 0%

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:

  1. daily – rotate logs daily; you can also specify weekly or monthly.
  2. missingok – not fail with an error if the log file is missing.
  3. rotate 14 – keep 14 rotated copies before deletion.
  4. compress – compress rotated logs using gzip.
  5. delaycompress – do not compress the most recent rotation; useful if the application still holds the file open.
  6. notifempty – skip rotation if the log file is empty.
  7. 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 usually apache or nginx).
  8. sharedscripts – run the postrotate script once, even if multiple files matched.
  9. postrotate – signal the application to reopen its file handles after rotation.

Info

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

Info

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

Info

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

Info

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

VAT

  • Other

    Ex. VAT

    0%
  • austria

    Austria

    20%
  • Belgium

    Belgium

    21%
  • Bulgaria

    Bulgaria

    20%
  • Croatia

    Croatia

    25%
  • Cyprus

    Cyprus

    19%
  • Czech Republic

    Czech Republic

    21%
  • Denmark

    Denmark

    25%
  • Estonia

    Estonia

    22%
  • France

    France

    20%
  • Finland

    Finland

    24%
  • Germany

    Germany

    19%
  • Greece

    Greece

    24%
  • Hungary

    Hungary

    27%
  • Ireland

    Ireland

    23%
  • Italy

    Italy

    22%
  • Latvia

    Latvia

    21%
  • Lithuania

    Lithuania

    21%
  • Luxembourg

    Luxembourg

    17%
  • Malta

    Malta

    18%
  • Netherlands

    Netherlands

    21%
  • Poland

    Poland

    23%
  • Portugal

    Portugal

    23%
  • Romania

    Romania

    19%
  • Slovakia

    Slovakia

    20%
  • Slovenia

    Slovenia

    22%
  • Spain

    Spain

    21%
  • Sweden

    Sweden

    25%
  • USA

    USA

    0%
european
states
  • germany
  • Español
  • Italiano
  • Poland
  • Русский
  • Slovenski
  • Türkçe
  • ukraine
  • kingdom
  • French
  • Hrvatska
  • Other
  • Austria
  • Belgium
  • Bulgaria
  • Croatia
  • Cyprus
  • Czech Republic
  • Denmark
  • Estonia
  • Finland
  • France
  • Germany
  • Greece
  • Hungary
  • Ireland
  • Italy
  • Latvia
  • Lithuania
  • Luxembourg
  • Malta
  • Netherlands
  • Poland
  • Portugal
  • Romania
  • Slovakia
  • Slovenia
  • Spain
  • Sweden
  • USA