Data Modeling
Schema decisions outlive the engineers who made them. These posts cover the trade-offs behind soft deletes, the NULL trap, UTC and time zones, JSONB versus columns, and the shapes that turn into pain three years later.
UTC In the Database Was the Easy Part
Storing UTC is the easy part. Display, recurring events, DST, date-only fields, and scheduled jobs: the real bugs live in the conversion layer, not the storage.
Read more BackendThe NULL Trap
NULL is a three-valued logic system that corrupts aggregations, breaks NOT IN subqueries, and hides rows from WHERE clauses. It is not just a missing value.
Read more BackendDatabase Partitioning: The Decision You Can't Undo
Range vs hash partitioning, hot spots, and the re-partitioning trap. Partitioning looks like a scaling win until you find out you cannot undo the choice.
Read more BackendSoft Deletes Are a Trap
Adding is_deleted to your tables feels harmless. Here's what it actually costs: broken constraints, query pollution, index bloat, and cascading confusion.
Read more DatabasePostgreSQL JSONB Deep Dive: Operators, Indexes, and the Tradeoffs Nobody Told You About
JSONB operators, GIN vs expression indexes, and the cost of JSONB over typed columns - all proved with EXPLAIN ANALYZE on 200k Postgres rows. Tests in the repo.
Read more