Deep-dive · Operate 4.3

Deletion fan-out

"Delete user X" looks like one row. In a microservices estate it is a distributed problem: at-least-once delivery, idempotent handlers, and a way to prove every service finished inside the clock. Scroll to watch a deletion propagate.

The ruleFan out "delete user X" over a durable bus with at-least-once delivery, idempotent handlers, and a saga that tracks every service's ack within SLA.
Identity / accounts service
writes to outbox in the same transaction, marks the user pending-deletion
UserDeletionRequested → durable bus
Kafka · SNS · EventBridge, at-least-once
DB row delete
Cache invalidate
Lake tombstone
Blob delete
Late joiner
Stripe API
SendGrid / Intercom API
Saga orchestrator
tracks each ack against SLA, pages on lag
ack vs SLA
Step 1 · the shape

A delete is a fan-out problem

"Delete user X" is never one row. It spreads across dozens of services. Doing it synchronously in a single transaction across 40 services is impossible; doing it asynchronously without guarantees is unsafe.

Step 2 · start at the source

Outbox, then a durable bus

The originating service writes UserDeletionRequested to a local outbox table inside the same transaction that marks the user pending-deletion. A relay (Debezium, Kafka Connect, a poller) publishes it. That gives exactly-once production from the source.

Step 3 · every copy

Each service erases its own holdings

Downstream services subscribe and delete locally: row delete, cache invalidation, index removal, lake-row tombstone, blob delete. Each emits UserDeletionCompleted with its service name and a timestamp.

Step 4 · survive replay

Idempotent handlers, tombstones not deletes

At-least-once delivery means handlers will see the same event twice. Either check the subject is gone and treat absence as success, or keep a processed-events table keyed by (event_id, service).

For compacted topics keyed by subject, publish a tombstone (null value) rather than a hard delete.

Step 5 · prove it finished

A saga tracks every ack

An orchestrator records which services have ack'd. When all expected services ack within SLA it marks the request complete and notifies the user. When any service lags, it pages on-call. Fire-and-forget pub/sub cannot prove completion within 30 days.

Step 6 · the outside world

External processors do not subscribe

Stripe, SendGrid, Intercom, Segment, your warehouse reverse-ETL: none of them read your Kafka topic. The orchestrator calls their delete APIs and tracks completion the same way it tracks internal services.

Step 7 · the clock and the trap

Provable in 30 days, and watch late joiners

All of this must be provable within the 30-day erasure clock; missing it is itself a violation. The classic regression: a service onboarded next quarter backfills old data and resurrects erased subjects. It must replay the erasure queue before it goes live.