We use analytics cookies.We use cookies to analyze site traffic and improve your experience.
Loading...
System Design Masterclass · Database Fundamentals
Free preview: the first 2 parts of this 9-part lesson.
Already bought the course? Sign in to read the whole lesson.
this lesson is part of
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design courseread the rest of this lesson in
System Design Masterclass
Unlock this lesson and the 751 other paid lessons
$25 once, by PayPal
See the System Design coursein Database Fundamentals
This lesson is part of the full System Design Masterclass. Unlock it along with 769 other lessons for a one-time payment.
One-time payment by card or PayPal
Get Lifetime AccessOne-time payment: UPI, card or netbanking
Get Lifetime Access18 Foundation lessons are free, no payment needed. Try them now
It is easy and good
“It is really nice and good Please join the course”
Soft delete is the first schema decision most teams make and the one they are least likely to revisit. Marking a row deleted instead of removing it sounds free: nothing is lost, the audit trail is intact, and the undelete button works.
The row is still there. Everything below follows from that one sentence.

A million users in a real PostgreSQL, seventy percent of them soft deleted, which is what a table looks like after a few years of a delete button that does not delete.
Soft delete is often the right decision. The point of this lesson is that it has a price, the price grows with the table, and two partial indexes stop most of it.

Every number is measured against a PostgreSQL this lab started on a scratch directory and tore down.

Both hold exactly the same live data. Seventy percent of the rows in the first are invisible to every query the application makes, and every one of them is on disk, in the page cache, and in every index.
The ratio moves with the share deleted and the shape does not. Whatever fraction of a table is dead, that fraction of every scan, every index page and every cached block is being spent on rows nothing will ever return.

The measured point is the last one. The rest of the curve is arithmetic on the same table, and its shape is why this problem is invisible for years and then suddenly is not.
Plot live rows over total rows on every table with a deleted flag. It is one query, it costs nothing, and it is the only number that tells you the schema has quietly committed to storing every row the product has ever created.