ClickHouse

Native insert. Merge uses `ReplacingMergeTree` keyed by `dedup_sort`.

Every destination receives the same layout; see the tables Ingest creates.

Setup

Ingest connects over the HTTPS interface and needs a user that can create and write tables in one database.

Create a user

CREATE USER ingest IDENTIFIED BY 'a-long-random-password';
GRANT CREATE DATABASE, CREATE TABLE, INSERT, SELECT, ALTER, DROP ON your_db.* TO ingest;

Each of those is used: CREATE TABLE per resource, INSERT for rows, SELECT to read back the _ingest_* state tables, ALTER when your source adds a column, and DROP for atomic replace, which loads into a new table and swaps, so a reader never sees a half-written one. Omitting DROP leaves replace-mode resources failing while append works, which is a confusing place to end up.

On ClickHouse Cloud the user you were given at signup already holds these; a dedicated user is still worth creating so revoking Ingest does not mean rotating your own login.

Reachable, and on the HTTPS port

Ingest egresses from a public address and has no route into your network. Use the HTTPS endpoint (8443 on Cloud, 8123 unencrypted for self-hosted; prefer TLS), and allow Ingest's egress address in any IP access list. ClickHouse Cloud denies all addresses by default, so a new service refuses the connection test until that list is edited.

What to paste

HTTP URL (the full https://host:8443) and the Password.

Then test it

Test connection creates a scratch schema and a table, writes a few rows through the same load path a real run uses, reads them back to check the count is exactly right, round-trips pipeline state, and drops the lot. Creating a database and writing to it are separate grants, so both are exercised.

Staging

needs_staging: none. Staging always happens in the destination's own cloud and region; data does not take a detour through ours.

Conformance

Every adapter passes the same suite before it ships: create a table with every canonical type, append 100k rows, atomic replace, merge (latest dedup_sort wins; child tables delete-then-insert by root id), schema evolution, NULL-key rejection, package replay without duplicates, state and schema round-trip, row-count read-back, identifier edge cases, double-underscored table names (__quarantine, child tables), and rollback on a mid-load failure.