Skip to content
GreenSnippets

Upsert with INSERT ... ON CONFLICT (PostgreSQL)

Insert a row or update it if the unique key already exists, atomically and safely under concurrency.

SQL
INSERT INTO page_views (path, views)
VALUES ('/pricing', 1)
ON CONFLICT (path)
DO UPDATE SET views = page_views.views + EXCLUDED.views
RETURNING path, views;

How it works

ON CONFLICT makes "insert or update" a single atomic statement, avoiding the race in a separate SELECT then INSERT. The conflict target must match a unique index or constraint. EXCLUDED refers to the row you tried to insert.

Use DO NOTHING when you only want to ignore duplicates. RETURNING gives you the final row either way.