Most systems accumulate. Old accounts, abandoned submissions, years of logs, exports nobody remembers making. Each is a record that can be breached, disclosed, or found by someone who should not see it — and none of it is doing any work.
Decide per data type
There is no single correct period. Financial records often have statutory minimums. Case files may need to persist while a matter is live and for a period afterwards. Access logs are useful for months, rarely for years. Marketing data usually has the shortest justified life. Write down each category, its period, and the reason — the reason is what you will need if anyone asks.
Automate it
Retention that depends on someone remembering does not happen. Build a scheduled job that deletes or anonymises past the retention period, log what it removed, and alert if it stops running. Test it against a copy first, because a deletion bug is not recoverable.
Do not forget the copies
- Backups contain deleted data until they rotate out — state the backup retention alongside the primary one.
- Logs and analytics often hold identifiers long after the record was removed.
- Exports, spreadsheets and support tickets accumulate copies outside the database.
- Third-party processors hold their own copies with their own periods.
Anonymise where you cannot delete
Where aggregate history has value, remove the identifying fields rather than the row. Do it properly: stripping a name while keeping an email, address and full timestamp is not anonymisation.
Say what you do
Your privacy notice should state what you keep and for how long, and it must match reality. A policy describing deletion that never happens is worse than saying nothing, because it is a documented false statement. If the practice changes, the notice changes with it.