Rotating Nginx access and error logs keeps /var/log from growing until the filesystem fills, while preserving enough history to troubleshoot outages, investigate suspicious traffic, and compare performance over time.
Most Linux distributions rely on logrotate to rename and optionally compress log files on a schedule (often via cron or a systemd timer). Because Nginx keeps log files open, rotation must be followed by a reopen signal so the master process closes old file descriptors and resumes writing to the active log paths.
Retention, rotation frequency, and compression settings should match traffic volume and incident-response needs. Incorrect file patterns, permissions, or ownership can leave logs unrotated or stop logging entirely after a rotation, so a dry-run plus a one-time forced rotation provides a safe validation path before relying on the policy in production.
Related: How to secure Nginx web server
Related: How to locate Nginx access and error log files
Steps to configure log rotation for Nginx:
- Locate the logrotate configuration for Nginx.
$ ls -la /etc/logrotate.d/nginx -rw-r--r-- 1 root root 356 Dec 14 09:40 /etc/logrotate.d/nginx
- Confirm the Nginx log file paths matched by the rotation rule.
$ sudo grep -R --line-number -E '^[[:space:]]*(access_log|error_log)[[:space:]]' /etc/nginx/nginx.conf /etc/nginx/conf.d /etc/nginx/sites-enabled 2>/dev/null /etc/nginx/nginx.conf:52: access_log /var/log/nginx/access.log; /etc/nginx/nginx.conf:53: error_log /var/log/nginx/error.log warn;
Custom access_log or error_log paths require updating the logrotate glob (for example, changing /var/log/nginx/*.log).
- Review or create a rotation policy that fits the environment.
/var/log/nginx/*.log { daily rotate 14 compress delaycompress missingok notifempty sharedscripts postrotate if [ -s /run/nginx.pid ]; then kill -USR1 $(cat /run/nginx.pid) elif [ -s /var/run/nginx.pid ]; then kill -USR1 $(cat /var/run/nginx.pid) fi endscript }Nginx reopens logs on the USR1 signal, so the postrotate block prevents continued writes to the rotated file. Add a create line if new logs are not created after rotation. Set the user/group to match the deployment (common values include www-data or nginx). Avoid copytruncate on busy servers, since it can drop log lines during truncation.
- Test the rotation configuration in debug mode.
$ sudo logrotate -d /etc/logrotate.d/nginx reading config file /etc/logrotate.d/nginx Reading state from file: /var/lib/logrotate/status Allocating hash table for state file, size 64 entries Handling 1 logs rotating pattern: /var/log/nginx/*.log after 1 days (14 rotations) empty log files are not rotated, old logs are removed considering log /var/log/nginx/access.log log needs rotating considering log /var/log/nginx/error.log log needs rotating ##### snipped #####
- Force a rotation to validate the policy end-to-end.
$ sudo logrotate -vf /etc/logrotate.d/nginx reading config file /etc/logrotate.d/nginx ##### snipped ##### rotating pattern: /var/log/nginx/*.log forced from command line (14 rotations) renaming /var/log/nginx/access.log to /var/log/nginx/access.log.1 renaming /var/log/nginx/error.log to /var/log/nginx/error.log.1 running postrotate script ##### snipped #####
Force rotation changes files immediately, so run it during a maintenance window on busy servers.
- List the rotated log files to confirm retention/compression behavior.
$ ls -lh /var/log/nginx total 140M -rw-r----- 1 root adm 12M Dec 14 09:41 access.log -rw-r----- 1 root adm 98M Dec 14 09:40 access.log.1 -rw-r----- 1 root adm 14M Dec 13 09:40 access.log.2.gz -rw-r----- 1 root adm 2.1M Dec 14 09:41 error.log -rw-r----- 1 root adm 5.8M Dec 14 09:40 error.log.1 ##### snipped #####
- Generate a request to create a new access log entry.
$ curl -I http://127.0.0.1/ HTTP/1.1 200 OK Server: nginx Date: Sun, 14 Dec 2025 09:41:35 GMT Content-Type: text/html Content-Length: 612 Connection: keep-alive ##### snipped #####
- Confirm that Nginx is writing to the active log files.
$ sudo tail -n 5 /var/log/nginx/access.log 127.0.0.1 - - [14/Dec/2025:09:41:35 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/8.4.0" ##### snipped #####
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
