# ADD COLUMN is not always free, and the lock queue is what takes you down

DevFeed: [ADD COLUMN is not always free, and the lock queue is what takes you down](<https://devfeed.tech/articles/add-column-is-not-always-free-and-the-lock-queue-is-what-takes-you-down-39595.md>)

Original publisher: [Read original article](<https://ankit-rana.com/logs/43-add-column-is-not-always-free/>)

Author: hello@ankit-rana.com

Published: 2026-08-26T00:00:00Z

Content type: article

Language: en

Sources: [Ankit Rana | Mechanical Sympathy](<https://devfeed.tech/sources/ankit-rana-mechanical-sympathy.md>)

Topics: [PostgreSQL](<https://devfeed.tech/topics/postgresql.md>), [incident](<https://devfeed.tech/topics/incident.md>), [Query (disambiguation)](<https://devfeed.tech/topics/query.md>), [migration](<https://devfeed.tech/topics/migration.md>), [MySQL](<https://devfeed.tech/topics/mysql.md>)

Tags: [ddl](<https://devfeed.tech/tags/ddl.md>), [incident](<https://devfeed.tech/tags/incident.md>), [locking](<https://devfeed.tech/tags/locking.md>), [migration](<https://devfeed.tech/tags/migration.md>), [migrations](<https://devfeed.tech/tags/migrations.md>), [mysql](<https://devfeed.tech/tags/mysql.md>), [postgresql](<https://devfeed.tech/tags/postgresql.md>), [query](<https://devfeed.tech/tags/query.md>), [queues](<https://devfeed.tech/tags/queues.md>), [schema-design](<https://devfeed.tech/tags/schema-design.md>), [timeout](<https://devfeed.tech/tags/timeout.md>)

## AI overview

Adding a nullable column can cause an outage even when the schema change itself is nearly instantaneous. In PostgreSQL, ALTER TABLE may wait for a long-running query, and subsequent queries can queue behind the waiting lock request. Setting a short lock_timeout and retrying can prevent the migration from taking down the table.

## Source excerpt

Modern PostgreSQL adds a column with a default as a metadata change, so the table is never rewritten and the migration itself is instant. The outage comes from lock acquisition instead: ALTER TABLE needs an ACCESS EXCLUSIVE lock, and while it waits behind one long-running query, every subsequent query queues behind the waiting ALTER because the lock queue is ordered. Setting lock_timeout to a couple of seconds and retrying converts that from an outage into a no-op.