Safeguard
Developer Tools•

Soft delete or hard delete for personal data?

A deleted flag is not erasure. When soft delete is fine, when you need hard delete, and a two stage pattern that satisfies both product and privacy.

Safeguard Security Team
3 min read

Soft delete, marking a row as deleted, is fine for undo and short grace periods, but it is not erasure. For personal data, schedule a hard delete or irreversible anonymisation after a fixed window, and make sure the flagged rows are excluded from every query, export and downstream copy until then.

Why soft delete is popular

It protects against mistakes and keeps foreign keys intact. A user clicks delete by accident, support restores the account in seconds. Analytics tables that reference the user do not break.

The cost is that the data is still there. Article 17 of GDPR requires erasure without undue delay when a ground applies, such as the data no longer being needed for its purpose or consent being withdrawn. A row with a deleted flag, full name and email still counts as stored personal data.

A two stage pattern

  1. Stage one, deactivate. On a delete request, mark the account deleted, hide it from product surfaces and stop all processing based on it. Keep it for a short, stated grace period, such as 30 days, chosen for undo needs.
  2. Stage two, erase. A scheduled job hard deletes or irreversibly strips identifying fields once the window ends. Log the erasure in a ledger holding only a subject token and a date.

State the grace period in your privacy notice so it is not a surprise.

What the second stage should do

Hard delete is simplest when nothing else references the row. When other tables must keep the record shape, replace identifying columns with null or a fixed placeholder and drop free text fields. Check that the remaining fields cannot identify the person alone or in combination. If they can, it is not anonymised, only pseudonymised.

Keep what a legal obligation requires. Invoices and tax records have their own retention rules, so retain those fields and delete the rest. Decide with counsel which fields qualify.

Pitfalls

  • Unique constraints. A soft deleted email may block re-registration. Release or hash the value at stage one.
  • Search indexes and caches. The row may vanish from the primary database but linger in an index. Include them in the erasure job.
  • Exports and warehouse copies. Filter on the deleted flag at the sync step, and propagate stage two there too.
  • ORM defaults. If some queries bypass the soft delete filter, deleted users appear in reports. Test it.
  • Cascade surprises. Deleting a user may cascade to shared content owned by others. Decide in advance what happens.

Test it like a feature

Add automated tests: create a user, delete it, run the stage two job, then search every store for the old email and ID. Fail the build if anything remains. Repeat this check after schema changes.

Quick check

Is a deleted_at column enough for GDPR erasure?

No. It hides the record but keeps the data. Erase or anonymise it after the grace period.

How long can the grace period be?

Keep it as short as the undo need justifies and state it in your notice. Article 17 says without undue delay, so long windows are hard to defend.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.