{"id":3409,"date":"2025-12-26T16:55:32","date_gmt":"2025-12-26T13:55:32","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/vps-disk-usage-and-logrotate-prevent-no-space-left-on-device-errors\/"},"modified":"2025-12-26T16:55:32","modified_gmt":"2025-12-26T13:55:32","slug":"vps-disk-usage-and-logrotate-prevent-no-space-left-on-device-errors","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/vps-disk-usage-and-logrotate-prevent-no-space-left-on-device-errors\/","title":{"rendered":"VPS Disk Usage and logrotate: Prevent \u201cNo Space Left on Device\u201d Errors"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>On a busy <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a>, disk space rarely disappears because of a single huge file. Most of the time, it is a slow and silent growth: web server access logs, PHP error logs, database logs, mail logs, application logs, temporary files and forgotten backups. One day a deploy fails, MySQL cannot write to its tables, or your site stops accepting uploads, all because of the classic <strong>&#8220;No space left on device&#8221;<\/strong> error. The good news is that this is one of the most predictable and preventable issues on a VPS. With a clear view of <strong>VPS disk usage<\/strong> and a correctly tuned <strong>logrotate<\/strong> configuration, you can keep your logs under control without breaking compliance rules or losing useful data.<\/p>\n<p>In this article, we will look at how disk usage really behaves on a Linux VPS, how to diagnose what is filling the disk, how <strong>logrotate<\/strong> actually works, and which settings we use in production on dchost.com servers. We will finish with a practical checklist you can apply today to stop &#8220;No space left on device&#8221; errors before they reach your applications.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#How_Disk_Usage_Really_Works_on_a_VPS\"><span class=\"toc_number toc_depth_1\">1<\/span> How Disk Usage Really Works on a VPS<\/a><ul><li><a href=\"#Check_overall_disk_usage_with_df\"><span class=\"toc_number toc_depth_2\">1.1<\/span> Check overall disk usage with df<\/a><\/li><li><a href=\"#Do_not_forget_inodes\"><span class=\"toc_number toc_depth_2\">1.2<\/span> Do not forget inodes<\/a><\/li><li><a href=\"#Find_which_directories_are_heavy_with_du\"><span class=\"toc_number toc_depth_2\">1.3<\/span> Find which directories are heavy with du<\/a><\/li><\/ul><\/li><li><a href=\"#Common_Causes_of_8220No_Space_Left_on_Device8221_on_a_VPS\"><span class=\"toc_number toc_depth_1\">2<\/span> Common Causes of &#8220;No Space Left on Device&#8221; on a VPS<\/a><ul><li><a href=\"#1_Log_files_that_never_rotate\"><span class=\"toc_number toc_depth_2\">2.1<\/span> 1. Log files that never rotate<\/a><\/li><li><a href=\"#2_Application_caches_and_session_files\"><span class=\"toc_number toc_depth_2\">2.2<\/span> 2. Application caches and session files<\/a><\/li><li><a href=\"#3_Backups_and_dumps_stored_on_the_same_disk\"><span class=\"toc_number toc_depth_2\">2.3<\/span> 3. Backups and dumps stored on the same disk<\/a><\/li><li><a href=\"#4_Deleted_but_still-open_log_files\"><span class=\"toc_number toc_depth_2\">2.4<\/span> 4. Deleted but still-open log files<\/a><\/li><li><a href=\"#5_systemd_journal_growing_without_limits\"><span class=\"toc_number toc_depth_2\">2.5<\/span> 5. systemd journal growing without limits<\/a><\/li><\/ul><\/li><li><a href=\"#Emergency_Steps_When_the_Disk_Is_Already_Full\"><span class=\"toc_number toc_depth_1\">3<\/span> Emergency Steps When the Disk Is Already Full<\/a><ul><li><a href=\"#1_Confirm_the_situation\"><span class=\"toc_number toc_depth_2\">3.1<\/span> 1. Confirm the situation<\/a><\/li><li><a href=\"#2_Locate_large_directories\"><span class=\"toc_number toc_depth_2\">3.2<\/span> 2. Locate large directories<\/a><\/li><li><a href=\"#3_Safely_trim_obvious_log_bloat\"><span class=\"toc_number toc_depth_2\">3.3<\/span> 3. Safely trim obvious log bloat<\/a><\/li><li><a href=\"#4_Remove_old_local-only_backups\"><span class=\"toc_number toc_depth_2\">3.4<\/span> 4. Remove old, local-only backups<\/a><\/li><li><a href=\"#5_Restart_services_holding_deleted_files\"><span class=\"toc_number toc_depth_2\">3.5<\/span> 5. Restart services holding deleted files<\/a><\/li><\/ul><\/li><li><a href=\"#logrotate_Basics_How_It_Keeps_VPS_Disk_Usage_Under_Control\"><span class=\"toc_number toc_depth_1\">4<\/span> logrotate Basics: How It Keeps VPS Disk Usage Under Control<\/a><ul><li><a href=\"#Where_logrotate_lives\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Where logrotate lives<\/a><\/li><li><a href=\"#Key_logrotate_directives_in_plain_language\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Key logrotate directives in plain language<\/a><\/li><li><a href=\"#Dry-run_and_force_logrotate\"><span class=\"toc_number toc_depth_2\">4.3<\/span> Dry-run and force logrotate<\/a><\/li><\/ul><\/li><li><a href=\"#Practical_logrotate_Configurations_for_a_Web_VPS\"><span class=\"toc_number toc_depth_1\">5<\/span> Practical logrotate Configurations for a Web VPS<\/a><ul><li><a href=\"#Rotating_Nginx_logs_safely\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Rotating Nginx logs safely<\/a><\/li><li><a href=\"#Rotating_Apache_logs\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Rotating Apache logs<\/a><\/li><li><a href=\"#Rotating_PHP-FPM_error_logs\"><span class=\"toc_number toc_depth_2\">5.3<\/span> Rotating PHP-FPM error logs<\/a><\/li><li><a href=\"#Rotating_application_logs_Laravel_custom_apps_etc\"><span class=\"toc_number toc_depth_2\">5.4<\/span> Rotating application logs (Laravel, custom apps, etc.)<\/a><\/li><li><a href=\"#Rotating_MySQLMariaDB_logs\"><span class=\"toc_number toc_depth_2\">5.5<\/span> Rotating MySQL\/MariaDB logs<\/a><\/li><\/ul><\/li><li><a href=\"#Controlling_systemd_Journal_Size_journald\"><span class=\"toc_number toc_depth_1\">6<\/span> Controlling systemd Journal Size (journald)<\/a><ul><li><a href=\"#Set_journald_limits\"><span class=\"toc_number toc_depth_2\">6.1<\/span> Set journald limits<\/a><\/li><li><a href=\"#Clean_up_existing_journal_logs_with_care\"><span class=\"toc_number toc_depth_2\">6.2<\/span> Clean up existing journal logs (with care)<\/a><\/li><\/ul><\/li><li><a href=\"#Beyond_logrotate_A_Long-Term_Strategy_for_VPS_Disk_Usage\"><span class=\"toc_number toc_depth_1\">7<\/span> Beyond logrotate: A Long-Term Strategy for VPS Disk Usage<\/a><ul><li><a href=\"#1_Set_up_monitoring_and_alerts\"><span class=\"toc_number toc_depth_2\">7.1<\/span> 1. Set up monitoring and alerts<\/a><\/li><li><a href=\"#2_Consider_centralised_logging\"><span class=\"toc_number toc_depth_2\">7.2<\/span> 2. Consider centralised logging<\/a><\/li><li><a href=\"#3_Separate_critical_data_and_logs_on_different_partitions_or_servers\"><span class=\"toc_number toc_depth_2\">7.3<\/span> 3. Separate critical data and logs on different partitions or servers<\/a><\/li><li><a href=\"#4_Align_log_rotation_with_compliance_and_forensics\"><span class=\"toc_number toc_depth_2\">7.4<\/span> 4. Align log rotation with compliance and forensics<\/a><\/li><li><a href=\"#5_Plan_for_growth_and_right-size_your_VPS\"><span class=\"toc_number toc_depth_2\">7.5<\/span> 5. Plan for growth and right-size your VPS<\/a><\/li><\/ul><\/li><li><a href=\"#Step-by-Step_Checklist_to_Prevent_8220No_Space_Left_on_Device8221_on_Your_VPS\"><span class=\"toc_number toc_depth_1\">8<\/span> Step-by-Step Checklist to Prevent &#8220;No Space Left on Device&#8221; on Your VPS<\/a><ul><li><a href=\"#One-time_baseline\"><span class=\"toc_number toc_depth_2\">8.1<\/span> One-time baseline<\/a><\/li><li><a href=\"#logrotate_hardening\"><span class=\"toc_number toc_depth_2\">8.2<\/span> logrotate hardening<\/a><\/li><li><a href=\"#Ongoing_maintenance\"><span class=\"toc_number toc_depth_2\">8.3<\/span> Ongoing maintenance<\/a><\/li><\/ul><\/li><li><a href=\"#Conclusion_Keep_VPS_Disk_Usage_Predictable_and_Boring\"><span class=\"toc_number toc_depth_1\">9<\/span> Conclusion: Keep VPS Disk Usage Predictable and Boring<\/a><\/li><\/ul><\/div>\n<h2><span id=\"How_Disk_Usage_Really_Works_on_a_VPS\">How Disk Usage Really Works on a VPS<\/span><\/h2>\n<p>Before touching logrotate, you need a reliable mental model for how disk space is used and reported on your VPS. Otherwise, you will fix one directory and still be surprised by another mount point filling up.<\/p>\n<h3><span id=\"Check_overall_disk_usage_with_df\">Check overall disk usage with df<\/span><\/h3>\n<p>The first step is to see which filesystem is actually full:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">df -h\nFilesystem      Size  Used Avail Use% Mounted on\n\/dev\/vda1        40G   35G  3.8G  91% \/\ntmpfs           399M     0  399M   0% \/run\/user\/0\n<\/code><\/pre>\n<p>Key points:<\/p>\n<ul>\n<li><strong>Use% above ~80\u201385%<\/strong> on root (<code>\/<\/code>) is a warning sign; above 90% is serious.<\/li>\n<li>On some setups, <code>\/var<\/code>, <code>\/home<\/code>, <code>\/tmp<\/code> or <code>\/var\/lib\/mysql<\/code> are on separate partitions; always check each mount point.<\/li>\n<\/ul>\n<h3><span id=\"Do_not_forget_inodes\">Do not forget inodes<\/span><\/h3>\n<p>Even with free GBs, you can hit &#8220;No space left on device&#8221; because you ran out of <strong>inodes<\/strong> (the metadata entries that track files). Check with:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">df -i\nFilesystem      Inodes  IUsed   IFree IUse% Mounted on\n\/dev\/vda1      2621440 120000 2501440    5% \/\n<\/code><\/pre>\n<p>If <code>IUse%<\/code> hits 100%, you have too many small files (often in cache or session directories). The fix is to clear or rotate these, not to grow the disk blindly.<\/p>\n<h3><span id=\"Find_which_directories_are_heavy_with_du\">Find which directories are heavy with du<\/span><\/h3>\n<p>Once you know which filesystem is full, use <code>du<\/code> to drill down:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">cd \/\nsudo du -xh --max-depth=1 | sort -h\n<\/code><\/pre>\n<p>This shows which top-level directories are consuming space (for example <code>\/var<\/code>, <code>\/home<\/code>, <code>\/var\/log<\/code>, <code>\/var\/lib<\/code>). Then descend step by step:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">cd \/var\nsudo du -xh --max-depth=1 | sort -h\n<\/code><\/pre>\n<p>On real dchost.com customer VPS setups, we often see most of the disk used by:<\/p>\n<ul>\n<li><code>\/var\/log<\/code> \u2013 web, PHP, database, mail and system logs<\/li>\n<li><code>\/var\/lib\/mysql<\/code> or <code>\/var\/lib\/postgresql<\/code> \u2013 databases and binary logs<\/li>\n<li><code>\/home\/USER<\/code> or <code>\/var\/www<\/code> \u2013 file uploads, backups, caches<\/li>\n<li><code>\/tmp<\/code> or <code>\/var\/tmp<\/code> \u2013 session files, temporary uploads, uncleaned application temp files<\/li>\n<\/ul>\n<h2><span id=\"Common_Causes_of_8220No_Space_Left_on_Device8221_on_a_VPS\">Common Causes of &#8220;No Space Left on Device&#8221; on a VPS<\/span><\/h2>\n<p>Now that you know where to look, let us list the usual suspects we see during VPS audits and support tickets.<\/p>\n<h3><span id=\"1_Log_files_that_never_rotate\">1. Log files that never rotate<\/span><\/h3>\n<p>This is by far the top reason. Even a medium-traffic site can generate:<\/p>\n<ul>\n<li>Gigabytes of web server access logs (<code>access.log<\/code>)<\/li>\n<li>PHP or application error logs when a bug spams the same stack trace<\/li>\n<li>Mail server logs (<code>maillog<\/code>, <code>exim<\/code>, <code>postfix<\/code> logs)<\/li>\n<li>Database error logs and slow query logs<\/li>\n<\/ul>\n<p>If <strong>logrotate<\/strong> is misconfigured, or some custom log files are not included in <code>\/etc\/logrotate.d\/<\/code>, a single file can reach tens of GB and push the filesystem over 100%.<\/p>\n<h3><span id=\"2_Application_caches_and_session_files\">2. Application caches and session files<\/span><\/h3>\n<p>Frameworks and CMSs (WordPress, Laravel, Magento, custom apps) often store cache and sessions in:<\/p>\n<ul>\n<li><code>\/var\/www\/example.com\/storage\/framework\/cache<\/code> (Laravel)<\/li>\n<li><code>\/var\/lib\/php\/sessions<\/code> (PHP sessions)<\/li>\n<li><code>\/tmp<\/code> (generic temp files)<\/li>\n<\/ul>\n<p>If you never purge these, millions of small files can accumulate. You might hit an <strong>inode limit<\/strong> before filling the disk in GB terms. Our separate article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/linux-dosya-izinleri-644-755-777-paylasimli-hosting-ve-vps-icin-guvenli-ayarlar\/\">Linux file permissions on shared hosting and VPS<\/a> is also helpful here, because incorrect permissions sometimes prevent automated cleanups from running.<\/p>\n<h3><span id=\"3_Backups_and_dumps_stored_on_the_same_disk\">3. Backups and dumps stored on the same disk<\/span><\/h3>\n<p>A common pattern is a nightly <code>mysqldump<\/code> or <code>tar<\/code> of the full site stored in <code>\/home<\/code> or <code>\/root<\/code> without automatic pruning. After a few weeks, you have dozens of backups and no free space. For a deeper dive into realistic backup planning, look at our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/yedekleme-stratejisi-nasil-planlanir-blog-e-ticaret-ve-saas-siteleri-icin-rpo-rto-rehberi\/\">how to design a backup strategy with RPO\/RTO in mind<\/a>.<\/p>\n<h3><span id=\"4_Deleted_but_still-open_log_files\">4. Deleted but still-open log files<\/span><\/h3>\n<p>Even if you delete a huge log file, the space might not be freed if some process still has that file open. The disk remains full, and you still see &#8220;No space left on device&#8221;.<\/p>\n<p>Find such files with:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo lsof | grep deleted\n<\/code><\/pre>\n<p>If you see large <code>(deleted)<\/code> files referenced by <code>nginx<\/code>, <code>php-fpm<\/code>, <code>httpd<\/code> or another daemon, you must restart that service so it releases the file handle.<\/p>\n<h3><span id=\"5_systemd_journal_growing_without_limits\">5. systemd journal growing without limits<\/span><\/h3>\n<p>On modern distributions, <code>systemd-journald<\/code> stores logs in <code>\/var\/log\/journal<\/code>. Without limits, it can grow to many gigabytes, especially on noisy systems. We will show how to configure safe limits in a later section.<\/p>\n<h2><span id=\"Emergency_Steps_When_the_Disk_Is_Already_Full\">Emergency Steps When the Disk Is Already Full<\/span><\/h2>\n<p>If your VPS is already returning &#8220;No space left on device&#8221;, you need a calm, step-by-step approach so you do not break databases or the OS while freeing space.<\/p>\n<h3><span id=\"1_Confirm_the_situation\">1. Confirm the situation<\/span><\/h3>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">df -h\n<\/code><\/pre>\n<p>Identify which filesystem is 100% full. If only <code>\/boot<\/code> or a small partition is full, the fix is different than when root (<code>\/<\/code>) is full.<\/p>\n<h3><span id=\"2_Locate_large_directories\">2. Locate large directories<\/span><\/h3>\n<p>Start with the full filesystem\u2019s mount point:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">cd \/               # or \/var, \/home, etc.\nsudo du -xh --max-depth=2 | sort -h | tail -n 20\n<\/code><\/pre>\n<p>This gives you the largest directories. Usually, <code>\/var\/log<\/code> or a backup directory stands out.<\/p>\n<h3><span id=\"3_Safely_trim_obvious_log_bloat\">3. Safely trim obvious log bloat<\/span><\/h3>\n<p>When you identify an oversized log file (for example <code>\/var\/log\/nginx\/access.log<\/code>), you can truncate it instead of deleting it:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo truncate -s 0 \/var\/log\/nginx\/access.log\n<\/code><\/pre>\n<p>This keeps file ownership and permissions intact, which is safer than <code>rm<\/code> in production. For heavily used logs, consider:<\/p>\n<ul>\n<li>Rotating them on the spot: <code>sudo logrotate -f \/etc\/logrotate.d\/nginx<\/code><\/li>\n<li>Then confirming new compressed files have appeared and the active log file is small again<\/li>\n<\/ul>\n<p><strong>Warning:<\/strong> do not randomly delete directories like <code>\/var\/lib\/mysql<\/code>, <code>\/var\/lib\/postgresql<\/code> or <code>\/etc<\/code> just to gain space. You will corrupt services and databases.<\/p>\n<h3><span id=\"4_Remove_old_local-only_backups\">4. Remove old, local-only backups<\/span><\/h3>\n<p>If you find directories like <code>\/root\/backups\/<\/code> or <code>\/home\/user\/backup-YYYYMMDD.tar.gz<\/code>, decide which ones are safe to remove. Ensure you have at least one recent, verified offsite backup before cleaning. If you are evaluating offsite options, our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/restic-ve-borg-ile-s3-uyumlu-uzak-yedekleme-surumleme-sifreleme-ve-saklama-ne-zaman-nasil\/\">offsite backups with restic\/Borg to S3-compatible storage<\/a> is a practical next step.<\/p>\n<h3><span id=\"5_Restart_services_holding_deleted_files\">5. Restart services holding deleted files<\/span><\/h3>\n<p>If <code>lsof | grep deleted<\/code> reveals large deleted log files still referenced by daemons, restart only those services:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo systemctl restart nginx\nsudo systemctl restart php-fpm\n<\/code><\/pre>\n<p>After that, confirm disk usage dropped with <code>df -h<\/code>. When the system is stable again, you can move on to permanent logrotate and journald tuning.<\/p>\n<h2><span id=\"logrotate_Basics_How_It_Keeps_VPS_Disk_Usage_Under_Control\">logrotate Basics: How It Keeps VPS Disk Usage Under Control<\/span><\/h2>\n<p><strong>logrotate<\/strong> is the standard tool on most Linux distributions to automatically rotate, compress and prune log files. Understanding a few directives is enough to build robust configurations for a typical web VPS.<\/p>\n<h3><span id=\"Where_logrotate_lives\">Where logrotate lives<\/span><\/h3>\n<ul>\n<li>Main config: <code>\/etc\/logrotate.conf<\/code><\/li>\n<li>Per-service configs: <code>\/etc\/logrotate.d\/<\/code> (for example <code>nginx<\/code>, <code>apache2<\/code>, <code>mysql<\/code>)<\/li>\n<\/ul>\n<p>logrotate is usually triggered daily via <code>cron<\/code> or a <code>systemd<\/code> timer, which reads these configuration files and decides what to rotate.<\/p>\n<h3><span id=\"Key_logrotate_directives_in_plain_language\">Key logrotate directives in plain language<\/span><\/h3>\n<ul>\n<li><strong>daily \/ weekly \/ monthly<\/strong> \u2013 how often to check and rotate the log.<\/li>\n<li><strong>size 100M<\/strong> \u2013 rotate logs when they reach or exceed 100 MB, even if the time-based period has not passed. Size-based rotation is very powerful to avoid &#8220;No space left on device&#8221; incidents.<\/li>\n<li><strong>rotate 14<\/strong> \u2013 keep 14 rotated files (for example two weeks if rotating daily), then delete the oldest.<\/li>\n<li><strong>compress<\/strong> \u2013 compress old log files (usually with gzip) to save space.<\/li>\n<li><strong>delaycompress<\/strong> \u2013 start compressing from the second rotated file, leaving the most recent one uncompressed for tools that might still read it.<\/li>\n<li><strong>missingok<\/strong> \u2013 do not complain if the log file does not exist.<\/li>\n<li><strong>notifempty<\/strong> \u2013 do not rotate empty log files.<\/li>\n<li><strong>create 0640 www-data adm<\/strong> \u2013 after rotating, create a new log file with given permissions and owner\/group.<\/li>\n<li><strong>copytruncate<\/strong> \u2013 copy the current log to a rotated file and truncate the original in place. Used for daemons that cannot be cleanly told to reopen log files.<\/li>\n<li><strong>dateext<\/strong> \u2013 append a date to rotated logs instead of just a numeric suffix.<\/li>\n<\/ul>\n<h3><span id=\"Dry-run_and_force_logrotate\">Dry-run and force logrotate<\/span><\/h3>\n<p>Before applying new rules, test:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo logrotate -d \/etc\/logrotate.conf\n<\/code><\/pre>\n<p>The <code>-d<\/code> flag shows what logrotate would do, without touching files. To force a rotation (useful for testing or emergency cleanup):<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo logrotate -f \/etc\/logrotate.conf\n<\/code><\/pre>\n<h2><span id=\"Practical_logrotate_Configurations_for_a_Web_VPS\">Practical logrotate Configurations for a Web VPS<\/span><\/h2>\n<p>Let us look at realistic example configurations for common services on a VPS: Nginx\/Apache, PHP-FPM and MySQL\/MariaDB. You can adapt the same patterns for your application logs.<\/p>\n<h3><span id=\"Rotating_Nginx_logs_safely\">Rotating Nginx logs safely<\/span><\/h3>\n<p>Create or edit <code>\/etc\/logrotate.d\/nginx<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/var\/log\/nginx\/*.log {\n    daily\n    size 50M\n    rotate 14\n    missingok\n    notifempty\n    compress\n    delaycompress\n    sharedscripts\n    create 0640 www-data adm\n    postrotate\n        [ -s \/run\/nginx.pid ] &amp;&amp; kill -USR1 $(cat \/run\/nginx.pid)\n    endscript\n}\n<\/code><\/pre>\n<p>Why these options?<\/p>\n<ul>\n<li><strong>daily + size 50M<\/strong> \u2013 rotate at least once per day and earlier if a log grows too fast.<\/li>\n<li><strong>rotate 14<\/strong> \u2013 about two weeks of logs; adjust for your compliance needs.<\/li>\n<li><strong>postrotate &#8230; kill -USR1<\/strong> \u2013 tells Nginx to reopen log files gracefully without downtime.<\/li>\n<\/ul>\n<h3><span id=\"Rotating_Apache_logs\">Rotating Apache logs<\/span><\/h3>\n<p>On Apache-based servers, you will see something like this in <code>\/etc\/logrotate.d\/apache2<\/code> or <code>\/etc\/logrotate.d\/httpd<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/var\/log\/apache2\/*.log {\n    daily\n    size 100M\n    rotate 14\n    missingok\n    notifempty\n    compress\n    delaycompress\n    sharedscripts\n    postrotate\n        \/usr\/sbin\/apachectl graceful &gt; \/dev\/null 2&gt;&amp;1 || true\n    endscript\n}\n<\/code><\/pre>\n<p>This gracefully reloads Apache after rotation so it writes to the new log files.<\/p>\n<h3><span id=\"Rotating_PHP-FPM_error_logs\">Rotating PHP-FPM error logs<\/span><\/h3>\n<p>PHP-FPM often logs to <code>\/var\/log\/php8.1-fpm.log<\/code> (or similar). Example <code>\/etc\/logrotate.d\/php-fpm<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/var\/log\/php*-fpm.log {\n    weekly\n    size 50M\n    rotate 8\n    missingok\n    notifempty\n    compress\n    delaycompress\n    create 0640 www-data adm\n    postrotate\n        \/usr\/sbin\/service php8.1-fpm reload &gt; \/dev\/null 2&gt;&amp;1 || true\n    endscript\n}\n<\/code><\/pre>\n<p>You can change <code>weekly<\/code> to <code>daily<\/code> on high-traffic systems or during debugging phases where logs grow quickly.<\/p>\n<h3><span id=\"Rotating_application_logs_Laravel_custom_apps_etc\">Rotating application logs (Laravel, custom apps, etc.)<\/span><\/h3>\n<p>Many frameworks store logs under <code>storage\/logs<\/code> or similar. You can create a generic rule:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/var\/www\/*\/storage\/logs\/*.log {\n    daily\n    size 20M\n    rotate 10\n    missingok\n    notifempty\n    compress\n    delaycompress\n    copytruncate\n}\n<\/code><\/pre>\n<p>Here we use <strong>copytruncate<\/strong> because application processes may not handle <code>SIGUSR1<\/code> or SIGHUP-based log reopening nicely. copytruncate is slightly less safe for high-traffic logs but usually fine for application logs.<\/p>\n<h3><span id=\"Rotating_MySQLMariaDB_logs\">Rotating MySQL\/MariaDB logs<\/span><\/h3>\n<p>MySQL has multiple types of logs: error log, slow query log and binary logs. Binary logs are usually managed by MySQL\u2019s own configuration (<code>expire_logs_days<\/code> or <code>binlog_expire_logs_seconds<\/code>). For error and slow logs, logrotate is appropriate.<\/p>\n<p>An example for the error log (<code>\/var\/log\/mysql\/error.log<\/code>):<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">\/var\/log\/mysql\/*.log {\n    daily\n    size 50M\n    rotate 10\n    missingok\n    notifempty\n    compress\n    delaycompress\n    create 0640 mysql adm\n    sharedscripts\n    postrotate\n        test -x \/usr\/bin\/mysqladmin || exit 0\n        if [ -f \/var\/run\/mysqld\/mysqld.pid ]; then\n           \/usr\/bin\/mysqladmin --defaults-file=\/etc\/mysql\/debian.cnf flush-logs &gt; \/dev\/null 2&gt;&amp;1 || true\n        fi\n    endscript\n}\n<\/code><\/pre>\n<p>On heavily loaded ecommerce databases, you may also want to tune MySQL itself for fewer slow queries and less noisy logs. Our checklist on <a href=\"https:\/\/www.dchost.com\/blog\/en\/woocommerce-icin-mysql-innodb-tuning-kontrol-listesi-buffer-pool-indeksleme-ve-slow-query-analizi-nasil-akillica-yapilir\/\">MySQL\/InnoDB tuning for WooCommerce<\/a> provides a practical roadmap.<\/p>\n<h2><span id=\"Controlling_systemd_Journal_Size_journald\">Controlling systemd Journal Size (journald)<\/span><\/h2>\n<p>Even if all classic text logs are rotated, <code>systemd-journald<\/code> can still fill <code>\/var\/log\/journal<\/code> if not limited. The journal is stored in a binary format and can grow quietly in the background.<\/p>\n<h3><span id=\"Set_journald_limits\">Set journald limits<\/span><\/h3>\n<p>Edit (or create a drop-in) <code>\/etc\/systemd\/journald.conf<\/code> and adjust these options:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">[Journal]\nSystemMaxUse=1G\nSystemMaxFileSize=200M\nMaxRetentionSec=1month\n<\/code><\/pre>\n<p>Explanation:<\/p>\n<ul>\n<li><strong>SystemMaxUse=1G<\/strong> \u2013 cap total journal size under 1 GB.<\/li>\n<li><strong>SystemMaxFileSize=200M<\/strong> \u2013 each individual journal file stays below 200 MB.<\/li>\n<li><strong>MaxRetentionSec=1month<\/strong> \u2013 keep at most one month of journal logs.<\/li>\n<\/ul>\n<p>Then apply changes:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo systemctl restart systemd-journald\n<\/code><\/pre>\n<h3><span id=\"Clean_up_existing_journal_logs_with_care\">Clean up existing journal logs (with care)<\/span><\/h3>\n<p>To see journal disk usage:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">journalctl --disk-usage\n<\/code><\/pre>\n<p>To vacuum old data while keeping at least 1 GB or 30 days of logs:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo journalctl --vacuum-size=1G\nsudo journalctl --vacuum-time=30d\n<\/code><\/pre>\n<p>Always balance cleanup with compliance needs. If you operate in regulated environments (payment, healthcare, etc.), check your logging and retention obligations first. Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/hosting-ve-e-posta-altyapisinda-log-saklama-sureleri\/\">log retention on hosting and email infrastructure for KVKK\/GDPR compliance<\/a> is a useful reference.<\/p>\n<h2><span id=\"Beyond_logrotate_A_Long-Term_Strategy_for_VPS_Disk_Usage\">Beyond logrotate: A Long-Term Strategy for VPS Disk Usage<\/span><\/h2>\n<p>Correct logrotate settings stop basic &#8220;No space left on device&#8221; errors, but healthy VPS disk usage also needs monitoring, smarter log storage and clear retention policies.<\/p>\n<h3><span id=\"1_Set_up_monitoring_and_alerts\">1. Set up monitoring and alerts<\/span><\/h3>\n<p>Do not wait for users to complain. At dchost.com, we strongly recommend:<\/p>\n<ul>\n<li>Disk usage alerts when a filesystem passes 80% and 90%<\/li>\n<li>Inode usage alerts above 70\u201380%<\/li>\n<li>Log-specific alerts when error logs grow abnormally fast<\/li>\n<\/ul>\n<p>If you want a hands-on example, our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-izleme-ve-alarm-kurulumu-prometheus-grafana-ve-uptime-kuma-ile-baslangic\/\">VPS monitoring and alerts with Prometheus, Grafana and Uptime Kuma<\/a> shows how to build a practical monitoring stack that includes disk space dashboards and alarms.<\/p>\n<h3><span id=\"2_Consider_centralised_logging\">2. Consider centralised logging<\/span><\/h3>\n<p>On multi-VPS or growing environments, you may not want all logs to live on the same disk as your web application. Sending logs to a central logging stack keeps individual servers lighter and simplifies searching.<\/p>\n<p>We have a step-by-step playbook on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-log-yonetimi-nasil-rayina-oturur-grafana-loki-promtail-ile-merkezi-loglama-tutma-sureleri-ve-alarm-kurallari\/\">centralised VPS log management with Grafana Loki and Promtail<\/a> that covers retention, indexing and alert rules. Offloading heavy logs like access logs and debug output to a dedicated logging VPS (or to object storage via a logging stack) is often cheaper than constantly upgrading your main VPS disk.<\/p>\n<h3><span id=\"3_Separate_critical_data_and_logs_on_different_partitions_or_servers\">3. Separate critical data and logs on different partitions or servers<\/span><\/h3>\n<p>On higher-end setups, it is common to:<\/p>\n<ul>\n<li>Keep <code>\/var\/lib\/mysql<\/code> or other databases on their own fast disk or partition.<\/li>\n<li>Place <code>\/var\/log<\/code> on a separate partition so a logging explosion cannot easily break the root filesystem.<\/li>\n<li>Run dedicated database and application servers instead of everything on a single VPS.<\/li>\n<\/ul>\n<p>If you are unsure when to separate database and application servers, you might find our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/veritabani-sunucusunu-uygulama-sunucusundan-ayirmak-ne-zaman-mantikli\/\">when it makes sense to split database and application servers<\/a> very helpful.<\/p>\n<h3><span id=\"4_Align_log_rotation_with_compliance_and_forensics\">4. Align log rotation with compliance and forensics<\/span><\/h3>\n<p>It is tempting to set aggressive logrotate limits like <code>rotate 3<\/code> and small sizes, but you may need logs for:<\/p>\n<ul>\n<li>Security investigations (intrusions, fraud, abuse)<\/li>\n<li>Compliance checks (PCI DSS, KVKK\/GDPR, local regulations)<\/li>\n<li>Debugging rare production issues<\/li>\n<\/ul>\n<p>For ecommerce, for instance, <a href=\"https:\/\/www.dchost.com\/blog\/en\/pci-dss-uyumlu-e-ticaret-hosting-rehberi\/\">our PCI-DSS compliant ecommerce hosting guide<\/a> explains how to treat logs as security artefacts, not just noise. The usual pattern is:<\/p>\n<ul>\n<li>Keep a shorter window (for example 7\u201330 days) on the VPS for quick debugging.<\/li>\n<li>Ship compressed logs to a central, access-controlled location with longer retention.<\/li>\n<\/ul>\n<h3><span id=\"5_Plan_for_growth_and_right-size_your_VPS\">5. Plan for growth and right-size your VPS<\/span><\/h3>\n<p>Even with perfect logrotate, no VPS disk is infinite. If your traffic or data grows, you will eventually need more space, better IOPS (NVMe) or a different architecture. When you are a dchost.com customer, our team can help you decide when to:<\/p>\n<ul>\n<li>Increase VPS disk size or move to NVMe-based plans<\/li>\n<li>Upgrade to a <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a> for heavy databases or analytics workloads<\/li>\n<li>Place your own hardware in our data center with colocation and attach larger storage<\/li>\n<\/ul>\n<p>We also keep a practical guide to <a href=\"https:\/\/www.dchost.com\/blog\/en\/nvme-vps-hosting-rehberi-hizin-nereden-geldigini-nasil-olculdugunu-ve-gercek-sonuclari-beraber-gorelim\/\">NVMe VPS hosting and real-world performance<\/a> if you want to understand when faster disks really make a difference.<\/p>\n<h2><span id=\"Step-by-Step_Checklist_to_Prevent_8220No_Space_Left_on_Device8221_on_Your_VPS\">Step-by-Step Checklist to Prevent &#8220;No Space Left on Device&#8221; on Your VPS<\/span><\/h2>\n<p>To turn all this into concrete action, here is a concise checklist you can apply to any Linux VPS.<\/p>\n<h3><span id=\"One-time_baseline\">One-time baseline<\/span><\/h3>\n<ol>\n<li><strong>Inventory your filesystems:<\/strong> run <code>df -h<\/code> and note all mount points and their sizes.<\/li>\n<li><strong>Map current usage:<\/strong> use <code>du -xh --max-depth=2<\/code> under <code>\/<\/code>, <code>\/var<\/code>, <code>\/home<\/code>, and <code>\/var\/lib<\/code> to find heavy directories.<\/li>\n<li><strong>Review existing logrotate configs:<\/strong> inspect <code>\/etc\/logrotate.conf<\/code> and <code>\/etc\/logrotate.d\/*<\/code>. Ensure all major logs (web, PHP, database, mail, app) are covered.<\/li>\n<li><strong>Set journald limits:<\/strong> configure <code>SystemMaxUse<\/code>, <code>SystemMaxFileSize<\/code> and <code>MaxRetentionSec<\/code> in <code>\/etc\/systemd\/journald.conf<\/code>.<\/li>\n<li><strong>Document retention needs:<\/strong> decide how long you need logs for operations vs. compliance, and whether you will use centralised logging.<\/li>\n<\/ol>\n<h3><span id=\"logrotate_hardening\">logrotate hardening<\/span><\/h3>\n<ol>\n<li><strong>Add size-based limits<\/strong> (for example <code>size 50M<\/code> or <code>size 100M<\/code>) to busy logs.<\/li>\n<li><strong>Set reasonable rotate counts<\/strong> (for example 7\u201330) based on how often you rotate and how long you keep on the VPS.<\/li>\n<li><strong>Enable compression<\/strong> for older logs and <code>delaycompress<\/code> where your tools expect a plain-text recent file.<\/li>\n<li><strong>Use create\/copytruncate correctly:<\/strong> use <code>create<\/code> with proper permissions for system daemons, <code>copytruncate<\/code> for stubborn app logs.<\/li>\n<li><strong>Test changes<\/strong> with <code>logrotate -d<\/code> (dry-run) and then <code>logrotate -f<\/code> for one-off verification.<\/li>\n<\/ol>\n<h3><span id=\"Ongoing_maintenance\">Ongoing maintenance<\/span><\/h3>\n<ol>\n<li><strong>Monitor disk and inode usage:<\/strong> add alerts for &gt;80\u201390% usage.<\/li>\n<li><strong>Regularly inspect heavy directories:<\/strong> monthly reviews of <code>\/var\/log<\/code>, <code>\/var\/tmp<\/code>, application cache and backup locations.<\/li>\n<li><strong>Keep backup storage separate:<\/strong> avoid stacking many full-site backups on the same disk as your live app.<\/li>\n<li><strong>Review logs for anomalies:<\/strong> sudden growth often indicates bugs or attacks that also deserve security attention.<\/li>\n<\/ol>\n<h2><span id=\"Conclusion_Keep_VPS_Disk_Usage_Predictable_and_Boring\">Conclusion: Keep VPS Disk Usage Predictable and Boring<\/span><\/h2>\n<p>&#8220;No space left on device&#8221; is one of those errors that should only happen once on any VPS. After the first incident, you know where to look and what to fix: oversized logs, unbounded systemd journals, forgotten backups and chatty applications. With a clear view of <strong>VPS disk usage<\/strong>, carefully tuned <strong>logrotate<\/strong> rules and a few journald limits, disk space becomes predictable instead of a surprise.<\/p>\n<p>At dchost.com, we design our VPS, dedicated server and colocation environments with these practices in mind. When you host with us, our team can help you review your logging setup, tune logrotate for your specific stack (WordPress, Laravel, Node.js, ecommerce platforms and more), and implement monitoring so you see disk issues long before they affect users. If you are planning a new project or migrating an existing one, this is also a great moment to revisit your backup and logging strategy in parallel with your hosting choice.<\/p>\n<p>If you want a calm, no-drama VPS experience, start by applying the checklist above on your current server. And if you prefer to do this together, reach out to our support team at dchost.com \u2013 we are happy to help you keep your disks clean, your logs useful and your applications far away from &#8220;No space left on device&#8221; errors.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>On a busy VPS, disk space rarely disappears because of a single huge file. Most of the time, it is a slow and silent growth: web server access logs, PHP error logs, database logs, mail logs, application logs, temporary files and forgotten backups. One day a deploy fails, MySQL cannot write to its tables, or [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3410,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-3409","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3409","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=3409"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3409\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/3410"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=3409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=3409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=3409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}