All rules Rule BV016 · LK
PostgreSQL
note
LK · Locks & blocking
free in the CLI

Does DROP INDEX block queries in Postgres?

DROP INDEX without CONCURRENTLY

Note: this works and blocks nothing, but a performance regression is likely.

What happens

DROP INDEX needs ACCESS EXCLUSIVE on the table. The drop itself is instant, but the lock request queues behind any running query touching the table, and every new query then queues behind the lock request. One slow SELECT turns an instant drop into a stall for all traffic.

Why it is dangerous on a populated table

Nothing blocks, but the cost scales with the table and shows up as a slower query plan or a longer maintenance window rather than an outage.

Measured

Both forms ran against the same table (20M rows, 1.7 GB) on Postgres 18.6, with one session inserting a row and another reading one row every 50 ms. Worst wait is the slowest of those probe calls while the statement ran. This run is from Sep 16, 2026; the whole benchmark has every scenario and how to run it.

StatementTimeWorst write waitWorst read waitLock
FiresDROP INDEX behind an open read10.0 s10.0 s10.0 sAccessExclusiveLock
SafeDROP INDEX CONCURRENTLY behind the same read10.0 s17 ms15 msShareUpdateExclusiveLock

Fires on

DROP INDEX idx_orders_region;

The safe pattern

DROP INDEX CONCURRENTLY waits for conflicting queries instead of queueing all traffic behind an ACCESS EXCLUSIVE request. Run it alone in its own migration, outside a transaction. (It cannot drop indexes that back UNIQUE or PRIMARY KEY constraints, use ALTER TABLE DROP CONSTRAINT for those.)

-- In its own migration file, run outside a transaction:
SET lock_timeout = '5s';
DROP INDEX CONCURRENTLY idx_orders_region;

Fixtures

The rule ships with these files and the test suite runs them on every change: the first set must fire, the second must stay silent.

Fires (1)

drop index
DROP INDEX idx_orders_region;

Stays silent (1)

drop index concurrently
DROP INDEX CONCURRENTLY idx_orders_region;

How to check locally

Catch this before it ships

This rule runs locally in the free CLI, or with the full corpus through the hosted service. No install, nothing leaves your machine:

npx bolvrk check migration.sql