← See all TILs

Unique hash indexes in Postgres

Published: April 18, 2024

I recently discovered via the excellent PostgreSQL 14 Internals book that it’s possible to have a hash index in Postgres with a unique constraint.

The trick is to use an exclude constraint like this:

constraint my_index exclude using hash(my_column with =)

There are currently a few caveats when using this trick:

The first one is that for on conflict statements the constraint must be explicitly named. This is not a big deal.

The second one is that exclude constraints cannot currently be added as not valid, meaning that you cannot add the constraint to an existing table without acquiring an exclusive lock and therefore it’s a migration that cannot run with zero downtime.

For an example of how this approach correctly handles potential hash collisions see this dbfiddle.