Synchronoid is in private beta. New workspaces open in small batches every few weeks. Join the waitlist →

PostgreSQL

Relational database. Incremental and full-table reads.

Source Destination GA

Overview

What the PostgreSQL connector does

The PostgreSQL connector reads tables and query results from any PostgreSQL 12+ database, including managed services, and writes published tables back when you need a copy next to your application.

Reads are incremental. Synchronoid stores a cursor per table (a timestamp or an increasing id), fetches only new and changed rows, and keeps the untouched rows in the raw layer so you can replay any run.

Capabilities

  • Full-table and incremental reads with a timestamp or id cursor
  • Custom SQL queries as sources, with bound parameters
  • Optional logical replication reader for change data capture (beta)
  • Upserts into destination tables, keyed on your primary key
  • Per-source connection pool and request budget
  • Provenance on every value: table, query, fetch time and run id
  • TLS required, with private networking on Enterprise
Configuration

Set it up in minutes

Describe the connection in synchronoid.yaml or in Python. Both produce the same source, and credentials always come from secrets.

synchronoid.yaml
sources:
  orders_db:
    connector: postgresql
    host: db.internal.example.com
    port: 5432
    database: shop
    user: synchronoid_reader
    password: ${secret:PG_PASSWORD}
    sslmode: require
    tables:
      - name: public.orders
        cursor: updated_at
        key: id
    rate_limit:
      per_minute: 600
pipelines/postgresql.py
import synchronoid as sy

orders_db = sy.Source(
    name="orders_db",
    connector="postgresql",
    host="db.internal.example.com",
    database="shop",
    user="synchronoid_reader",
    password=sy.Secret("PG_PASSWORD"),
    tables=[{"name": "public.orders", "cursor": "updated_at", "key": "id"}],
    rate_limit=sy.RateLimit(per_minute=600),
)

@sy.asset(layer="staged", source=orders_db)
def orders(ctx, raw):
    for row in raw.records():
        yield {"order_id": row["id"], "total": row["total"]}
Requirements

Permissions and prerequisites

ItemRequirement
PostgreSQL version12 or newer
NetworkReachable from Synchronoid egress IPs, or via private networking (Enterprise)
Database roleCONNECT on the database, USAGE on the schema, SELECT on the tables you sync
For destinationsINSERT and UPDATE on the target tables
For change data captureREPLICATION attribute and wal_level = logical
EncryptionTLS 1.2 or newer
Tip. Create a dedicated, least-privilege account for Synchronoid. You can then revoke access in one step if you ever need to.
Limitations

Good to know before you start

  • Tables without a stable cursor column need a full read on every run.
  • Hard deletes are only detected with change data capture or a periodic full read.
  • Logical replication is in beta and supports one slot per source.
  • Very wide rows (over 10 MB) are rejected and reported in the run log.

Need something we don’t cover?

Tell us what you are missing. Feedback from beta users decides what we build next, and you can follow progress on the roadmap.

Request a feature →

Connect PostgreSQL to Synchronoid

Synchronoid is in private beta. Tell us about your data and we will get you a workspace.