Understanding and Reclaiming Storage After DELETE in Azure Database for PostgreSQL
PostgreSQL's Multi-Version Concurrency Control (MVCC) allows readers and writers to operate simultaneously without blocking. When rows are deleted, PostgreSQL marks them as dead tuples rather than physically removing them from disk. This ensures data consistency for ongoing transactions, but the table file size remains unchanged. Consequently, Azure Monitor storage graphs will continue to show high consumption despite a reduced logical row count. Old row versions created by updates also occupy space until no active transaction requires them. Dead tuples, which are obsolete row versions, can accumulate and require cleanup through vacuuming operations. Table and index bloat can occur from frequent data modifications. Standard VACUUM reclaims internal space for reuse but does not shrink table files. VACUUM FULL rewrites tables into compact files, physically shrinking them, but requires exclusive locks. pg_repack offers a less blocking alternative for table and index compaction. Partitioning is a proactive approach to manage historical data by removing entire partitions instead of individual rows. Unused space from temporary files is automatically reclaimed after queries complete. Azure Database for PostgreSQL Flexible Server allows storage increases but not reductions. Storage costs are based on provisioned capacity, so deleting data does not automatically lower bills. Best practices include batch deletes, monitoring key metrics, using partitioning, and proactive planning for storage capacity.