Data Retention Framework
Retention policy answers a simple question for every dataset: why do we still have this? The framework turns the answer into enforceable, automated lifecycle rules with an audit trail.
How it works
Each data class has an owner, a purpose, a retention period measured from a defined trigger such as account closure or transaction date, and an end-of-life action. A scheduler evaluates records against policy and applies actions in stages: move to cold storage, pseudonymise or aggregate, then delete. Deletion events propagate to replicas, search indexes, and analytic copies. Legal holds mark records as exempt until released.
Implementation steps
- Build a data inventory covering stores, derived copies, logs, and third-party processors.
- Classify records by sensitivity and purpose, and map each class to legal retention requirements.
- Define periods and triggers, recording the basis for each decision.
- Add the lifecycle metadata to data: creation date, trigger date, class, and hold flag.
- Implement automated jobs using partition dropping or time-to-live features for efficiency, rather than row-by-row deletes where possible.
- Propagate deletions through event streams to downstream systems, and document backup expiry so erased data ages out of backups on a known schedule.
- Log every deletion run, and report coverage and exceptions to the owner.
Common pitfalls
- Deleting from the primary store while copies persist in logs, analytics, and exports.
- Measuring retention from creation when the legal trigger is a later event.
- No legal hold mechanism, forcing manual exceptions.
- Deleting referenced rows and breaking integrity or reporting.
- Treating backups as out of scope.
Metrics to watch
- Share of data classes with an enforced policy.
- Volume of data past its retention date.
- Deletion job success rate and duration.
- Time from erasure request to completion across all stores.
- Active legal holds and their age.
Example configuration
retention:
- class: customer-profile
trigger: account_closed_at
period: 30d
action: delete
propagate: [search, warehouse, cache]
- class: invoice
trigger: issued_at
period: 7y
action: archive
legalBasis: "tax record keeping"
- class: access-log
trigger: created_at
period: 90d
action: delete
legalHold:
respected: true
Practical rollout
Start with the highest-risk and highest-volume datasets rather than attempting a full inventory first. A pilot on one class, such as inactive customer profiles, exposes technical obstacles like missing trigger dates and undeleted copies. Involve legal, security, and engineering in a single review so periods are defensible and implementable. Run new deletion jobs in report-only mode first, and compare the counts with expectations before enabling destructive actions.
Key takeaways
- Tie every dataset to an owner, purpose, and trigger.
- Automate lifecycle actions and prove they ran.
- Include derived copies and backups in scope.
- Build legal holds in from the start.