# Debugging Slow Database Migrations

A migration that runs in seconds on a laptop can hold locks for minutes in production. The difference usually comes from table size and from other sessions waiting behind the migration.

Two checks find most of these problems before they reach users.

## Find the Locking Statement

Start with the sessions that are active while the migration waits. The wait event column shows whether a session is blocked on a lock or on input and output.

```
SELECT pid, wait_event_type, query
FROM pg_stat_activity
WHERE state = 'active';
```

## Batch the Backfill

Large updates should run in batches so each transaction releases its locks quickly. Larger batches raise throughput only slightly while lock waits grow much faster.

| Batch size | Rows per second | Lock wait (ms) |
|------------|-----------------|----------------|
| 1000 | 8200 | 3 |
| 10000 | 9100 | 41 |
| 100000 | 9300 | 620 |
