Database Migrations Without Downtime: The Expand-Contract Pattern

Database migrations are terrifying. One wrong move and you’ve locked tables, broken queries, or corrupted data. The traditional approach — maintenance window, stop traffic, migrate, restart — works but costs you availability and customer trust. The expand-contract pattern lets you migrate schemas incrementally, with zero downtime, while your application keeps serving traffic. The Core Idea Never make breaking changes in a single step. Instead: Expand: Add the new structure alongside the old Migrate: Move data and update application code Contract: Remove the old structure Each step is independently deployable and reversible. ...

February 23, 2026 Â· 5 min Â· 991 words Â· Rob Washington

Database Connection Pooling: The Performance Win You're Probably Missing

Database connections are expensive. Each new connection requires TCP handshake, authentication, session initialization, and memory allocation on both client and server. Do this for every web request and you’ve got a performance problem hiding in plain sight. The Problem: Connection Overhead A typical PostgreSQL connection takes 50-100ms to establish. For a web request that runs a 5ms query, you’re spending 10-20x more time on connection setup than actual work. 1 2 3 4 5 6 7 8 # The naive approach - connection per request def get_user(user_id): conn = psycopg2.connect(DATABASE_URL) # 50-100ms cursor = conn.cursor() cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,)) # 5ms result = cursor.fetchone() conn.close() return result Under load, this creates connection storms. Each concurrent request opens its own connection. The database has connection limits. You hit those limits, new connections queue, latency spikes, everything falls apart. ...

February 23, 2026 Â· 5 min Â· 898 words Â· Rob Washington

Database Migrations: Schema Changes Without Downtime

The scariest deploy isn’t code—it’s schema changes. One wrong migration can lock tables, corrupt data, or bring down production. Zero-downtime migrations require discipline, but they’re achievable. The Problem Traditional migrations assume you can take the database offline: 1 2 -- Dangerous in production ALTER TABLE users ADD COLUMN phone VARCHAR(20) NOT NULL; This locks the table, blocks all reads and writes, and fails if any existing rows lack a value. In a busy system, that’s an outage. ...

February 16, 2026 Â· 6 min Â· 1095 words Â· Rob Washington