My original understanding for ALTER TABLE ADD COLUMN in postgres is that if you just add a simple new column (i.e. no default value, no indexing, no non-null validation etc.) then there's no locking.
However starting from 9.4 this no longer seems to be true:
https://www.postgresql.org/docs/9.3/static/sql-altertable.html
https://www.postgresql.org/docs/9.4/static/sql-altertable.html
In the 9.4 documentation it says
An ACCESS EXCLUSIVE lock is held unless explicitly noted. When multiple subcommands are listed, the lock held will be the strictest one required from any subcommand.
while there was no such thing in 9.3.
In practice, 9.4 does seem more likely to trigger deadlock when the table has heavy traffic - not exactly sure why this is the case though. Theory is the transaction is implicitly holding a ROW EXCLUSIVE lock on the table and then it gets escalated to ACCESS EXCLUSIVE when the statement gets executed but again it's just a theory.
Question is: what changed the design and what's the correct way to add a column today for tables with high traffic?