Spock gives PostgreSQL logical multi-master replication, at the cost of a patched server
Logical multi-master PostgreSQL replication
At a glance
- What is it?
- Spock is a pgEdge extension that replicates data between PostgreSQL 15 through 19 nodes as a logical, multi-master set, with replication sets, subscriptions, automatic DDL replication and lag tracking. It is not a loadable module: you apply version-specific patches to a PostgreSQL source tree and build both together.
- Who is it for?
- Spock fits teams that need several PostgreSQL nodes to accept writes and stay in sync at the row level, that want to add and remove nodes with scripts rather than manual surgery, and that are prepared to own a patched build of the database server.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly C, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Multi-master replication that needs a patched PostgreSQL
Spock is a pgEdge extension that provides multi-master replication for PostgreSQL versions 15, 16, 17, 18 and 19. The mechanism is logical replication, where changes are decoded and replayed between nodes rather than replicated as physical WAL bytes, and the multi-master part means more than one node can take writes.
The thing to understand before anything else is that this is not an extension you load into a stock server. The README is explicit that you need to build the Spock extension on a patched PostgreSQL source tree to which you have applied version specific .diff files. You apply the patches, then configure, make and make install the PostgreSQL server, and only then build the extension itself.
That is a significant operational commitment, and it shapes everything else. It means your upgrade path is a source patch, not a package upgrade, that your build system has to carry the patches, and that the version-specific patch set is something you track.
The extension is written in C and lives in a repository with the usual PostgreSQL extension shape: a Makefile, a spock.control.in template, sql/ with the versioned SQL scripts, src/ with the C sources, include/ with headers, tests/, and a patches/ directory holding the per-version diffs. The main branch was last pushed to on 2026-10-19, and the project has no GitHub releases, with the release notes kept in the documentation instead.
Identical schemas are a requirement, not a convention
The prerequisites section of the README lists the requirements you have to design your cluster around, and the first one is about schema identity.
On each node, tables must have the same name and reside in the same schema. The README shows how to check this with psql, by listing the relations for a database:
SELECT schemaname, tablename FROM pg_tables ORDER BY schemaname, tablename;Each table must also have the same columns and primary keys, with the same data types in each column. The README shows the psql command for a whole schema, \d public.*, and the output that reveals the column types, the nullability, the defaults, the primary key index and the sequence owned by the identity column.
The third requirement is about constraints, and it is asymmetric in an important way. CHECK constraints and NOT NULL constraints must be the same or more permissive on any standby node that acts only as a subscriber.
That direction of travel makes sense for a replication system. A subscriber that enforced a stricter constraint than the primary could reject a row that the primary legitimately accepted, which would turn a data problem into a replication stall. The cost is that the subscriber's schema is not free to be tighter, so the constraints you want everywhere have to be applied on the node that accepts writes.
Together these three rules are the schema contract for the cluster. They are not checked at runtime for you, so a cluster that drifts will fail in ways that point at the data rather than at the configuration.
The build is: patch the source, install Postgres, then build the extension
The README gives the build steps in order, and the order matters.
First get the PostgreSQL source. Then copy the patch files to the base repository, with the patches for each version in a version specific subdirectory of the spock repo, and apply each one with:
patch -p1 < path_to_patch/patch_nameThe instruction that follows is the one people miss. You must apply the patches in the numerical order designated by their prefixes in the spock repository, for example pg16-015-patch-name, then pg16-020-patch-name, then pg16-025-patch-name. The numbering is a sequence, not a set, so an out of order application can fail or produce a tree that does not compile.
Then you configure, make and make install the Postgres server as described in the PostgreSQL documentation, and add the location of your pg_config file to your PATH:
export PATH=path_to_pg_config_fileNext clone the extension and build it:
git clone https://github.com/pgEdge/spock.gitfollowed by make and then make install for spock.
Finally the server configuration has to be changed, and the README shows the settings:
shared_preload_libraries = 'spock'
track_commit_timestamp = on # needed for conflict resolutionThe shared_preload_libraries entry is the standard way a PostgreSQL extension that needs to start first is loaded, and the track_commit_timestamp line carries a comment that says why it is there: it is needed for conflict resolution. That single comment tells you the replication conflict logic depends on commit timestamps being available, which is a dependency worth understanding before you design the conflict resolution policy.
The Makefile picks the source directory from your PostgreSQL version
The extension's Makefile is where the multi-version support is implemented, and it is worth reading before you build.
The version detection is a shell pipeline that runs pg_config, strips the non-numeric characters and takes the first two digits:
export PG_CONFIG ?= pg_config
PGVER := $(shell $(PG_CONFIG) --version | sed 's/[^0-9]//g' | cut -c 1-2)That value then selects the source directory, since the vpath line points at src and src/compat/$(PGVER), and the same pattern appears in the source list, where the C files are the wildcard of src/*.c plus the wildcard of src/compat/$(PGVER)/*.c. So the compatibility layer for each PostgreSQL major lives in its own subdirectory and is compiled in on top of the shared sources.
Two environment variables toggle development behaviour. SPOCK_RANDOM_DELAYS injects unconditional random delays at worker start and finish, and the comment says it does this without requiring injection point infrastructure or a runtime spock.inject_attach() call, which makes it usable from a plain shell rather than from a debugger session. NO_LOG_OLD_VALUE compiles out the logging of the old value of a column.
The build is a standard PGXS build, since the Makefile computes PGXS from $(PG_CONFIG) --pgxs and includes it, with the module named spock and an output plugin module named spock_output. The PGFILEDESC line describes it as spock, multi-master replication.
Replication sets, subscriptions and the management surface
The documentation index shows how much sits on top of the core replication, and the structure is worth understanding before you plan a deployment.
The organising idea is the replication set. You put tables into replication sets, you create subscriptions between nodes and the replication sets, and the extension handles the movement of rows. There is a whole documentation chapter for replication set management functions, alongside node management functions, subscription management functions and general cluster management functions, so most day to day operations are SQL functions rather than configuration edits.
Around that core sit the features that make a multi-master setup usable in production. There is a chapter on replicating partitioned tables, one on using batch inserts, one on filtering data, and one on running Spock in read-only mode. A separate chapter covers using a trigger to manage replication set membership, so membership can follow the application rather than a manual list.
There is also automatic DDL replication, so schema changes can travel with the data instead of needing a separate migration on each node, and support for Snowflake sequences for distributing unique keys without a central allocator, and a chapter on using Lolor to manage large objects.
Adding and removing nodes has its own section, and this is where the tooling is unusually strong. There is Zodan, a set of scripts and workflows for modifying a cluster, with a tutorial for adding a node with zero downtime, plus a separate path for adding a node with minimal downtime using pgBackRest. The two documents, in the repository under docs/modify/, and the samples/ directory which includes a Z0DAN folder and a script for setting synchronized standby slots.
Monitoring a cluster means watching lag and content
The monitoring section of the documentation is aimed at answering two questions: is the cluster healthy, and are the nodes actually in agreement.
For configuration and health there is a chapter on monitoring the configuration and health of a cluster, and a separate one on finding cluster information, with spock_info as the function that surfaces it. For replication delay there is a dedicated lag tracking chapter, which is the one an on-call engineer will actually open during an incident.
The interesting instrument is the sync event, documented under using a sync event to monitor node content. A sync event lets you check that the nodes really do hold the same data, which is a stronger check than comparing lag counters, because a cluster can be healthy and still inconsistent if a subscription is missing rows.
The project also publishes a badge for regression tests and Spockbench, pointing at the spockbench workflow, so the build is exercised by an automated test suite rather than only by the maintainers' own clusters. The tests/ directory in the repository holds the test sources, and the Makefile cleans the tests/logs and tests/tap/logs directories after a run, which is the shape of a TAP based regression suite.
The documentation also has dedicated pages for limitations, troubleshooting and a FAQ, and separate release notes, which is what you want from a project where upgrades mean reapplying patches.
A custom licence, no GitHub releases, and a vendor behind it
Spock comes from pgEdge, and the repository is under the pgEdge organisation rather than the PostgreSQL project. The homepage linked in the repository is the pgEdge get started page, and the documentation is built with mkdocs, with a mkdocs.yml at the repository root.
The licence is a custom one that GitHub cannot classify, with LICENSE.md and a COPYRIGHT file in the repository root. The README section for that topic is not in the visible documentation, so the terms are in the files themselves, and for a component that sits in the middle of a database cluster, the terms are worth reading before you commit to it.
There are no GitHub releases, so the version history lives in the documentation, in the release notes page listed in the table of contents. That is a sensible choice for a project whose releases are tied to PostgreSQL major versions and to a specific patch set, and it is consistent with the build model, where the version-specific patch directory is what you actually select.
The repository also has a SECURITY.md for responsible disclosure and a .codacy.yaml for static analysis, and the samples directory contains a README alongside the Zodan material and the slot synchronisation script.
The most recent push was on 2026-10-19, so the tree is being worked on, and the practical conclusion for anyone evaluating the project is that the deciding factor is not the feature list but whether your team can carry a patched PostgreSQL build.
Editorial conclusion
Spock fits teams that need several PostgreSQL nodes to accept writes and stay in sync at the row level, that want to add and remove nodes with scripts rather than manual surgery, and that are prepared to own a patched build of the database server. It is the wrong choice if you need a drop-in extension for an unmodified PostgreSQL install, since the extension requires patched server source, and it is the wrong choice if your tables differ between nodes, because identical schemas and primary keys are a hard requirement. Verify first that the version of PostgreSQL you run is one of the supported majors, that the table names, schemas, columns and primary keys really are identical everywhere, that the constraints on subscriber nodes are at least as permissive as on the primary, and that your build toolchain can produce a patched server.
Frequently asked questions
What is the Spock extension for PostgreSQL?
Spock provides logical multi-master replication for PostgreSQL versions 15, 16, 17, 18 and 19. It replicates changes at row level between nodes, with replication sets, subscriptions, automatic DDL replication and lag tracking.
What are the schema requirements for a Spock cluster?
On every node, tables must have the same name and be in the same schema, with the same columns, primary keys and data types. CHECK and NOT NULL constraints must be the same or more permissive on any standby node that acts only as a subscriber.
How do I build the Spock extension?
You apply the version specific patch files from the spock repository to a PostgreSQL source tree in the numerical order of their prefixes, build and install PostgreSQL, put pg_config on your PATH, clone the spock repository, then run make and make install for the extension.
Which PostgreSQL settings does Spock need?
The extension must be listed in shared_preload_libraries as 'spock', and track_commit_timestamp must be turned on, which the README notes is needed for conflict resolution. The extension also installs an output plugin module, spock_output.
How do I add a node to a Spock cluster?
The documentation covers two paths, adding a node with zero downtime using Zodan scripts and workflows, and adding a node with minimal downtime using pgBackRest. There is also a chapter on using a trigger to manage replication set membership.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/pgedge-spock)Was this useful?