Skip to content
← All issues

Readyset Weekly: Issue 61

The Hidden Work Behind Zero-Downtime Migrations

A schema change tends to sound small when someone describes it. Add a column, change a type, drop a constraint. The migration script is a few lines and the review takes minutes. Run that same change against a table holding a few hundred million rows, though, and it can turn into the longest twenty minutes of your week.

The reason comes down to locks. Many schema changes take them, and some require a full table rewrite. In Postgres, a column type change that rewrites the table takes an ACCESS EXCLUSIVE lock, which means every SELECT, INSERT, and UPDATE waits behind it until the operation finishes. Connection pools fill, health checks start failing, and a routine deploy becomes an incident. Zero-downtime is the phrase everyone writes on the ticket, but it describes a set of techniques you have to deliberately reach for, because the default behavior of many schema changes is the opposite of zero-downtime.

Here are a few places where the cost shows up, and how to handle them:

  • The lock is the heart of the problem. Some schema changes block reads and writes while they run, so the goal is to avoid disruptive operations rather than avoid the change itself. That means reaching for CREATE INDEX CONCURRENTLY instead of the blocking form, adding constraints as NOT VALID before validating them in a separate step, and structuring changes to avoid unnecessary table rewrites.
  • Replication lag is the second bill. A migration that leaves the primary available can still flood the replication stream with row changes, causing replicas to fall behind. Reads routed to a replica may suddenly be serving data that's minutes old. Batching the backfill into smaller chunks, with pauses between them if needed, helps replicas keep up.
  • Expand-contract takes more deploys than it first appears. Renaming a column safely means adding the new one, writing to both columns, backfilling, switching reads over, and only then dropping the old column. That's several deploys spread over time rather than a single clean swap. It's more work, but each step is safe and reversible.

So how do you keep a schema change from becoming a war story? Safe migrations trade wall-clock time for availability. A table rewrite might finish in twelve minutes of blocked traffic, while an expand-contract migration takes hours of background work and never makes a user wait. Done carefully, a schema change becomes a series of ordinary, reversible steps rather than a high-stakes event that demands a maintenance window. And before making the change, it helps to know which queries depend on the table you're touching. A quick pass with RDST shows you what's hitting it, so nothing surprises you in production.

🔍 What We're Watching in the Database Ecosystem

SpaceX to Acquire AI Coding Startup Cursor for $60 Billion

Days after its record IPO, SpaceX agreed to buy Cursor in an all-stock deal worth $60 billion, one of the largest acquisitions of a venture-backed startup on record. The number worth holding onto if you run a database underneath an engineering org: Cursor's tools generate something on the order of 150 million lines of enterprise code a day. Whatever you make of the deal, the tool writing that much production code, and the SQL that rides along with it, just changed hands, which is worth watching if your team leans on it.

PostgreSQL 19 Beta 1 Is Out

The first beta of Postgres 19 landed on June 4, and there's plenty in it for operators, not just app developers. Foreign key checks can run up to twice as fast, autovacuum can finally use parallel workers, and logical replication picks up several usability improvements, including sequence synchronization and the ability to enable replication without a server restart. It's a beta, so it's for testing rather than production, but it's a good opportunity to run your own workloads against it.

In Case You Missed It

Readyset now speaks MCP: our new MCP server lets Claude, Cursor, and other agents inspect proxied queries, see what's cacheable, and create or drop caches directly, so the copy-SQL-into-a-chat-window-and-paste-it-back loop is finally over.

Know a database aficionado who'd appreciate this? Forward it their way.

Get Readyset Weekly in your inbox

One email a week — what shipped, what we learned, and what is worth reading.