DEV Community

James Sanderson
James Sanderson

Posted on

Implementing CCPA Deletion Is a Distributed Systems Problem

The first time a team implements a data deletion request, the ticket usually says something like "add account deletion." Someone adds a button, writes a DELETE FROM users WHERE id = ?, cascades a few foreign keys, and closes it.

Then legal asks whether the data is gone from the analytics warehouse. And the answer is no. And the ticket reopens as an architecture project.

If you build for California residents, CCPA and CPRA make this obligation real rather than theoretical, and the interesting part is that it is not a legal problem at all once the requirement is understood. It is a distributed systems problem about every place data has been copied to, and it is far easier to design for than to retrofit.

The actual requirement

Stripped of legal language, the system must be able to do three things for a given individual:

  1. Locate every piece of personal information about them, everywhere it is stored
  2. Produce it in a portable format
  3. Delete it, with limited and specific exceptions

Point one is the hard one. Points two and three are mostly mechanical once you can do point one reliably.

The reason point one is hard is that "everywhere" is a much larger set than most teams' mental model of their system.

Where the data actually is

Write this list out for your own system. It is longer than you expect.

  • Primary database. The obvious one. Usually the only one anyone thinks of initially.
  • Read replicas and caches. Redis keyed by user id, materialised views, denormalised lookup tables, search indices. An Elasticsearch document containing a user's name and email survives the primary-database delete quite happily.
  • The analytics warehouse. Your BigQuery or Snowflake instance has been receiving event streams for years. Those events contain user identifiers, and often much more than identifiers.
  • Event streams and message queues. Kafka topics with a retention window still contain the data during that window. So do dead-letter queues, which frequently have no retention policy at all.
  • Application logs. This is the one that catches people. If you have ever logged a request body during debugging, personal data is sitting in your log aggregator, and log aggregators are typically retained for months and indexed for search.
  • Backups. The genuinely hard one, discussed below.
  • Third-party processors. Your email provider, payment processor, error tracker, session recorder, support desk, CRM, feature flag service, and marketing automation platform each hold a copy. Each has its own deletion API, its own latency, and its own quirks.
  • Derived artifacts. Exported CSVs sitting in an S3 bucket, generated PDFs, a data-science team's working copy in a notebook environment.

A deletion implementation that does not have an answer for every line on that list is not a deletion implementation. It is a button.

The backup problem

Backups are where most implementations quietly compromise, and it is worth understanding the honest options rather than pretending the problem does not exist.

Deleting a single record from a backup is generally not feasible. Backups are immutable snapshots by design; that immutability is the entire point of having them.

The three approaches that actually get used:

Retention-window expiry. Document that backups age out on a defined schedule — 30, 60, 90 days — and that deletion propagates as backups expire. Track the pending deletion so that if a restore happens within the window, the deletion is reapplied immediately afterwards. This is the most common approach and it is defensible when the window is documented and the reapplication step actually exists rather than being assumed.

Crypto-shredding. Encrypt each user's personal data with a per-user key held outside the backup scope. Deleting the key renders the backed-up ciphertext unrecoverable. This is elegant, genuinely solves the problem, and has to be designed in from the start — retrofitting per-user encryption into an existing schema is a large project.

Tokenisation. Keep personal data in a separate vault referenced by token, so the bulk of the system holds only tokens. Delete the vault entry and every backup elsewhere contains only meaningless identifiers. Also a design-time decision.

The point is not that one approach is correct. It is that a team who has done this before will raise backups within the first two minutes of the conversation, because it is the constraint that shapes the design. A team who has not will describe a settings page.

Design implications worth adopting early

A user-data inventory as a maintained artifact. A document, ideally generated or at least validated by tests, listing every store containing personal data and the deletion mechanism for each. Without it, the next new datastore silently breaks compliance and nobody notices for a year.

A deletion orchestrator, not a deletion function. Deletion spans systems with different latencies and failure modes, and third-party APIs fail. This is a durable workflow with retries, idempotency, per-target status tracking, and an audit record — not a synchronous call chain. Treat it with the same seriousness as a payment flow.

Log hygiene as a build-time concern. Structured logging with an explicit allowlist for fields, plus a linter or CI check that fails when a request body is logged whole. Cleaning personal data out of a year of log history is enormously more expensive than never putting it there.

Consistent identifiers across systems. If your warehouse keys on a different user identifier than your primary database, and your support desk keys on email address, locating one individual across all three becomes a join nobody wants to maintain under time pressure. Decide the correlation strategy early.

Test it in CI. Create a user, exercise the system so data spreads to every store on the inventory, issue a deletion, then assert emptiness across all of them. This is one of the highest-value integration tests a product can have, and almost nobody writes it.

Why this belongs in a vendor conversation

If you are evaluating an engineering partner and you serve California residents, this is a precise, checkable question with a wide range of possible answers: describe a data subject deletion you implemented end to end.

Teams who have done it start with backups and third-party processors, because that is where the difficulty lives. Teams who have not describe a settings page and a database cascade.

It is worth noting that the obligation attaches to serving California residents, not to where your engineering team is located. A firm in San Francisco has no inherent advantage here over a distributed team — what matters is whether they have implemented it before.


The full guide to evaluating California engineering partners — market segments, regional differences, current rate bands, contract specifics under California law, and twelve-month cost ranges — is here: Software Companies in California, USA.

Frequently Asked Questions

Does CCPA require deleting data from backups?

The obligation is to delete personal information, and regulators have generally accepted documented retention-window expiry as reasonable for backups, provided deletion is reapplied if a restore occurs within the window. Crypto-shredding and tokenisation solve it more completely but must be designed in from the start.

What is crypto-shredding?

Encrypting each user's personal data with a per-user key stored outside backup scope. Deleting the key makes the backed-up ciphertext unrecoverable without touching the backup itself. It works well and is difficult to retrofit into an existing schema.

Why are application logs such a common problem?

Because request bodies get logged during debugging and the practice persists. Log aggregators are typically retained for months and are fully indexed, so personal data there is both durable and searchable. A CI check that fails on whole-body logging is far cheaper than remediating a year of history.

How should deletion across third-party services be implemented?

As a durable, idempotent workflow with retries and per-target status tracking, not a synchronous call chain. Third-party deletion APIs have varied latencies and failure modes, and you need an audit record showing which targets completed.

Do I need a California-based team for CCPA compliance?

No. The obligation attaches to serving California residents regardless of where your engineers are. What matters is demonstrated experience implementing deletion end to end — ask for a specific prior implementation rather than a claim of familiarity.

What single test proves the implementation works?

An integration test that creates a user, exercises the system so data propagates to every store in your inventory, issues a deletion, then asserts emptiness across all of them. Very few teams have this, and it is one of the highest-value tests a product can carry.

Top comments (0)