Guides / OSError: [Errno 28] No space left on device (Django)

OSError: [Errno 28] No space left on device (Django)

Requests start failing with OSError: [Errno 28] No space left on device, or Postgres reports could not write to file ... No space left on device. The disk is full. In a Django app the culprits are almost always the same few: logs, temporary upload files, sessions or cache written to disk, and old Docker data.

What it means

Something filled the filesystem (or used up its inodes, the file count limit) that Django, Postgres or Python writes to. The first thing to break is usually whatever writes at that moment: a log line, an upload, a session or a migration.

Why it happens

  1. Log files grow forever. Application logs, gunicorn and nginx logs, or Docker's JSON logs without rotation.
  2. Docker data piles up. Old images, stopped containers and build cache from every deploy.
  3. Temporary upload files. Large uploads are spooled to /tmp (FILE_UPLOAD_TEMP_DIR) and are not cleaned up when a request is aborted.
  4. File-based sessions or cache (django.contrib.sessions.backends.file, FileBasedCache) that never expire their files, or a database-backed session table never cleaned.
  5. The database itself: a SQLite file, or Postgres WAL and tables on a small volume.
  6. A small root disk, such as 8 GB on a fresh cloud instance.

The fix

Find what is using the space before deleting anything:

df -h                      # which filesystem is full?
df -i                      # or is it out of inodes?
sudo du -xh / --max-depth=2 2>/dev/null | sort -h | tail -20
docker system df          # if you use Docker

Then clean up the cause:

docker image prune -a --filter "until=168h"   # images unused for a week
docker builder prune
sudo journalctl --vacuum-size=200M
python manage.py clearsessions                # remove expired database sessions

For log files, rotate them (logrotate for nginx and gunicorn files) or stop writing them to disk. In Django, log to the console and let the platform collect the output:

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "handlers": {"console": {"class": "logging.StreamHandler"}},
    "root": {"handlers": ["console"], "level": "INFO"},
}

If you need files, use logging.handlers.RotatingFileHandler with maxBytes and backupCount. For Docker's own logs, set a size cap in /etc/docker/daemon.json:

{"log-driver": "json-file", "log-opts": {"max-size": "10m", "max-file": "3"}}

Making it stick in production

Or skip it

On Django Cloud your app's disk is reset on every deploy, so state belongs in Postgres, and your logs live in the dashboard, searchable and kept for 30 days, and not in files that grow on the server.

pip install djangocloud-cli
djangocloud deploy

Get startedSee pricing

Free plans are available for students, AWS Activate startups, open-source, non-profit and research projects. See how Django Cloud compares with other ways to host Django.

Django is a registered trademark of the Django Software Foundation. Django Cloud is not affiliated with or endorsed by it. Found a mistake in this guide? Tell us and we will fix it.