Syncle

Overview

Syncle keeps databases in sync, live and across engines, without a data platform in between. Most change-data-capture tools hand you a stream and stop there: Debezium gives you a Kafka topic, and you still run the broker and build the thing that writes to your database. Syncle writes to your database. You connect databases, draw a bridge from a source to one or more destinations, and rows move across it — once, on a schedule, or the moment they change.

Five engines are supported — PostgreSQL, MySQL, SQLite, MongoDB and Redis — and any of them can sit on either end of a bridge. A relational table can feed a document store, a document collection can feed a key-value cache, and an HTTP endpoint can stand in for a database on the receiving side. Everything runs on your own machine, under the MIT licence, and the web interface is how you use it day to day.

What gets installed

Four containers: the web interface, the API, and a PostgreSQL and Redis instance of its own. The PostgreSQL holds Syncle's metadata (connections, bridges, job history) and the Redis backs the job queue. Your databases stay wherever they already are; Syncle connects out to them.

Three terms come up throughout these pages:

  • A bridge is the saved sync path — the source table or query, the column mapping, the destinations, and the trigger.
  • A job is one execution of a bridge.
  • A delivery is one row (or batch) delivered within a job — the unit the live timeline shows, and the unit you can retry or skip.

Installing

Docker with Compose v2 and curl are the only requirements. One command downloads the newest release, starts it, and opens the interface:

curl -fsSL https://syncle.dev/install | sh -s -- up

The installation page explains what the script actually does, the manual Docker Compose route if you would rather not pipe curl into sh, and how updating and uninstalling work.

What people use it for

Each of these is one bridge, configured differently.

  • Migrate to a different engine (Replay + CDC) — Backfill every row with a replay job, then leave a CDC bridge running so old and new stay identical while you cut traffic over. Nothing has to go offline for it.
  • Keep a reporting copy up to date (CDC) — Keep a second database in step for reporting or exports, so analysts are not querying production and you are not paying for a managed replica.
  • Warm a cache from the source of truth (CDC) — Project rows into Redis as they change, keyed however you like. Deletes remove the key rather than leaving it to expire.
  • Give search its own copy (Watch) — Sync the columns a search index needs into MongoDB, reshaped on the way across, without bolting write hooks onto the application.
  • Split a monolith database (CDC) — Carve a table out to a new service database and keep both in sync while callers move over one at a time, instead of coordinating a single risky switch.
  • Push rows to a service, not a database (Any) — Send each change to an HTTP endpoint with a payload you design, with retries and backoff, when the thing to feed is an API rather than another store.

Where to go next

  • Installation — The one-command install, the syncle launcher, the manual Docker Compose route, ports, and updating or removing an install.
  • Quickstart — From syncle up to a first working bridge: the setup token, connecting a database, and reading the delivery timeline.
  • How bridges work — Bridges, jobs and deliveries; the three trigger modes; delivery guarantees; destinations; and the tuning knobs.
  • CDC setup — Per-engine prerequisites for real-time change data capture, what Syncle provisions for you, and where each engine falls short.
  • Database workbench — Browsing and editing tables, the query editor, schema and ER diagrams, DDL, backup and restore, and SSH tunnels.
  • Configuration — Every environment variable with its default, the in-app settings, and where the config files live.
  • HTTP API — The REST API under /api: authentication, response envelopes, and every endpoint for connections, bridges and jobs.
  • Troubleshooting — The failures that come up most: CDC that never fires, watch bridges that deliver nothing, connections that will not test, and rows that fail.
  • Self-hosting & security — Running Syncle beyond localhost: accounts and sessions, encryption, what to back up, and a troubleshooting list.

Common questions

Which databases can Syncle sync between?

PostgreSQL, MySQL, SQLite, MongoDB and Redis, in any combination. A relational source can write into a document or key-value store and back again, with values translated to fit the target. HTTP endpoints work as a destination too, for when you are feeding a service rather than a database.

Does it sync in real time, or on a schedule?

You choose per bridge. CDC reads the database change log directly — Postgres logical replication, MySQL binlog, MongoDB change streams, Redis keyspace notifications — so changes arrive without polling. Watch polls a cursor instead, which works on every engine, including SQLite, which has no change log to read. The cursor can be an auto-increment id, a timestamp column, or a diff of the primary keys, so a table with no updated_at column can still be watched. Replay is a one-shot pass, for the initial backfill.

Can it duplicate or lose rows?

Writes are idempotent upserts keyed by the columns you pick, so a replay, a retry or a redelivery rewrites the same row rather than adding another. Jobs record their cursor as they go, so an interrupted run resumes where it stopped. What each trigger can see differs, though: a CDC bridge propagates inserts, updates and deletes, while a watch bridge polls, so it sees new rows (and updates, on a timestamp cursor) but never deletes. And Redis CDC rides keyspace notifications, which are not durable — if Syncle is down when a Redis key changes, that event is gone.

What do I need installed to run it?

Docker with Compose v2, and curl for the installer. That is what the install script checks for before it will run. Node, PostgreSQL and Redis all run in containers, and the application image is pulled prebuilt, so nothing is compiled on your machine.

Is Syncle free, and is my data sent anywhere?

It is MIT licensed and entirely self-hosted. It runs on your own machine against your own databases; there is no account and no third-party service in the data path. Stored connection credentials are encrypted with AES-256-GCM under a key that never leaves your install.

How is it different from Airbyte or Debezium?

Mainly in where the rows end up. Debezium writes change events into a Kafka topic, so you run the broker and you still build or configure the thing that consumes it and writes to your destination. Syncle writes to the destination itself. Airbyte expects a platform deployment — Kubernetes, or Docker Compose at smaller scale — and a team to operate it. Both are built for organisations running pipelines as a discipline, and if that is you, they are the better fit. Syncle is one command, four containers and a web interface, for one operator who wants two databases to match without standing up a data platform first.

How much can it move?

A million rows, cross-engine, in well under a minute on a laptop, each arriving exactly once. Rather than quote a figure here that goes stale the moment the code moves, the measured results live on the benchmarks page, along with the machine they were taken on and the runner that produced them. The pattern behind the numbers: round trips set the pace, not the database, which is why work is sent in batches rather than a row at a time. There is no published benchmark against a managed or remote database yet, and latency dominates there.

What happens if the destination goes down?

By default the reader stops advancing, which means the source keeps its change log until the destination is back. That is safe, but on PostgreSQL a long outage leaves WAL accumulating on the source. Turning on the optional spool changes that: changes are written to a durable Redis stream first and the source is acknowledged immediately, so its log advances at the speed of Redis rather than the destination. The spool is bounded, so a stalled destination throttles the reader instead of growing without limit. It is off by default, because while a change sits in the spool Redis holds the only copy of it, and that trade-off should be a deliberate one.

About these docs

These pages document Syncle 1.0. Every command, endpoint and default in them was taken from the source repository rather than from memory. Where a feature has a limitation — SQLite has no change log to capture, Redis change events are not durable — it is written down next to the feature itself. If you find a place where the docs and the software disagree, that is a bug: please report it.