How do you implement soft deletes and undelete safely?

Soft delete is a pattern where a record is marked as deleted without being physically removed. You keep the data in primary storage but hide it from normal reads and write paths. Undelete is the controlled reversal that restores the record and every dependent artifact such as caches search documents and derived aggregates. This pattern gives you safety observability and compliance without breaking user expectations. In a system design interview you will impress when you show how soft delete and undelete flow through storage indexing caching streaming and authorization.

Why It Matters

Real systems need safety rails. Users change their minds. Customer support needs to recover data quickly. Legal teams need audit trails. Product teams need analytics on churned items. Hard delete removes all of that context immediately. Soft delete keeps the ability to roll back while enforcing privacy policies through scheduled purge. In interviews it shows senior judgment about data lifecycle risk control and scalable architecture choices in distributed systems.

How It Works (Step-by-Step)

1. Model the State Add fields such as deleted_at, deleted_by, and delete_reason. Use a timestamp instead of a boolean since it helps with retention policies and time-based analytics. Treat deletion as a state transition: active → deleted → purged.

2. Apply Filters at the Data Boundary Ensure every read path automatically excludes deleted records. Use database views, ORM-level global filters, or service-layer policies. Add observability counters to track accidental reads of deleted rows.

3. Maintain Uniqueness Correctly Soft deletes can break unique constraints. Use partial indexes that enforce uniqueness only for active rows or include the deleted_at column in composite keys. During undelete, validate that no active record now holds the same unique field.

4. Make Deletes Idempotent and Auditable A delete request should only mark the record and emit an event (tombstone). Repeated requests should be safe and return the same result. Always log who deleted it, when, and why in an audit trail.

5. Propagate Changes to Derived Stores Broadcast tombstone events to dependent systems such as caches, search indexes, or analytics stores. These consumers should invalidate or remove the data consistently and idempotently.

6. Add Retention and Purge Policies Schedule jobs to permanently remove soft-deleted data after a fixed retention window. Track purge latency and reclaimed storage for operational health.

7. Implement Safe Undelete Undelete should:

  • Validate conflicts or constraint violations
  • Clear deletion markers
  • Rebuild caches and search indexes
  • Publish an undelete event Make it idempotent to avoid partial restores if the operation is retried.

8. Test and Monitor Automate checks to ensure deleted data doesn’t leak into user views. Track metrics for delete, undelete, and purge operations. Alert on failures or inconsistencies across systems.

Real World Example

Think about a photo in a social app. When a user taps delete the photo should disappear from feeds search and notifications right away. Internally the media row is marked deleted at now plus user id and reason. The service publishes a tombstone event that removes the item from search and invalidates feed caches. Customer support has thirty days to restore the photo if the user contacts support. If the user restores it from a recently deleted view the system checks whether any unique constraints such as a short link still collide and then clears the marker reindexes the document and repopulates any timeline aggregates. After the retention window a nightly purge job removes the row the media file and any related comments or likes that are no longer needed.

Common Pitfalls or Trade offs

Query leaks Teams forget to filter out deleted rows in new endpoints or ad hoc queries. Solve this with default scopes database views and automated tests that assert the filter.

Uniqueness collisions on restore Undelete fails because another active record now holds the unique value. Use partial indexes and a preflight conflict check that offers a merge or rename workflow.

Orphaned children Deleting a parent while children remain active can break invariants. Choose clear rules cascade to mark children deleted restrict delete when children exist or move children to a safe container during retention.

Derived store skew Search caches and analytics might lag behind. Use reliable event delivery and idempotent consumers. Add a reconciliation job that scans for mismatches between primary storage and derived stores.

Privacy and right to erasure Soft delete alone is not compliance. You still need a purge plan that removes data fully within policy windows. Keep audit metadata only if policies allow.

Storage bloat and performance Large tables with many deleted rows can slow queries. Use partial indexes prune partitions and compact storage through purge. For object stores enable lifecycle rules that transition old blobs to cheaper tiers before deletion.

Ambiguous product behavior Users expect immediate disappearance but support needs to restore. Provide a clear recently deleted experience and notify the user about retention policy.

Interview Tip

Clarify the life cycle at the whiteboard. Say that delete is a reversible state change that publishes a tombstone event while purge is an irreversible operation. Then outline how you will enforce uniqueness for active rows and how undelete rebuilds search caches and projections. Finish with an idempotent flow and an audit log that records who did what and when.

Key Takeaways

  • Soft delete marks data as deleted while keeping it available for restore analytics and audit

  • Undelete is a first class workflow with conflict checks reindex and cache warm up

  • Always filter deleted rows at the data boundary and enforce uniqueness for active rows

  • Publish deletion and restoration events so every consumer updates caches and search

  • Add retention and purge to meet privacy and cost goals

Table of Comparison

ApproachDescriptionProsConsTypical UseUndelete Support
Soft DeleteMarks data with a deletion flag and hides from readsEasy recovery, full audit, low riskIncreases storage size, potential query leaksApps needing restore & audit trails✅ Yes
Hard DeletePhysically removes dataSimple, storage efficientIrreversible, no auditData easy to recompute or privacy critical❌ No
Archive TableMoves deleted rows to a separate tableKeeps primary fast, recoverableSlower restore, higher complexityLarge transactional systems✅ Yes
Object VersioningStores delete markers in object storageGreat for media & blobsNeeds coordination with metadataFile or document storage✅ Yes
Event Log TombstonePublishes delete events for consumersWorks in event-driven systemsRequires strict contractsStreaming & CQRS designs✅ Yes

FAQs

Q1. Is soft delete the same as archive?

No. Soft delete keeps the row in place with a marker and hides it from reads. Archive moves data to a different table or store to keep hot paths small.

Q2. How do I enforce unique keys with soft delete?

Use partial indexes that apply only to active rows or include the deletion marker in a composite unique key. On undelete run a conflict check and repair by merge or rename.

Q3. How long should I retain deleted data before purge?

Pick a policy based on user expectations and legal rules such as thirty or ninety days. Document it and enforce it with a scheduled purge that also removes blobs and derived data.

Q4. How does undelete work in microservices?

Treat restore as a workflow. The owning service clears the marker then republishes a resource restored event. Consumers rebuild search documents counters and caches. Make every step idempotent.

Q5. Does soft delete satisfy right to erasure requirements?

Not by itself. You must purge all copies within the required window. That includes primary tables backups object storage and search indexes. Keep only the minimal audit metadata allowed by policy.

Q6. How do I test that deleted rows never leak into user views?

Add contract tests at the service boundary. Use database views or ORM global scopes that filter by default. Create a synthetic deleted record and assert that core endpoints and search do not return it.

Further Learning

To master data lifecycle management and reliability patterns:

  • Strengthen your fundamentals with Grokking System Design Fundamentals, which is ideal for beginners who want to understand how patterns like soft delete, caching, and replication interact.

  • Dive deeper into event-driven architecture and state recovery with Grokking Scalable Systems for Interviews, which is perfect for intermediate to advanced engineers preparing for FAANG-level design interviews.

TAGS
System Design Interview
System Design Fundamentals
CONTRIBUTOR
Design Gurus Team
-

GET YOUR FREE

Coding Questions Catalog

Design Gurus Newsletter - Latest from our Blog
Boost your coding skills with our essential coding questions catalog.
Take a step towards a better tech career now!
Image
One-Stop Portal For Tech Interviews.
Copyright © 2025 Design Gurus, LLC. All rights reserved.