Blog

Insights, updates, and best practices

Postgres runs your query fast exactly five times. Then it changes its mind.
Alexander Ioffe
postgresexplain-analyzeprepared-statementsplan_cache_modequery-plannerbenchmarkingstatisticspgjdbcplpgsql

Postgres runs your query fast exactly five times. Then it changes its mind.

One prepared statement, twelve EXPLAIN ANALYZE runs on one connection, a plan change on run six, and why a single run could never have shown it.

A prepared statement ran in 274 ms for five executions and 2,319 ms from the sixth, on the same connection in the same minute. One EXPLAIN ANALYZE is a sample of size one and cannot see this; twelve in a row, with the plan kept per run, can. The plan cache mechanism behind it, why psql cannot reproduce it, which drivers trigger it, and the one-line fix. Measured on PostgreSQL 17 using ExoBench with twelve repetitions per connection.

JOIN FETCH May Not Save You
Alexander Ioffe
jpahibernateeclipselinkn-plus-oneormsqljavaexobenchmcp

JOIN FETCH May Not Save You

Seven things JPA developers believe about N+1, checked against the SQL that Hibernate and EclipseLink actually prepared

We ran a JPA N+1 detector over Shopizer, Apache Fineract, and Spring PetClinic, then used it to check the standard fixes. A second JOIN FETCH query left the N+1 at 12 statements. Fetching the parent collection left 25. setMaxResults silently lost its LIMIT. Seven beliefs, measured, with the transcripts.

Alexander Ioffe
aiagentstool-callscostsqloptimizationpostgresexobenchmcpbenchmarking

The Cheapest Model Per Run is the Most Expensive Per Real Fix

I gave twelve AI models the same slow query, then read the SQL they actually wrote

Twelve AI models, one slow five-table join, and a real Postgres benchmark they could call as often as they liked. Priced with a flat cost per tool call, a 135x spread in token price collapses to a 1.93x spread in what a run actually costs. Then I read the SQL: 37 of 45 runs from the newest models never sped up the query at all, they precomputed the answer into a materialized view. Divide spend by the runs that actually sped up the query and a mid-tier model from the previous generation wins by 2x.

Alexander Ioffe
postgrespostgres-19graphsql-pgqgraph-tableapache-agerecursive-cteexplain-analyzeneo4j

How Fast Are Postgres 19 Graph Queries?

Part 1: What Are They Actually Doing?

Postgres 19 adds SQL/PGQ graph queries. Measured against a PostgreSQL 19beta1 build, the fixed-depth graph query compiles to the exact same plan as a hand-written join, and the variable-depth traversal that graph databases were built for still falls to a recursive CTE. Apache AGE runs the same indexed traversal under a Cypher wrapper. Numbers from ExoBench in local mode.

Alexander Ioffe
aiagentstool-callscostsqloptimizationpostgresexobenchmcp

Your Cheap AI Model Isn't Cheap Once It Starts Calling Tools

When you give an agent something it can check, the cheap ones just keep checking

The usual advice is that a cheaper model saves money. I gave seven models the same slow SQL query, a verifiable benchmark to hit, and counted the tool calls. The cheap chatty models made 10 to 12 calls each stumbling toward a fix; the frontier models found a cleaner one in 3 to 5. Once each tool call carries a real, model-agnostic cost, the cheap model's price advantage erodes, and past a break-even point the expensive model is the cheapest thing in the room.

Alexander Ioffe
sqloptimizationpostgressql-serverazure-sqlskewcardinality-estimationindexing

Why is my Whale Query 1000x Slower in Prod?

Databases hate skew, each hates it differently

Ten enterprise customers own 80% of the orders. On uniform test data the query runs in ~1ms; on that real skew it runs ~1,000x slower. The fix doesn't transfer between engines: Postgres is rescued by one free session setting, SQL Server can't be touched by it and needs a completely different access-path fix. Measured on Neon and Azure SQL Database using ExoBench.