selfhost.directory

The index of self-hostable projects — ranked, categorized and served with live updates.
Own your data and stop giving it to big tech.

PeerDB logo

Self-host PeerDB

v0.37.13

Postgres-first CDC and streaming ETL into warehouses

ReleaseOpen SourceAGPL-3.0
Updated9 hours ago
LanguageGo
Setup difficultyModerate
Stars
3 310
Ports
9900 (PeerDB server: Postgres-compatible SQL interface (psql client port)), 8112 (Flow API (gRPC)), 8113 (Flow API (HTTP)), 3000 (PeerDB web UI)
Requires
MinIO (S3-compatible object storage), PostgreSQL (catalog), Temporal
Docker
ghcr.io/peerdb-io/peerdb-server
Install with Docker Compose
Peers page of the PeerDB dashboard with the Create Peer buttonNew CDC mirror form: mirror name and source/target peersMirror overview with sync status and replicated row count

What is PeerDB?

PeerDB is a Postgres-focused ETL/ELT tool for streaming data out of PostgreSQL into warehouses, queues and storage at scale. It supports log-based (CDC) replication as the actively maintained mode, with cursor-based Query Replication and XMIN kept functional but deprecated. The maintainers claim 10x faster CDC than general-purpose tools thanks to parallel initial load with transaction snapshotting and CTID scans, parallel reading of the replication slot, efficient handling of large TOAST columns, propagation of added columns, partitioned-table support, and slot-growth and connection alerts. Everything is driven through a Postgres-compatible SQL interface on port 9900, so psql, pgAdmin, or any BI tool can create and monitor peers and mirrors, alongside a web dashboard on port 3000; the Rust Nexus query layer also allows querying remote peers like a federated database. Operators deploy it with the repo's Docker Compose stack (bash ./run-peerdb.sh), which starts the peerdb-server, Flow API and workers, the UI, a Postgres catalog, Temporal for orchestration and fault tolerance, and MinIO used to stage files before loading. PeerDB Cloud and a native ClickHouse Cloud integration are offered as hosted alternatives, and several destination connectors (Snowflake, BigQuery, Elasticsearch, Kafka family, Event Hubs, Pub/Sub, S3) are deprecated for maintenance reasons while still working.

Should you self-host PeerDB?

PeerDB scores 60/100 on selfhost.directory (how scoring works) and ranks #3 of 8 in Data Pipeline. It has 3 310 GitHub stars.

It shipped 8 stable releases in the past year. The latest, v0.37.13, came out on 22 October 2026. New versions land roughly every 7 days.

Setup is moderate: expect some configuration beyond a single command. An official Docker image is available. It is AGPL-3.0-licensed and written mostly in Go.

Its closest alternative on selfhost.directory is sequin (61/100, 2 219 stars). It scores higher overall, so compare the two before you pick. See PeerDB vs sequin side by side.

Features

  • Alerting
  • Change data capture (CDC) replication
  • Fault tolerance and automatic retries
  • Mirror pause, edit and resyncPausing is not possible during initial load/setup, and a paused mirror still grows the replication slot.
  • Parallel initial load
  • Partitioned table replication
  • PeerDB Cloud (hosted)Hosted service, not part of the self-hosted software.
  • Postgres-compatible SQL interface
  • Query-based replicationDeprecated and no longer actively maintained; still functional.
  • Query federation / query layer
  • Schema change propagationRenames, drops and type changes are not propagated automatically.
  • TOAST / large column support
  • Web Dashboard

PeerDB README

How to install PeerDB

Install PeerDB with Docker Compose

docker and docker-compose

git clone --recursive https://github.com/PeerDB-io/peerdb.git cd peerdb ./run-peerdb.sh

Requires docker and docker-compose installed. Then connect with psql "port=9900 host=localhost password=peerdb" and open the UI at localhost:3000.

How to configure PeerDB

  • AWS_ACCESS_KEY_ID
  • AWS_EC2_METADATA_DISABLEDtrue
  • AWS_ENDPOINT_URL_S3http://host.docker.internal:9001
  • AWS_REGIONus-east-1
  • AWS_SECRET_ACCESS_KEY
  • CI_CATALOG_CONTAINERcatalogCatalog container used by flow/db/migrations_test.go to pg_dump scratch databases

    Catalog container used by flow/db/migrations_test.go to pg_dump scratch databases

  • CI_CLICKHOUSE_HOSThost.docker.internal
  • CI_CLICKHOUSE_HTTP_PORT11123
  • CI_CLICKHOUSE_HTTP_PORT_0213123
  • CI_CLICKHOUSE_NATIVE_PORT11000
  • CI_CLICKHOUSE_NATIVE_PORT_0213000
  • CI_CLICKHOUSE_TLS_PORTNative protocol over TLS, exercised by TestClickHouseTLSDirectory. Client certs use cert-manager naming (tls.crt/tls.key). The connector reads the dir as-is, so the path is relative to the test binary's working directory, flow/connectors/clickhouse (NOT repo-root-relative like the PG_MTLS_* paths). Regenerate certs with volumes/ch-tls/regenerate-certs.sh.

    Native protocol over TLS, exercised by TestClickHouseTLSDirectory. Client certs use cert-manager naming (tls.crt/tls.key). The connector reads the dir as-is, so the path is relative to the test binary's working directory, flow/connectors/clickhouse (NOT repo-root-relative like the PG_MTLS_* paths). Regenerate certs with volumes/ch-tls/regenerate-certs.sh.

  • CI_COCKROACH_DATABASEdefaultdb
  • CI_COCKROACH_HOSThost.docker.internal
  • CI_COCKROACH_PORT26257
  • CI_COCKROACH_USERroot
  • CI_MARIADB_HOSThost.docker.internal
  • CI_MARIADB_PORT3308
  • CI_MARIADB_ROOT_PASSWORD
  • CI_MARIADB_VERSIONmaria-11
  • CI_MONGO_ADMIN_PASSWORD
  • CI_MONGO_ADMIN_URImongodb://host.docker.internal:11017
  • CI_MONGO_ADMIN_USERNAMEadmin
  • CI_MONGO_HOSThost.docker.internal
  • CI_MONGO_PASSWORD
  • CI_MONGO_PORT11017
  • CI_MONGO_URImongodb://host.docker.internal:11017
  • CI_MONGO_USERNAMEcsuser
  • CI_MYSQL_GTID_PORT3306
  • CI_MYSQL_GTID_VERSIONmysql-gtid
  • CI_MYSQL_HOSThost.docker.internal
  • CI_MYSQL_PORT3306
  • CI_MYSQL_POS_PORT3307
  • CI_MYSQL_POS_VERSIONmysql-pos
  • CI_MYSQL_ROOT_PASSWORD
  • CI_MYSQL_VERSIONmysql-gtid
  • CI_SSH_MYSQL_HOSThost.docker.internal
  • DOCKER_GO_DEBUG_FLOW_APISet to 1 for enabling go debugger in dockerfile and Tilt Setup

    Set to 1 for enabling go debugger in dockerfile and Tilt Setup

  • DOCKER_GO_DEBUG_FLOW_SNAPSHOT_WORKER
  • DOCKER_GO_DEBUG_FLOW_WORKER
  • DOCKER_GO_DEBUG_PORT_FLOW_API
  • DOCKER_GO_DEBUG_PORT_FLOW_SNAPSHOT_WORKER
  • DOCKER_GO_DEBUG_PORT_FLOW_WORKER
  • ENABLE_OTEL_METRICSfalseOTel metrics export from the PeerDB flow services. Opt-in in local envs to avoid clashes with local integration environments.

    OTel metrics export from the PeerDB flow services. Opt-in in local envs to avoid clashes with local integration environments.

  • FLOW_API_HTTP_PORT
  • FLOW_API_PORT
  • FLOW_TESTS_RDS_IAM_AUTH_SKIPtrue
  • MINIO_CONSOLE_PORT
  • MINIO_PORT
  • MINIO_ROOT_PASSWORD
  • MINIO_ROOT_USER_peerdb_minioadmin
  • PEERBD_UI_PORT
  • PEERDB_CATALOG_DATABASEpostgres
  • PEERDB_CATALOG_HOSThost.docker.internal
  • PEERDB_CATALOG_PASSWORD
  • PEERDB_CATALOG_PORT9901
  • PEERDB_CATALOG_USERpostgres
  • PEERDB_CLICKHOUSE_AWS_S3_BUCKET_NAMEpeerdb
  • PEERDB_CLICKHOUSE_TLS_CERT_DIR../../../volumes/ch-tls
  • PEERDB_CLICKHOUSE_TLS_PORT11440
  • PEERDB_GCP_CLUSTER_LOCATION
  • PEERDB_GCP_CLUSTER_NAME
  • PEERDB_GCP_PROJECT_ID
  • PEERDB_GCP_WORKLOAD_IDENTITY_TARGET_SERVICE_ACCOUNTGCP workload identity deployment settings. The projected token must use <PEERDB_GCP_PROJECT_ID>.svc.id.goog as its audience. Project and cluster values can be omitted on GKE, where they are read from the metadata server.

    GCP workload identity deployment settings. The projected token must use <PEERDB_GCP_PROJECT_ID>.svc.id.goog as its audience. Project and cluster values can be omitted on GKE, where they are read from the metadata server.

  • PEERDB_GCP_WORKLOAD_IDENTITY_TOKEN_FILE
  • PEERDB_NEXUS_PORT
  • PEERDB_SWITCHBOARD_PORT
  • PG2_DATABASEpostgres
  • PG2_HOSThost.docker.internal
  • PG2_PASSWORD
  • PG2_PORT5437
  • PG2_USERpostgres
  • PG_DATABASEpostgres
  • PG_HOSThost.docker.internal
  • PG_MTLS_CLIENT_CERT_PATHvolumes/pg-tls/client.crt
  • PG_MTLS_CLIENT_KEY_PATH
  • PG_MTLS_ROOT_CA_PATHvolumes/pg-tls/server.crtClient certificate (mutual TLS) auth test, paths relative to repo root

    Client certificate (mutual TLS) auth test, paths relative to repo root

  • PG_PASSWORD
  • PG_PORT5436
  • PG_USERpostgres
  • TEMPORAL_PORT
  • TEMPORAL_UI_PORT

PeerDB releases & version history

FAQ

Does Query Replication support deletes?

No — use CDC if deletes must be synced.

When should I use query replication?

For replicating views, joins or complex queries, tables without primary key/replica identity, or when you cannot have a replication slot in Postgres.

Does PeerDB drop the replication slot once I delete the mirror?

Only slots created by PeerDB (names starting with peerflow_slot_) are dropped; a slot you supplied yourself is kept.

If I change the data type of a column on source, will PeerDB automatically change the data type in destination?

No; the destination keeps the old type and the sync may fail if the change is incompatible.

If I drop a column from a table which is part of a mirror, will PeerDB automatically drop the column in the destination?

No, the column remains and future values will be null.

If I rename a column, will PeerDB automatically rename the column in the destination?

No — the old column stays in the destination and future rows have it as null.

If I add a column to a table which is part of a mirror, will that column automatically be added in destination?

Yes, the new column is synced in the next CDC sync.

If I add a table to my source schema, will PeerDB automatically pick it up and sync it?

No — you must edit the mirror to add newly created tables.

Does pausing a mirror stop replication slot growth?

No, the replication slot keeps growing; only a running mirror that syncs changes makes the slot size drop.

What is pull batch size in PeerDB CDC?

It is the row count PeerDB reads from the WAL into staging files before flushing that batch to the destination.

What is sync interval in PeerDB CDC?

PeerDB stages rows read from the WAL as temporary files and flushes them to the target warehouse once the sync interval elapses; for PeerDB Streams it is not applicable since data is synced as soon as it is read.

If I kick off an initial load + CDC mirror with pre-existing data, will it duplicate the data?

Yes — initial load blindly copies everything, so data already present in the destination can be duplicated. Resync via the UI, or drop target tables and recreate the mirror.

What is initial load in CDC?

If enabled, initial load performs a one-time copy of the existing data in the synced tables before CDC starts streaming newer changes.

What is the difference between CDC and Query Replication?

CDC mirrors replicate table inserts/updates/deletes by reading the Postgres WAL via logical replication, while query replication periodically streams the results of a SQL query to a single destination table and needs no replication slot.

Can I pause a mirror during initial load or setup phase?

No.

More in ETL

Rate this project

Click to rate — no account needed.

0 comments

Posting as guest
Loading comments…