> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lancedb.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Garbage Collection

> Pruning old versions and the files only they referenced.

**Applies to:** Embedded ✅, Enterprise ✅

Every write keeps the version before it, which is what makes
[time travel](https://docs.lancedb.com/management/table.md#versioning) possible. Cleanup is what ends
that: pruning versions older than a retention window, and the files that only
those versions referenced.

> [!NOTE]
>
> **Enterprise job type:** `cleanup`. Distinct from `compact`: compaction
> merges files, cleanup removes them. `optimize()` in LanceDB Embedded runs both in one call;
> Enterprise schedules them as separate jobs, and runs cleanup only when the
> deployment's configuration enables it.

## Retention

```python Python icon="python" theme={"theme":{"light":"vitesse-light","dark":"catppuccin-mocha"}}
from datetime import timedelta

table.optimize(cleanup_older_than=timedelta(days=30))
```

`cleanup_older_than` defaults to **7 days**. Versions older than that are
removed, along with the files only they referenced. In LanceDB Enterprise, the
retention period comes from its configuration instead.

The latest version is never removed, whatever you pass. `timedelta(0)` makes
every older version eligible for removal, but cleanup still keeps tagged
versions, as the warning below describes.

> [!WARNING]
>
> Pruning is what makes [time travel](https://docs.lancedb.com/management/table.md#versioning) finite: an
> eligible version outside the retention window is gone. Cleanup keeps a version,
> whatever its age, when it is:
>
> * the **latest** version;
> * a **tagged** version.
>
> To keep a version recoverable, tag it, subject to the policy below, or keep
> the window wide enough to cover it.
>
> Under the default policy, a tag can also stop cleanup. When a tagged version is
> older than the window and is not the latest, cleanup refuses to run: it raises
> an error naming the tag and prunes nothing. To let it proceed, move the tag to a
> version inside the window, delete the tag, or widen the window.
>
> A tag on the latest version does not stop cleanup. But `optimize()` compacts
> before it prunes, and compacting commits a new version whenever it merges
> files, so a tag on what was the latest version can become an older one by the
> time cleanup runs. `optimize()` then raises after compacting, and its index
> update does not run.
>
> Enterprise background cleanup keeps tagged snapshots while pruning unrelated
> expired versions. If you rely on reading untagged old versions, set the window
> to cover the range you
> need before running this, not after.

## Managed blob objects

[Managed blobs](https://docs.lancedb.com/management/table.md#managed-blobs) store out-of-line payloads
under the table's `_blobs/` directory. Cleanup follows the references from
retained snapshots, including protected tags, before selecting
objects for deletion. Replacing a blob or deleting a row makes its old payload
eligible only after no retained snapshot references it.

Cleanup removes whole objects. If a packed object contains several blobs, it
remains while any of them is live. Compaction preserves Managed payload objects
rather than copying their bytes, so compaction alone does not reclaim the
unused portion of a packed object.

Use table maintenance to remove Managed objects; deleting `_blobs/` files
directly can corrupt current or historical snapshots. Upgrade all clients and
maintenance workers to a version that understands Managed blobs before using
them, and reopen handles created before that upgrade.

For LanceDB Embedded tables, `optimize()` performs compaction and cleanup.
Enterprise runs these as background jobs; Python tables connected to Enterprise
do not support `optimize()`.
See [Intelligent Auto-Maintenance](https://docs.lancedb.com/enterprise/intelligent-auto-maintenance.md#cleanup) for the Enterprise path.

## Disk usage does not drop immediately

Compaction writes new, merged files before the old ones are removed, so disk
usage can rise before it falls. Space is reclaimed only when cleanup prunes the
versions that referenced the superseded files.

If you need to reclaim space aggressively in the embedded library, shorten the
retention window rather than waiting for the default:

```python Python icon="python" theme={"theme":{"light":"vitesse-light","dark":"catppuccin-mocha"}}
table.optimize(cleanup_older_than=timedelta(days=1))
```

## Files from failed transactions

A write that fails partway can leave files that look like an operation still
in progress. Cleanup will not remove them until they are at least seven days
old, because it cannot tell them apart from a live write.

```python Python icon="python" theme={"theme":{"light":"vitesse-light","dark":"catppuccin-mocha"}}
table.optimize(delete_unverified=True)
```

This option belongs to `optimize()` in the embedded library. A deployment's
cleanup jobs never set it.

> [!WARNING]
>
> `delete_unverified=True` removes them regardless of age. Only set it when you
> can guarantee **no other process is writing to the table**. Otherwise it can
> delete files belonging to a write that is genuinely in progress, and corrupt
> the table.

## What to read next

> [card] [Compaction](https://docs.lancedb.com/maintenance/compaction.md)
>
> Merging small files, the other half of `optimize()`.

> [card] [Intelligent Auto-Maintenance](https://docs.lancedb.com/enterprise/intelligent-auto-maintenance.md#cleanup)
>
> How Enterprise decides to run cleanup without a call from you.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.