PostgreSQL
Postgres is the database I default to, and most of these posts are about the failure modes you only meet at scale: query planner surprises, NULL semantics, replica staleness, deadlocks, partitioning trade-offs, and the indexes you thought you had.
Postgres Won the Database War. Now What?
Postgres passed MySQL on the Stack Overflow survey. 'Postgres for everything' became the default. Where that gravity helps, where it quietly stops, and my rule.
Read more BackendYou're Running Kafka for Three Topics
Kafka is a commit log for high-throughput streaming. Three topics at 10 msg/sec is not that. The operational tax you didn't price, and the tool that fits.
Read more DatabaseDuckDB Ate Your Analytics Pipeline and That's Fine
Most 'big data' analytics is tens of gigabytes, not terabytes. DuckDB runs it on one node in seconds, no cluster. When single-node wins and where it bites.
Read more Databasepgvector at 10 Million Rows Is a Different Animal
pgvector is great at 100k rows. At 10 million it's a different animal. IVFFlat vs HNSW, storage math, the quantization escape, and what actually breaks.
Read more BackendThe Postgres Index That Never Gets Used
Postgres indexes accumulate. Every perf push adds one. Almost no team removes any. How to find the unused ones and why their write cost is the bigger problem.
Read more BackendThe Long Transaction That Ate Your Postgres
An idle transaction pins the xmin horizon. Autovacuum cannot reclaim anything newer than it. Tables bloat. Queries slow. Here is the fix every install needs.
Read more BackendHibernate's ddl-auto Is Not a Migration Tool
ddl-auto: update silently adds columns and never drops them. What it does to your schema, why it fails on renames, and how to safely replace it with Flyway.
Read more BackendYour Replica Is Lying To You
Read replicas trade staleness for throughput. Replication lag, read-your-writes, and the staleness window nobody tracks: these are where things actually break.
Read more BackendUTC 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 BackendTwo Transactions Walk Into a Lock
Deadlocks are not exotic. They are predictable consequences of lock order. Here are the patterns, the fixes, and the eleven characters that ended one outage.
Read more BackendThe Composite Index Nobody Can Read
Your composite index covers every column but EXPLAIN still shows a full scan. Column order, not column presence, determines whether PostgreSQL uses the index.
Read more BackendDatabase Isolation Levels Are a Contract, Not a Dial
Isolation levels define which anomalies you tolerate, not how much correctness you get. The SQL standard and what databases implement diverged decades ago.
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 BackendEXPLAIN ANALYZE Lies to You
PostgreSQL's EXPLAIN ANALYZE tells you the plan looks fast. It doesn't tell you the timing is cached, the estimates are stale, or the cost isn't milliseconds.
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 BackendConnection Pool Tuning: A Practical Guide
HikariCP's defaults look sensible until your app hits production load. Here's how to actually size your connection pool using Little's Law, not guesswork.
Read more BackendTransactions Don't Fix Race Conditions
Wrapping code in a transaction doesn't make concurrent operations safe. Here's what transactions guarantee and what race conditions they let slip through.
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 BackendThe Database Is Not Your Message Queue
Polling a status column every few seconds works until it does not. Here is why your database makes a terrible message queue and what to reach for instead.
Read more BackendDatabase Indexes Explained for People Who Keep Forgetting
You've read about database indexes before. You've forgotten most of it. Here's the practical guide you'll actually remember, with PostgreSQL examples.
Read more BackendSpring Data Derived Queries: Crossing Boundaries
Nested traversal in Spring Data derived queries: the underscore rule, the distinct-join trap, the same-collection trap, projections, EntityGraph, streams.
Read more BackendSpring Data Derived Queries: The Single-Entity Toolkit
Spring Data writes JPQL from your method names. The full single-entity keyword set: equality, comparison, string ops, null, In, OrderBy, Top, Pageable, countBy.
Read more BackendHikariCP in Production: Tuning, Monitoring, and pgbouncer
Tune HikariCP for production Spring Boot 4 services on Postgres. Little's Law sizing, the properties that matter, monitoring signals, pgbouncer fronting.
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 DatabaseDatabase Indexes Explained: A PostgreSQL Walkthrough With EXPLAIN ANALYZE
B-tree, composite, partial indexes proved with EXPLAIN ANALYZE on 500k Postgres rows. Plus the three ways EXPLAIN ANALYZE lies to you. Tests in the repo.
Read more