How to fix Disk full in PostgreSQL

PostgreSQLINTERMEDIATECRITICALUpdated Dec 28, 2025ยท 235 views

PostgreSQL encounters a disk full error when the file system runs out of available space. This prevents writes and can cause database shutdown. Immediate action is needed to free space or expand storage.

Quick fix

Fixes Disk full

df -h
  1. Check current disk usage and locate the problem
  2. Stop external applications and check WAL files
  3. Free up disk space safely
  4. Increase disk space if necessary
postgresql โ€” error
df -h
Disk full

What this error means

A "Disk full" error (ENOSPC - Error No Space) occurs when PostgreSQL attempts to write data but the underlying file system has no available disk space. This can happen during data writes, WAL (Write-Ahead Log) operations, or temporary file creation. PostgreSQL's response depends on where the error occurs: data writes may abort the current transaction and allow read-only access, but WAL errors trigger an immediate PANIC and database shutdown since transaction logging is critical.

Typical symptoms

  • PostgreSQL refuses new write operations or INSERT/UPDATE/DELETE queries fail
  • Error messages mentioning "No space left on device" in logs
  • Database goes into read-only mode or shuts down unexpectedly
  • WAL (pg_wal) directory grows abnormally large
  • Backup operations fail due to insufficient space
  • VACUUM or maintenance operations cannot complete

Common causes

  1. Database data directory has grown beyond available disk space
  2. WAL files are not being archived or cleaned up properly, causing pg_wal directory to fill the disk
  3. Replication slots are holding WAL files from a disconnected standby or subscriber
  4. Large bulk operations generated more WAL than available disk space
  5. Temporary files or indexes bloat the database beyond available storage
  6. Monitoring was not in place, allowing gradual disk consumption to go unnoticed
  7. File system partitions are too small relative to database growth rate

How to fix "Disk full"

1Check current disk usage and locate the problem

Connect to your PostgreSQL server and check which filesystem is full:

bash
df -h

Identify the partition holding the PostgreSQL data directory (typically /var/lib/postgresql or your custom PGDATA). Then check PostgreSQL directory sizes:

bash
du -sh /var/lib/postgresql/[version]/main
du -sh /var/lib/postgresql/[version]/main/pg_wal

If pg_wal is consuming most space, your archiving or replication is likely broken.

2Stop external applications and check WAL files

Halt any ongoing backup or bulk operations that might be generating excessive WAL:

bash
# Check WAL file count
ls -la /var/lib/postgresql/[version]/main/pg_wal/ | wc -l

If you see thousands of WAL files not being cleaned up, your archive_command or replication is failing. Check PostgreSQL logs:

bash
tail -100 /var/log/postgresql/postgresql.log

Look for archive_command errors or replication slot issues.

3Free up disk space safely

Choose appropriate actions based on your situation:

Option A: Remove old transaction logs (if archiving is working):

bash
# On a standby or after verifying archives are safe
rm /var/lib/postgresql/[version]/main/pg_wal/0000*

Option B: Vacuum and reclaim space from deleted rows:

bash
psql -U postgres -d your_database -c "VACUUM ANALYZE;"

For aggressive reclamation (requires 2x current table space):

bash
psql -U postgres -d your_database -c "VACUUM FULL;"

Option C: Drop or truncate unused tables:

bash
psql -U postgres -d your_database -c "DROP TABLE unused_table;"

Option D: Use pg_repack for online reclamation (requires installation):

bash
pg_repack -U postgres -d your_database -k -v
4Increase disk space if necessary

If the database is legitimately large, expand storage:

Cloud environments (AWS, Azure, GCP):
- Stop the PostgreSQL service
- Expand the EBS/managed disk volume through your cloud console
- Expand the filesystem (e.g., sudo resize2fs /dev/xxx for ext4)
- Restart PostgreSQL

On-premises:
- Add a new disk or replace with larger capacity
- Create new partition and extend the filesystem
- Or use tablespaces to move database files to another disk:

bash
# Create tablespace on new disk
sudo mkdir -p /mnt/postgres_data/new_tablespace
sudo chown postgres:postgres /mnt/postgres_data/new_tablespace

psql -U postgres -c "CREATE TABLESPACE new_space LOCATION '/mnt/postgres_data/new_tablespace';";

# Move tables or indexes
psql -U postgres -d your_database -c "ALTER TABLE large_table SET TABLESPACE new_space;";
5Fix archiving and replication issues

Prevent future disk full incidents:

Check archive_command:

sql
SHOW archive_command;

If it's failing, verify the archive destination is accessible and has space:

bash
ls -la /path/to/archive/
df -h /path/to/archive/

Fix replication slots:

sql
-- List slots
SELECT slot_name, restart_lsn FROM pg_replication_slots;

-- Drop abandoned slots
SELECT pg_drop_replication_slot('slot_name');

Set up WAL limits (PostgreSQL 13+):

sql
ALTER SYSTEM SET max_slot_wal_keep_size = '10GB';
SELECT pg_reload_conf();
6Verify recovery and set up monitoring

Confirm everything is working:

bash
psql -U postgres -c "SELECT datname, pg_database_size(datname) FROM pg_database ORDER BY pg_database_size DESC;"

Ensure PostgreSQL is accepting writes:

bash
psql -U postgres -d your_database -c "CREATE TABLE test_write (id int); DROP TABLE test_write;"

Set up proactive monitoring:

sql
-- Create a monitoring view
CREATE VIEW disk_usage AS
SELECT 
  datname,
  pg_size_pretty(pg_database_size(datname)) as size,
  ROUND((pg_database_size(datname)::float / 1099511627776 * 100), 2) as percent_of_tb
FROM pg_database
ORDER BY pg_database_size(datname) DESC;

SELECT * FROM disk_usage;

Enable log shipping or use Prometheus/pganalyze to alert when disk usage exceeds 70% or 80%.

Advanced notes

PostgreSQL's ENOSPC handling varies by context. In smgrextend() (data writes), it aborts only the current transaction, allowing recovery. In smgrwrite() (after commit), it's dangerous because dirty data may be lost. In WAL writes, it causes immediate PANIC and shutdown. For this reason, isolate pg_wal on a separate filesystem with its own quota monitoring. Use max_slot_wal_keep_size (PostgreSQL 13+) to prevent replication slots from consuming all disk. VACUUM FULL requires 2x current table size temporarily. Consider pg_repack for online space reclamation. Some filesystems (ext4, XFS) reserve space optimistically, but can still fail if the OS reports ENOSPC. Always maintain spare capacity and monitor trends, not just absolute usage.

Frequently asked questions

What does "Disk full" mean?
A "Disk full" error (ENOSPC - Error No Space) occurs when PostgreSQL attempts to write data but the underlying file system has no available disk space. This can happen during data writes, WAL (Write-Ahead Log) operations, or temporary file creation. PostgreSQL's response depends on where the error occurs: data writes may abort the current transaction and allow read-only access, but WAL errors trigger an immediate PANIC and database shutdown since transaction logging is critical.
How do I fix "Disk full"?
PostgreSQL encounters a disk full error when the file system runs out of available space. This prevents writes and can cause database shutdown. Immediate action is needed to free space or expand storage.
What causes "Disk full"?
Database data directory has grown beyond available disk space WAL files are not being archived or cleaned up properly, causing pg_wal directory to fill the disk Replication slots are holding WAL files from a disconnected standby or subscriber
Is the "Disk full" error serious?
Yes. This is a critical-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading