Your Postgres data in ClickHouse, kept in sync, with proof both sides agree.
chlift takes a snapshot of your Postgres tables into ClickHouse, keeps them current with live change data capture, and checks that both sides hold the same data. It is for teams that run their own Postgres and need analytics without hurting it.
chlift is free and MIT licensed. The only paid offers are installation, support and training: [email protected]
What we measured
One recorded run on 2026-10-03, from empty nodes and an empty ClickHouse. Every command is on a terminal recording with real timing, and nothing was typed or edited by hand. Setup: one shared 8-core Linux server (other workloads running too); two ClickHouse 26.3 replicas plus Keeper in containers capped at 1.5 GB RAM each; PeerDB on the same server; Postgres 16 with default settings in 768 MB; synthetic data from chlift seed (about 14M rows, 2.6 GB). This is not a vendor benchmark.
Install from empty nodes
chlift install set up 3 hosts plus PeerDB, and all checks passed. The hosts are containers on one server; packages come from the official ClickHouse repo.
14,000,000 rows into both replicas
8M + 4M + 2M rows copied by migrate start to both ClickHouse replicas. An upper bound: status was polled every 15 s.
Equal after live changes
After 50,000 inserts, 1,000 updates and 5,000 deletes over live CDC, migrate check --checksums found every day equal in Postgres and on both replicas (8,047,000 / 4,000,000 / 1,998,000 live rows). The checksums compare counts, ids, integers, timestamps and text lengths per primary-key range. JSON and float columns are not compared.
Cutover, end to end
migrate cutover waits for PeerDB to confirm the watermark, then requires equal day counts and 0 of 64 differing checksum buckets on every replica for all 3 tables before it stops the mirror. ClickHouse keeps the data, and check still matches afterwards. Recorded with a later build that also compares rows below Postgres's lowest id.
Query time
14× to 163× faster than Postgres while PeerDB is still replicating (ClickHouse queries use FINAL). 31× to 308× faster without FINAL, which is what you get after cutover or for append-only tables.
| Query (median of 5 runs, ms) | Postgres | ClickHouse FINAL | ClickHouse |
|---|---|---|---|
| Daily active users, last 30 days | 5,388 | 266 | 107 |
| Events per kind per week, 6 months | 21,950 | 1,600 | 710 |
| Top 10 accounts by events, last 7 days | 5,740 | 159 | 57 |
| p95 latency per endpoint, last 30 days | 23,994 | 147 | 78 |
- Median of 5 runs per query, all taken in one invocation. The raw samples and a script that recomputes this table are published with the recording.
- Postgres time is measured from the client and includes sending the result; ClickHouse time is the server's own elapsed time.
- Postgres runs with default settings in 768 MB. A tuned Postgres on bigger hardware would narrow the gap. Your data and queries are the real test.
Two silent data bugs, reproduced on camera, and what chlift does about them
Replication that fails loudly is annoying. Replication that quietly gives you wrong numbers is worse. In the recording we removed chlift's own requirement on purpose to show what happens without it. Nothing reported an error until migrate check failed.
Deleted rows that stay alive
Without REPLICA IDENTITY FULL, after 4,000 updates and 1,000 deletes Postgres had 19,000 rows and both ClickHouse replicas 20,000.
Long text that arrives empty
In the same run, long texts reached ClickHouse empty. In one checksum bucket: 120,124 bytes of text in Postgres, 1,335 in ClickHouse.
What chlift does
migrate plan requires REPLICA IDENTITY FULL on every table it moves and gives you the ALTER TABLE to run before anything is copied. With the requirement in place, the same kind of changes gave 18,000 = 18,000 = 18,000 rows and 0 of 64 differing buckets.
Install
chlift v0.1.0-preview is one binary for Linux (amd64 or arm64). The script downloads it, checks it against the release's SHA256SUMS and against the checksums written into the script, and installs it only if both match.
curl -fsSL https://chlift.deemwar.com/install.sh | sh
Prefer to read it first: install.sh. Or download by hand: linux-amd64 · linux-arm64 · SHA256SUMS, then run sha256sum -c SHA256SUMS --ignore-missing.
Then
chlift init --cluster prod \
--host a=10.0.0.1:clickhouse,keeper --host b=10.0.0.2:clickhouse,keeper --host c=10.0.0.3:keeper,peerdb
chlift plan # probes every host; changes nothing
chlift install # ClickHouse replicas, Keeper, PeerDB over SSH
chlift verify
export CHLIFT_PG_DSN='postgres://USER:YOUR_PASSWORD_HERE@db:5432/app'
chlift migrate plan # writes chlift-migration.yaml for you to review
chlift migrate start --apply-postgres
chlift migrate check --checksums # every day and every key range, on every replica
chlift migrate cutover
- Hosts: Debian/Ubuntu (tested) or RHEL-family (written, not yet tested), SSH key access, Docker with compose v2 on the PeerDB host.
- Postgres 12+ with
wal_level=logical. Managed Postgres (RDS/Aurora) is not tested yet. - Preview: replicated targets stay preview until the fault soak passes.
What works today, and what doesn't yet
Recorded end to end
Install from empty nodes; migrate plan, start, status, check with checksums; live CDC; cutover; the bench. The recording also turned up four bugs, all fixed in this release.
Still preview
A replication reliability run under injected faults is still in progress. Until it passes, replicated targets stay marked preview. We have not reproduced the known PeerDB row-loss issue with a Distributed target; chlift avoids that layout.
Install today
Release binaries for Linux amd64 and arm64, checked against SHA256SUMS: install. Or deemwar installs it with you: tell us about your setup below.
Talk to us
Tell us about your Postgres and what you want in ClickHouse. A person replies, usually within a working day. Or email [email protected].