Technology

VPS Disk-Full Errors: logrotate and Journal Settings

On a busy VPS, disk space can be consumed by a single huge file or by gradual growth across 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 “No space left on device” error. Monitoring VPS disk usage and tuning logrotate can help prevent log-related disk exhaustion. Retention settings must also account for diagnostic needs and any applicable compliance requirements.

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 logrotate actually works, and which settings to consider for a web VPS. We will finish with a practical checklist to reduce the risk of “No space left on device” errors reaching your applications.

The command examples target GNU/Linux; logrotate directives were checked against upstream 3.22.0 documentation. Check your installed version and distribution documentation before adapting paths, users, service units or hooks. Database examples below are explicitly scoped to MySQL 8.4; MariaDB needs its own matching package instructions.

How Disk Usage Really Works on a VPS

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.

Check overall disk usage with df

Identify the filesystem containing the application’s actual write path. The output below is illustrative, not a measurement from a customer server:

df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G   35G  3.8G  91% /
tmpfs           399M     0  399M   0% /run/user/0

Key points:

  • Free space and growth rate matter: 80% warning and 90% critical are example thresholds, not universal safety boundaries. Allow time and working space for intervention.
  • On some systems /var, /home, /tmp or /var/lib/mysql are separate mounts. A tmpfs has its own limit, so free space on root does not settle the diagnosis.
  • If the relevant filesystem appears to have free blocks and inodes, inspect quotas, the application’s mount/container view and storage-layer limits; do not assume every write failure has the same cause.

Do not forget inodes

Even with free GBs, you can hit “No space left on device” because you ran out of inodes (the metadata entries that track files). Check with:

The inode output below is also illustrative. Filesystems report inode capacity differently; use the values reported for the affected filesystem.

df -i
Filesystem      Inodes  IUsed   IFree IUse% Mounted on
/dev/vda1      2621440 120000 2501440    5% /

If IUse% hits 100%, the filesystem has exhausted its available inodes, often because of many small cache or session files. Identify the source and use application-supported cleanup for expired or disposable files; do not delete active sessions or required data indiscriminately.

Find which directories are heavy with du

Once you know which filesystem is full, use du to drill down:

These GNU du scans are read-only but can create substantial I/O on large trees. Keep permission and read errors visible, start with the affected mount, and narrow the scope where possible.

cd /
sudo du -xh --max-depth=1 | sort -h

This shows usage for directories one level below the current directory, such as /var and /home when starting at root. The -x option excludes other filesystems, so start at the affected mount point if it is not root. Descend into a large directory to inspect children such as /var/log and /var/lib:

cd /var
sudo du -xh --max-depth=1 | sort -h

df reports filesystem accounting while du walks reachable files; their totals need not match. Filesystem metadata, snapshots/shared extents and deleted-but-open files can account for differences. For inode-heavy directories, GNU sudo du --inodes -x --max-depth=1 /var is another diagnostic; replace /var with the affected mount.

Directories worth checking on a web VPS include:

  • /var/log – web, PHP, database, mail and system logs
  • /var/lib/mysql or /var/lib/postgresql – database data and transaction logs
  • /home/USER or /var/www – file uploads, backups, caches
  • /tmp or /var/tmp – session files, temporary uploads, uncleaned application temp files

Common Causes of “No Space Left on Device” on a VPS

Use the following list to investigate likely sources of disk or inode exhaustion.

1. Log files that never rotate

Logs can consume substantial space if they accumulate without retention controls. Even a medium-traffic site can generate:

  • Gigabytes of web server access logs (access.log)
  • PHP or application error logs when a bug spams the same stack trace
  • Mail server logs (maillog, exim, postfix logs)
  • Database error logs and slow query logs

If logrotate is misconfigured, or custom log files have no effective rotation or retention policy, a single file can reach tens of GB and fill the filesystem. Check the main configuration and any included files, commonly under /etc/logrotate.d/.

2. Application caches and session files

Frameworks and CMSs (WordPress, Laravel, Magento, custom apps) often store cache and sessions in:

  • /var/www/example.com/storage/framework/cache (Laravel)
  • /var/lib/php/sessions (PHP sessions)
  • /tmp (generic temp files)

If you never purge these, millions of small files can accumulate. You might hit an inode limit before filling the disk in GB terms. Our separate article on Linux file permissions on shared hosting and VPS is also helpful here, because incorrect permissions sometimes prevent automated cleanups from running.

3. Backups and dumps stored on the same disk

A common pattern is a nightly mysqldump or tar of the full site stored in /home or /root without automatic pruning. Without pruning, backups can eventually consume the remaining free space. For a deeper dive into realistic backup planning, look at our guide on how to design a backup strategy with RPO/RTO in mind.

4. Deleted but still-open log files

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 “No space left on device”.

Find such files with:

sudo lsof | grep deleted

sudo lsof +L1 selects open files with a link count below one, rather than relying on a text match for “deleted”. Identify the filesystem, process and file type before acting; a listed file is not automatically safe to discard.

If you see large (deleted) files referenced by nginx, php-fpm, httpd or another daemon, you need the process to close its handle before that space can be reclaimed. Use the service’s documented log-reopen procedure where supported, or arrange a controlled restart of the affected service.

Deleted-but-open space still counts as used in df; it does not explain every case where that same filesystem reports enough free space. Preserve any required evidence before closing the remaining handle, then recheck both usage and service health.

5. Excessive systemd journal usage

On systems using systemd-journald, persistent journal logs may occupy /var/log/journal; volatile logs use /run/log/journal. Check actual usage and effective retention limits rather than assuming the journal is unlimited. Noisy systems may need tighter limits to fit their disk budget. We will cover journal limits in a later section.

Journald can coexist with a syslog daemon, so the same event may consume space in both a journal and a text log. Do not apply logrotate or truncate to journal files. Docker-managed json-file logs likewise need Docker’s own driver limits rather than external manipulation; changes to default logging options do not automatically update existing containers.

Emergency Steps When the Disk Is Already Full

If your VPS is already returning “No space left on device”, you need a calm, step-by-step approach so you do not break databases or the OS while freeing space.

1. Confirm the situation

df -h

Identify the affected filesystem and its available space. Also check inode usage with df -i, as shown above: free GBs do not rule out inode exhaustion. If only /boot or a small partition is full, the fix is different than when root (/) is full.

2. Locate large directories

Start with the full filesystem’s mount point:

cd /               # or /var, /home, etc.
sudo du -xh --max-depth=2 | sort -h | tail -n 20

This gives you the largest directories. Usually, /var/log or a backup directory stands out.

A large file is not proof that it can be removed. Determine its owner, purpose, retention requirement and whether an application still uses it. Preserve required evidence and recovery points on verified storage outside the full filesystem before any deletion or truncation.

3. Assess emergency text-log cleanup

When you identify an oversized plain-text log file (for example /var/log/nginx/access.log), truncation can be an emergency option instead of deletion. It irreversibly discards the existing contents, so preserve any required evidence or retention copy off the full filesystem first. Confirm that the file is a disposable log, not database data, a transaction log or a journal file:

sudo truncate --no-create -s 0 /var/log/nginx/access.log

This preserves file ownership and permissions but not log contents. As an alternative to truncation, consider rotation after freeing enough working space and reviewing the effective rotation configuration:

This is not a database or binary-journal repair command. Confirm that the existing path is the intended regular text log, including any symlink resolution. Prefer the service’s supported rotation/reopen procedure when it can be performed with sufficient space.

  • Rotating them on the spot only if this file has all required settings without relying on main-config defaults: sudo logrotate -f /etc/logrotate.d/nginx
  • Then checking for rotation errors, confirming the service writes to the active log, and verifying that disk usage improved; compressed files may not appear immediately, depending on the configuration

Warning: do not randomly delete directories like /var/lib/mysql, /var/lib/postgresql or /etc just to gain space. You will corrupt services and databases.

4. Remove old local backups that are safe to discard

If you find backup directories like /root/backups/ or archive files like /home/user/backup-YYYYMMDD.tar.gz, decide which are safe to remove under your retention policy. Ensure you have a recent, verified offsite backup, and retain any older recovery points you still need before cleaning. If you are evaluating offsite options, our guide on offsite backups with restic/Borg to S3-compatible storage is a practical next step.

A successful upload alone does not prove that the backup can be restored. Verify integrity, credentials and a representative restore, and keep required historical recovery points. Do not assume rsync or a copy command supplies an independent retention policy.

5. Release deleted files held by services

If lsof | grep deleted, run with sufficient privileges, reveals large deleted log files still referenced by daemons, use a documented log-reopen procedure or restart only the affected service. Restarts may interrupt requests. The commands below are examples, not a requirement to restart both services; confirm the installed unit name, since PHP-FPM units may be version-specific:

sudo systemctl restart nginx
sudo systemctl restart php-fpm

After that, confirm disk usage dropped with df -h. When the system is stable again, you can move on to permanent logrotate and journald tuning.

logrotate Basics: How It Keeps VPS Disk Usage Under Control

logrotate 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.

Where logrotate lives

  • Main config: /etc/logrotate.conf
  • Per-service configs: /etc/logrotate.d/ (for example nginx, apache2, mysql)

logrotate is commonly called by cron or a systemd timer, often daily. The scheduler decides when it runs; logrotate then evaluates the configuration and state. It is not a daemon watching file growth continuously. Check the actual timer/cron schedule, state-file use and error reports before relying on size rules.

Key logrotate directives in plain language

  • daily / weekly / monthly: Time eligibility at a run, not the scheduler’s invocation frequency.
  • size 100M: Rotate when the file is bigger than the threshold at a run. This is mutually exclusive with time criteria; the last specified criterion takes precedence.
  • daily + maxsize 100M: Keep the time condition but allow earlier rotation when the file exceeds the size threshold. This requires sufficiently frequent invocations. minsize instead requires both the size and time conditions.
  • rotate 14: Keep up to 14 rotated copies, not a guaranteed 14 days. Multiple rotations per day shorten the history.
  • compress / delaycompress: Compress old logs, with compression delayed to the next rotation when delaycompress is set. Confirm that no process is still writing the archived file.
  • missingok / notifempty: Ignore a missing log / skip an empty one. A wrong path can therefore go unnoticed.
  • create 0640 www-data adm: Create a new active file after the old one is moved, using these example permissions and ownership. It neither performs reopening nor deletes the old file by itself.
  • copytruncate: Copy the log, then truncate the original in place. Records written between those operations can be lost. create has no effect with this method.
  • su app app: Use an appropriate service user/group for rotation in directories controlled by unprivileged users; these are example names.
  • dateext: Use a date suffix. Choose a sufficiently precise date format for multiple rotations per day; otherwise names can collide.

Dry-run and force logrotate

Back up the configuration and identify the responsible rotation mechanism first; do not add duplicate rules for a package-managed log. Confirm retention requirements and working space before allowing old files to be removed. Inspect the effective main configuration with:

sudo logrotate -d /etc/logrotate.conf

-d prints debug decisions without changing logs or the state file; it does not prove that a service will reopen its log successfully. -f performs real rotation and may run hooks, compress or delete retained files. Only after reviewing those effects, use a single self-contained service configuration for controlled verification; do not force every log on the server as a routine test:

sudo logrotate -f /etc/logrotate.d/nginx

The standalone file must contain all required settings; it does not inherit defaults from a main file that was not loaded. Avoid overlap with a scheduled run or bypassing state-file locks. Afterwards inspect errors, current-log writes, retained files and free space; return to normal scheduling.

Practical logrotate Configurations for a Web VPS

The following examples retain useful service patterns, but require adaptation to the installed package. Verify actual text-log paths, owner/group, permissions, executable and PID paths. Use an existing package rule where available, and keep errors visible. None of these rules continuously enforces a hard file-size cap.

Rotating Nginx logs safely

Inspect the existing /etc/logrotate.d/nginx rule before editing. This example assumes a running Nginx master, a trusted /run/nginx.pid containing that master’s PID, and valid www-data/adm ownership. Check those details and the new log’s writability before sending a signal:

/var/log/nginx/*.log {
    daily
    maxsize 50M
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    create 0640 www-data adm
    postrotate
        kill -USR1 "$(cat /run/nginx.pid)"
    endscript
}

Why these options?

  • daily + maxsize 50M: Daily eligibility with earlier size-triggered rotation at another invocation. A daily timer alone cannot react during the rest of the day.
  • rotate 14: Fourteen copies; count, schedule and growth rate determine the retained period.
  • USR1: Requests Nginx log reopening. Verify the new file receives writes; the signal is not a guarantee that every permission or filesystem operation succeeds.

Rotating Apache logs

For Apache 2.4 writing directly to files, the package may use /etc/logrotate.d/apache2 or httpd. Adapt the paths below and inspect existing rules. If Apache uses piped rotatelogs instead, do not add a second competing rotation mechanism:

/var/log/apache2/*.log {
    daily
    maxsize 100M
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    sharedscripts
    postrotate
        /usr/sbin/apachectl graceful
    endscript
}

A graceful restart requests log reopening while existing requests finish; old workers may keep the former log open for a time. Validate the Apache configuration, preserve the package’s ownership handling and wait for old writers before compressing or disposing of their files. Check the hook result and actual log writes.

Rotating PHP-FPM error logs

PHP-FPM’s main error_log can be a text file or syslog, and its PID-file path is configurable. The following PHP 8.4 example uses the example text path /var/log/php8.4-fpm.log, master PID file /run/php/php8.4-fpm.pid, and root/adm log ownership. Verify all three for the installed server. Use your package’s actual paths and ownership; do not apply one version’s hook to a wildcard covering several FPM instances:

/var/log/php8.4-fpm.log {
    weekly
    maxsize 50M
    rotate 8
    missingok
    notifempty
    compress
    delaycompress
    create 0640 root adm
    postrotate
        kill -USR1 "$(cat /run/php/php8.4-fpm.pid)"
    endscript
}

PHP-FPM documents SIGUSR1 for reopening log files; SIGUSR2 reloads workers and configuration and is a different operation. Confirm the trusted PID file identifies the intended running master. Choose weekly or daily time eligibility and a suitable invocation schedule; pool/application logs may use different paths or logging owners and need separate review.

Rotating application logs (Laravel, custom apps, etc.)

First inspect the framework’s own logging/rotation support. The example below is restricted to one application whose process cannot use a supported reopen method. copytruncate can lose records written between copying and truncation; it is inappropriate when that loss is unacceptable. The app user/group and path are placeholders for verified real values. Allow space for the copy and do not duplicate the framework’s own rotation:

/var/www/app/storage/logs/app.log {
    su app app
    daily
    maxsize 20M
    rotate 10
    missingok
    notifempty
    compress
    delaycompress
    copytruncate
}

copytruncate keeps the original inode and truncates that original file after copying it. The race is not limited to “very high traffic”, and no fixed number of lost lines can be promised. create has no effect here. If loss is unacceptable, use application-supported rotation/reopening or a suitable logging transport, and verify collection continuity.

Rotating MySQL/MariaDB logs

Separate file-based diagnostic logs (error, general query and slow query) from binary logs, redo/undo and PostgreSQL WAL. Never apply this text-log rule or truncate to recovery/replication files. In MySQL 8.4, binary-log expiry is managed with binlog_expire_logs_seconds and server-supported purge operations; older variable names are not interchangeable across MySQL and MariaDB versions. Check all replicas, including disconnected ones, and required point-in-time recovery history before changing expiry.

This example is for MySQL 8.4 writing error and slow logs to the example paths below; verify or replace those paths for the actual server. The protected, administrator-readable /etc/mysql/logrotate-client.cnf must already contain the correct connection settings and an account with the required flush privilege. Verify the client binary and mysql/adm ownership. MariaDB users should adapt their package configuration and mariadb-admin instructions:

/var/log/mysql/error.log /var/log/mysql/mysql-slow.log {
    daily
    maxsize 50M
    rotate 10
    missingok
    notifempty
    compress
    delaycompress
    create 0640 mysql adm
    sharedscripts
    postrotate
        /usr/bin/mysqladmin --defaults-file=/etc/mysql/logrotate-client.cnf flush-logs error slow
    endscript
}

After renaming, a successful flush closes and reopens the selected logs; the new files need appropriate ownership and writable paths. The unqualified flush-logs also flushes other logs, including the binary log. The selected types above restrict that scope. Do not put passwords in command lines, and inspect authentication, flush and new-write results before accepting the rotation.

On heavily loaded ecommerce databases, you may also want to tune MySQL itself for fewer slow queries and less noisy logs. Our checklist on MySQL/InnoDB tuning for WooCommerce provides a practical roadmap.

Controlling systemd Journal Size (journald)

Journald already has size controls; inspect effective settings rather than assuming an unlimited default. Storage=persistent prefers /var/log/journal and can fall back to /run/log/journal during early boot or when disk is not writable. volatile uses /run/log/journal; auto selects persistent storage if /var/log/journal exists. none disables storage but can still forward records. The default may depend on the build and distribution.

Upstream documentation gives default MaxUse and KeepFree values of 10% and 15% of the corresponding filesystem, each calculated default capped at 4G. The more restrictive limit applies. These are not guarantees that other applications cannot fill the disk, and persistent and runtime journals have separate settings.

Set journald limits

Read the main configuration first. A local drop-in such as /etc/systemd/journald.conf.d/60-disk-budget.conf can hold overrides under [Journal]. The example below applies to persistent storage in the default namespace; choose values from capacity and required history. Use RuntimeMaxUse, RuntimeKeepFree and RuntimeMaxFileSize for /run storage instead:

[Journal]
SystemMaxUse=1G
SystemKeepFree=1G
SystemMaxFileSize=200M
MaxRetentionSec=1month

Explanation:

  • SystemMaxUse=1G: A persistent-journal space budget, not a promise that all active and archived files immediately total less than 1G.
  • SystemKeepFree=1G: A free-space constraint used together with MaxUse. It does not reserve space against other applications or retroactively recover arbitrary data.
  • SystemMaxFileSize=200M: Controls individual-file growth and rotation granularity, affecting how much archived data can be removed at once.
  • MaxRetentionSec=1month: A maximum-age policy, not a minimum month of history. Space limits can remove records sooner. Required long-term history needs separately verified storage.

Review the effect on required history and protect needed records before applying tighter limits. An authorised administrator can apply the configuration with the following restart; for journald, use restart rather than separate stop/start operations so existing service output streams are preserved:

sudo systemctl restart systemd-journald

Check the service result, effective settings and receipt of new log records afterwards. Existing persistent data does not disappear merely because Storage is changed to volatile.

Clean up existing journal logs (with care)

To see journal disk usage:

journalctl --disk-usage

The following are alternative deletion operations, not commands to keep “at least” a volume or age of logs. They irreversibly remove the oldest eligible archived journal files. Before selecting one, preserve required investigation and retention copies outside the affected filesystem and verify those copies:

sudo journalctl --vacuum-size=1G
sudo journalctl --vacuum-time=30d

--disk-usage includes active files, which vacuum does not remove; the total can remain above the size target. Time and size options combined in one invocation enforce both limits, so the size limit can remove history newer than the age threshold. --rotate first archives active files and makes more history eligible for removal; add it only after assessing that wider effect. Vacuum is documented from systemd 218 and rotate from 227; confirm the local version.

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 log retention on hosting and email infrastructure for KVKK/GDPR compliance is a useful reference.

Beyond logrotate: A Long-Term Strategy for VPS Disk Usage

Rotation reduces log-related exhaustion risk; it cannot prevent every no-space error. Monitoring, separate backup storage and a retention policy that matches real recovery needs remain part of disk management.

1. Set up monitoring and alerts

Build alerts from filesystem metrics collected by an appropriate agent, such as node_exporter, and verify notification delivery. Uptime Kuma endpoint checks alone do not supply host disk/inode measurements. Useful conditions include:

  • Per-filesystem available bytes and disk-usage percentage, with example warning/critical alerts when usage exceeds 80%/90%; adjust these thresholds to actual capacity and response time.
  • Inode availability and growth in file count where the filesystem reports meaningful limits.
  • Rapid log growth, failed rotation and a projected time-to-full shorter than the response window.
  • Missing metrics or failed collection; silence does not establish healthy disk usage.

If you want a hands-on example, our guide on VPS monitoring and alerts with Prometheus, Grafana and Uptime Kuma shows how to build a practical monitoring stack that includes disk space dashboards and alarms.

2. Consider centralised logging

Centralised collection can improve searching and protect a separate copy, but forwarding does not automatically remove local logs. Plan local rotation, retention, access controls and bounded buffers for outages, then verify that central ingestion and retrieval work.

We have a step-by-step playbook on centralised VPS log management with Loki that covers retention, indexing and alert rules. Promtail reached end of life on 2 March 2026; select Grafana Alloy or another supported client for current deployments. Compare ingestion, retention and retrieval costs rather than assuming central storage is always cheaper.

3. Separate critical data and logs on different partitions or servers

On higher-end setups, it is common to:

  • Keep /var/lib/mysql or other databases on their own fast disk or partition.
  • Place /var/log on a separate partition so a logging explosion cannot easily break the root filesystem.
  • Run dedicated database and application servers instead of everything on a single VPS.

Separate filesystems isolate capacity consumption only at those boundaries; their own full conditions can still break dependent services. Verify mount persistence, ownership, backup consistency and alarms. A faster disk does not create more free bytes or remove retention duties.

If you are unsure when to separate database and application servers, you might find our article on when it makes sense to split database and application servers very helpful.

4. Align log rotation with compliance and forensics

It is tempting to set aggressive logrotate limits like rotate 3 and small sizes, but you may need logs for:

  • Security investigations (intrusions, fraud, abuse)
  • Compliance checks (PCI DSS, KVKK/GDPR, local regulations)
  • Debugging rare production issues

For ecommerce, for instance, our guide to PCI DSS hosting requirements explains how to treat logs as security artefacts, not just noise. The usual pattern is:

  • Choose a local history window for response needs; a 7–30 day example is not a legal rule or a duration guaranteed by rotate counts.
  • Store required longer history centrally with restricted access, integrity checks and tested retrieval.
  • Verify actual collection completeness before pruning local copies; forwarding failures can leave gaps.

5. Plan for growth and right-size your VPS

If measured data growth exceeds the disk budget, capacity expansion or architecture changes may be needed. Confirm the available expansion paths, product limits and management responsibilities with DCHost or the chosen provider. Options to evaluate include:

  • Additional capacity or a different storage tier, after checking partition/filesystem expansion requirements and backups.
  • A dedicated server where measured workload and operational needs justify it.
  • Separate database, log or backup storage, with explicit recovery, access and cost requirements.

We also keep a practical guide to NVMe VPS hosting and real-world performance if you want to understand when faster disks really make a difference.

Checklist to Reduce VPS Disk-Full Errors

To turn all this into concrete action, here is a concise checklist you can apply to any Linux VPS.

One-time baseline

  1. Inventory filesystems: Use df -h and df -i at the actual write paths; record mounts, free space and inode capacity.
  2. Map usage: Use bounded GNU du scans on the affected mount, then check deleted-open files when df and du differ.
  3. Review logging owners: Identify file logs, journal storage, application rotation and Docker-managed logs; avoid duplicate rules.
  4. Set matching journal budgets: Choose System or Runtime settings for the actual storage mode and namespace.
  5. Document history: Preserve operational evidence, required recovery points and verified central/offsite copies before deleting data.

logrotate hardening

  1. Match conditions to the schedule: Use maxsize with time criteria when intended, and run logrotate often enough for expected growth.
  2. Choose retention deliberately: Rotate counts are copies, not a guaranteed number of days.
  3. Compress after writers finish: delaycompress postpones work but does not repair a failed reopen.
  4. Verify ownership and reopening: Prefer a supported reopen method; use copytruncate only if its loss window is acceptable.
  5. Validate in stages: Inspect with logrotate -d, then perform only a reviewed, scoped real rotation with space and retention prerequisites satisfied.

Ongoing maintenance

  1. Monitor disk and inode usage: choose warning thresholds from capacity, growth and response time; test delivery.
  2. Regularly inspect heavy directories: monthly reviews of /var/log, /var/tmp, application cache and backup locations.
  3. Keep backup storage separate: avoid stacking many full-site backups on the same disk as your live app.
  4. Review logs for anomalies: sudden growth often indicates bugs or attacks that also deserve security attention.

Conclusion: Keep VPS Disk Usage Predictable and Boring

“No space left on device” requires diagnosis at the filesystem and application boundary. Check block space, inode availability, deleted-open files and the actual log/backup owner. Scheduling, supported reopening and verified retention make log growth easier to control; they cannot promise that the error will never recur.

When choosing a DCHost VPS or dedicated server, verify the product’s capacity, expansion, backup and management scope. Keep responsibilities for operating-system configuration, log retention and application maintenance explicit. Hosting choice does not replace a tested disk-monitoring and recovery plan.

Start with the affected filesystem and its largest or most numerous files, preserve what must be retained, and make one controlled change at a time. After each change, verify new writes, available space, service health and alert delivery. Use those results to adjust the ongoing schedule and storage budget.

Primary technical references: logrotate 3.22.0, journald.conf, journalctl, Nginx, MySQL 8.4.

Frequently Asked Questions

Check df -i for inode exhaustion and confirm that df -h describes the filesystem and write path used by the failing application. A separate mount, tmpfs or quota can matter. Deleted-open files can explain why df reports more used space than du, but they still count as used in df; they do not explain every free-space case. Use privileged lsof +L1 to inspect them, preserve required records and use a documented log-reopen procedure or a controlled restart of only the affected service. Recheck space and writes afterwards.

Choose the schedule from log growth and available working space. Time directives do not schedule invocations. Use daily plus maxsize for a time condition with an earlier size trigger; size is mutually exclusive with time criteria and the last criterion takes precedence. Thresholds are checked only when logrotate runs, so logs can exceed them between runs. Rotate counts are copies, not guaranteed days. Verify the scheduler, reopening, compression and required retained history before relying on the rule.

Prefer a supported reopen method: rotation moves the old file and create makes a new active file with the selected ownership. create alone does not tell the service to reopen or delete the old file. copytruncate instead copies the contents and truncates the original inode in place; create has no effect with it. Records written between copying and truncation can be lost at any write rate. Use it only when that loss is acceptable and provide working space for the copy; otherwise choose application-supported rotation or a suitable logging transport.

Inspect Storage and effective settings first. System limits apply to persistent /var/log/journal data and Runtime limits to volatile /run/log/journal data. MaxUse, KeepFree and MaxFileSize work with file rotation; they do not promise an immediate exact total or a minimum retained period. MaxRetentionSec is a maximum-age policy and size limits can remove records earlier. Preserve required history before tightening limits or vacuuming. Vacuum removes archived files, while disk-usage also includes active ones. Validate configuration and new logging after a controlled journald restart.

Plan independent, access-controlled backup storage and allow local working space for backup and restore operations. Verify integrity and representative restores before pruning, and keep required historical recovery points as well as a recent copy. Select a tool that supports the actual backend and implement an explicit retention policy; a generic transfer alone does not create one. Monitor failed backups, available local space and retention results. Offsite copies reduce dependence on one server but do not guarantee recovery without tested credentials, data and procedures.
↑