A couple of years ago we shared[0] an experimental extension for CRDTs in Postgres. This was a good start, but it had a major limitation: CRDTs can be very chatty and so they quickly fill up the WAL.<p>We just released a new version which solves this problem: <a href="https://github.com/supabase/pg_crdt">https://github.com/supabase/pg_crdt</a><p>The new approach uses UNLOGGED tables for documents and logged tables for changes. This enables us to merge changes efficiently in-memory, then persists just the changes directly to the WAL (previously it was sending the entire CRDT).<p>The new version also takes advantage an advanced in-memory object persistence feature in Postgres called "expanded datum"[1] and some optimizations to this feature that are coming in Postgres 18[2]. This allows for more complex operations without serializing and deserializing the documents between every operation, which gets progressively slower as documents grow.<p>What is a CRDT? A CRDT (Conflict-free Replicated Data Type) is a data structure that syncs across multiple devices or users. They are used in multi-player applications like Figma and Notion. For example: A shared text editor where multiple people type at once, and everyone sees the same final result without manual conflict resolution.<p>The end goal here is that you will be able to store CRDTs as a data type in your database, and treat Postgres simply as a "peer". A good example would be storing text for a blog post:<p><pre><code> create table posts (
id serial primary key,
title text not null
content autodoc not null default '{}'
);
</code></pre>
Repo: <a href="https://github.com/supabase/pg_crdt">https://github.com/supabase/pg_crdt</a><p>Docs: <a href="https://supabase.github.io/pg_crdt/automerge/" rel="nofollow">https://supabase.github.io/pg_crdt/automerge/</a><p>----<p>[0] initial release/discussion: <a href="https://news.ycombinator.com/item?id=33931971">https://news.ycombinator.com/item?id=33931971</a><p>[1] expanded datum: <a href="https://www.postgresql.org/docs/current/storage-toast.html#STORAGE-TOAST-INMEMORY" rel="nofollow">https://www.postgresql.org/docs/current/storage-toast.html#S...</a><p>[2] PG18 optimizations: <a href="https://www.postgresql.org/message-id/3363452.1737483125%40sss.pgh.pa.us" rel="nofollow">https://www.postgresql.org/message-id/3363452.1737483125%40s...</a>