Skip to content
Good engineers know 4 min read · Delta 2 practice problems ↓

VACUUM and retention

Delete old data files safely without breaking running readers or time travel.

You will learn

  • What VACUUM deletes and what it keeps
  • Why the retention threshold protects readers and time travel
  • How to run it safely, with DRY RUN
  • The Iceberg equivalents: expire snapshots and remove orphan files

Read first

Comfortable with these? Read on.

TL;DR Deleted and rewritten data files stay on storage after a commit, so old versions and running queries keep working. VACUUM permanently deletes files that are no longer referenced by the current table and are older than the retention threshold (7 days by default).

Why old files pile up

Every UPDATE, DELETE, MERGE and OPTIMIZE removes files from the table by writing remove actions, but the files themselves stay on storage. That is what makes time travel and snapshot isolation work. Without cleanup, storage grows forever: a table that is compacted daily can easily hold several times its live size in old files.

What VACUUM deletes

  • Files that are not referenced by the current version of the table, and
  • were removed (or written by failed jobs) longer ago than the retention threshold: delta.deletedFileRetentionDuration, 7 days by default.
  • It never deletes files the current version uses, and it does not touch the transaction log; log cleanup happens separately at checkpoints.
PySparkSpark SQL
from delta.tables import DeltaTable

DeltaTable.forName(spark, "events").vacuum()        # default retention
DeltaTable.forName(spark, "events").vacuum(240)     # keep 240 hours (10 days)
VACUUM events DRY RUN;           -- list what would be deleted
VACUUM events;                   -- default 7 days
VACUUM events RETAIN 240 HOURS;  -- 10 days

Why the threshold matters

09:00 · long query starts

A report starts reading version 50 of the table, which includes file A.

09:20 · OPTIMIZE

Compaction rewrites file A into file B and commits version 51. File A is removed from the table but still on storage. The report keeps reading version 50, fine.

09:25 · VACUUM RETAIN 0

An aggressive VACUUM deletes file A immediately, because version 51 does not reference it.

09:30 · failure

The report reaches file A and fails with a file-not-found error. Streaming readers behind the latest version can fail the same way, and time travel to version 50 is gone.

Delta refuses retention below the default unless you disable spark.databricks.delta.retentionDurationCheck.enabled. Keep the threshold longer than your longest running query, your slowest streaming consumer, and the time travel window you promise users.

In Iceberg

Spark SQL
-- Remove old snapshots and the files only they reference
CALL catalog.system.expire_snapshots(
  table => 'db.events', older_than => TIMESTAMP '2025-03-01 00:00:00', retain_last => 10);

-- Remove files no metadata references at all (failed writes)
CALL catalog.system.remove_orphan_files(table => 'db.events');

Iceberg splits the job in two: expiring snapshots deletes files that only expired snapshots used; removing orphan files cleans up files no snapshot ever committed. Orphan removal defaults to files older than 3 days, for the same reason as Delta's threshold: an in-progress write's files look like orphans until it commits.

Running it in production

  • Schedule it (daily or weekly), after compaction jobs.
  • Run DRY RUN the first time and after changing retention.
  • VACUUM must list the table's files, which can be slow on huge tables; newer Delta versions offer a lighter mode that uses the log instead of a full listing.
  • Coordinate with compliance: deleting a person's rows with DELETE does not remove the data from storage until VACUUM runs after retention.

Common mistakes

VACUUM RETAIN 0 HOURS

Breaks running queries, streams and time travel.

Never vacuuming

Storage grows with every rewrite.

Assuming DELETE removes data physically

For GDPR erasure, the old files must also be vacuumed.

Key takeaways

  • Removed files stay on storage until VACUUM, enabling time travel and snapshot reads.
  • VACUUM deletes unreferenced files older than the retention threshold (7 days).
  • Never set retention shorter than your longest reader or time-travel needs.
  • Iceberg uses expire_snapshots and remove_orphan_files.

Check yourself

3 questions

1. Which files can VACUUM delete?

Show the answer

Files not referenced by the current version and removed longer ago than the retention. Both conditions must hold.

2. Why can VACUUM RETAIN 0 HOURS break a running query?

Show the answer

It deletes files that an older snapshot the query is reading still needs. Running queries read a fixed version whose files may have just been removed from the current one.

3. Iceberg equivalent for deleting files used only by old versions?

Show the answer

expire_snapshots. Expiring snapshots deletes files that only those snapshots referenced.

Practice it

Interview problems that use this: write the PySpark, run it, and get graded on hidden tests.

Solve: Files VACUUM Can Delete →

Go deeper

Primary sources: Delta: VACUUM · Iceberg: maintenance