How would you set snapshot retention for lakehouse tables across audit, rollback and cost?
answer
- start from how long a mistake goes unnoticed
- the window you keep is the window you can undo
- history is free to make, not to keep
- compaction plus long retention is the expensive pair
- one number for every table is wrong somewhere
basics
~20 sDerive retention from how long a bad write takes to detect, then check it against storage cost, the longest running query, and any deletion deadline. Tier it per table rather than setting one platform-wide number, and pin the few versions that must stay reproducible.
solid answer
~60 sRetention is a **recovery objective**, not a tidiness setting, so start from the detection window: how long until a bad write is noticed — a failed quality check in minutes, a Monday dashboard, a monthly close — plus slack. That is the floor. Then test it against four ceilings. **Cost**: files pinned by history are files you pay for, and long retention combined with nightly compaction is the combination that quietly multiplies a table's footprint. **Metadata volume**: a table committing every minute accumulates versions far faster than a daily batch table, so the same number of days means very different things. **Longest reader**: expiry must not delete files under a running query. **Deletion deadlines**: a row erased for compliance survives in every unexpired snapshot that references its file, so retention is a floor on that SLA. The output is a small set of tiers — short for raw streaming ingest, medium for curated tables, long only where audit demands it — plus named exceptions for versions that must stay reproducible, and monitoring on storage, file counts and version counts so the policy is checked against reality rather than assumed.
code
text · 11 linestier retention also bounded by rationale
------------ ---------- ------------------- ----------------------------------
raw ingest 2 days max N versions replayable from source, 1440 commits/day
curated 14 days - covers weekend + Monday detection
serving 30 days - published outputs must be reproducible
regulated per audit pinned versions cost accepted; check erasure deadline
separate knobs (do not conflate):
retention window how far back you can travel
maintenance schedule how often expiry + compaction run
orphan age threshold > longest in-flight write, alwaysgo deeper
Know that retention is a configured window and that it decides how far back time travel and rollback can reach.
Explain the cost side: files stay alive while any unexpired version references them, so update-heavy and frequently compacted tables pay far more for the same number of days.
Derive the number from detection time and defend it against the ceilings — storage, version count, longest reader, deletion deadlines — and separate retention from maintenance frequency and the orphan threshold.
Own it as a platform policy with tiers, named exceptions for reproducible versions, monitoring on oldest-available-version, and a rehearsed rollback runbook; be ready to argue the audit-versus-erasure tension explicitly.
## Frame it as an objective, not a number The weak answer is "seven days, it's the default." The strong answer starts by naming what retention buys — the ability to return to, reproduce, or audit a past table state — and what it costs — storage for every file that only history still references, plus metadata for every retained version. Then it derives the number from requirements on both sides. ## The floor: detection time How long does a bad write take to notice? Three honest patterns: - A pipeline with data-quality gates that fail the run: minutes to hours. - A table watched only through a dashboard someone opens on weekday mornings: up to a long weekend. - A table reconciled at month end: weeks. Retention must exceed the realistic detection time with margin, because recovery *after* the horizon means reconstruction from sources, not rollback. This is the single most useful sentence in the whole answer: **the retention window is the rollback window**. ## The four ceilings **Storage cost.** Files stay alive while any unexpired snapshot references them. Update-heavy and compacted tables are the expensive cases: a nightly compaction rewrites live data every night, and every rewritten predecessor is pinned until the snapshot that references it expires. Thirty-day retention on such a table can hold many multiples of its live size. Estimate it per table rather than assuming history is nearly free — it is nearly free only for append-only tables that are never rewritten. **Version and metadata volume.** A streaming job committing every minute produces on the order of a thousand-plus versions a day. Retention expressed only in days ignores this; healthy policies bound both **age** and **count**, because metadata growth degrades planning long before storage becomes alarming. **Longest-running reader.** Expiry that deletes files under a scan pinned to an expiring snapshot kills the query. Retention comfortably longer than your slowest query, plus scheduling maintenance away from heavy read windows, prevents an entirely self-inflicted incident class. **Deletion deadlines.** Deleting a row does not remove it from files that unexpired snapshots still reference. If you have committed to erasing personal data within a fixed period, retention on the affected tables must be shorter than that period, or the policy must include a forced expiry step for those tables. This is the constraint people most often discover late, and it cuts directly against the audit argument for long history. ## Tier, don't standardise One number across a platform is always wrong somewhere. A workable set of tiers: - **Raw / streaming ingest**: short — a day or a few days. Replayable from the source, high commit rate, expensive to keep. Bound by version count as well as age. - **Curated / derived tables**: medium — long enough to cover the detection window for the pipelines feeding them, typically one to two weeks. - **Serving tables with published, reproducible outputs**: longer, and paired with pinned versions rather than blanket retention. - **Regulated tables**: driven by the audit requirement, with the storage cost accepted explicitly and the deletion deadline reconciled against it. ## Exceptions instead of blanket extensions When one version must stay reproducible — a model's training set, a filed report — protect *that version* where the format supports pinning or naming snapshots so expiry skips it, or copy the state into a separate table. Extending table-wide retention to preserve one point also pins every intermediate version's files, which is the expensive way to buy one thing. ## Operationalising it Retention is one of three separate knobs, and conflating them causes incidents: **retention** (how far back you can travel), **maintenance frequency** (how often expiry and compaction run), and the **orphan-file age threshold** (safety margin, which must exceed the longest in-flight write). Set them independently, apply them as table properties owned by the platform rather than by whoever wrote the pipeline, and monitor the outcome: total storage versus live data, file counts, retained version counts, and oldest available version per table. Alert when the oldest available version drifts inside a stated recovery objective — that is the signal that a schedule change has silently shortened someone's rollback window. ## Rehearse the recovery A retention policy justified by rollback should be tested by an actual rollback drill on a real table. Teams routinely discover that the version they would return to predates a schema change, or that the downstream consumers need re-running too. Retention only buys the *option* to recover; the runbook is what turns it into a recovery.
- Two tables have the same retention in days but wildly different costs. Why?Because cost follows rewrites, not time. An append-only table's history pins only files that are still current anyway, so it is nearly free. A table that is updated and compacted nightly pins every superseded and pre-compaction file for the whole window, so its footprint can be several multiples of live data. Retention should be set per rewrite profile, not uniformly.
- How does a compliance deletion deadline interact with a long retention policy?It caps it. A deleted row still lives in the files that unexpired snapshots reference, so it remains readable through time travel until those snapshots expire. If you have promised erasure within a fixed period, retention on those tables must be shorter than it, or the policy needs a forced expiry step after such deletes. Long audit history and short erasure deadlines are in direct tension.
- A streaming table commits every minute. What does that change about the policy?Bound versions as well as days. A week of minute-level commits is roughly ten thousand versions, and metadata growth hurts query planning long before storage becomes the headline cost. Pair a short age-based retention with regular compaction, and treat the raw table as replayable from the source rather than as the thing you roll back.
- How do you know the policy is actually holding?Monitor the outcome rather than the config: total storage against live data per table, file and retained-version counts, and the oldest available version. Alert when the oldest available version drifts inside a stated recovery objective, since that means a schedule or config change has quietly shortened someone's rollback window. Then rehearse a rollback on a real table.
saying these in an interview costs you the question
- Sets one retention value for every table on the platform
- Treats retained history as effectively free storage
- Ignores that expiry can delete files under a long-running query
- Forgets that deleted rows survive in unexpired snapshots
- Extends table-wide retention to preserve one auditable version