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.
| Statement | Time | Worst write wait | Worst read wait | Lock | |
|---|---|---|---|---|---|
| Fires | DROP INDEX behind an open read | 10.0 s | 10.0 s | 10.0 s | AccessExclusiveLock |
| Safe | DROP INDEX CONCURRENTLY behind the same read | 10.0 s | 17 ms | 15 ms | ShareUpdateExclusiveLock |
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 idx_orders_region;Stays silent (1)
DROP INDEX CONCURRENTLY idx_orders_region;How to check locally
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