Now available
Meet ingestr v1.
Ingestion, rebuilt for speed.
- Open source
- ⚡12x faster
- ★3.5K stars
// why.ingestr-v1
Built to be the fastest path from source to destination.
ingestr v1 keeps everything teams already love about ingestr: a single binary, declarative sources and destinations, incremental and full-refresh modes, and a CLI you can drop into any pipeline. What's new is what happens between the source and the destination.
- Up to 12x faster end-to-end
- Across five common source-destination pairs (duckdb, postgres, mysql in any direction), ingestr v1 is the fastest tool we measured in every single one.
- Drop-in upgrade from v0
- Same command surface, same connectors, same place in your pipelines. If your jobs run on ingestr today, they'll run on v1 tomorrow.
- Open source first
- ingestr is open source alongside the Bruin CLI. Bruin Cloud adds orchestration, governance, and observability on top.
// benchmarks.full-suite
Fastest in every scenario we ran.
Each row is the mean of 5 runs loading a 1M-row table from source to destination on identical hardware. v0 is included for reference.
See the full benchmark suite| Scenario | ingestr v1 | sling | dlt | ingestr v0 |
|---|---|---|---|---|
| duckdb → duckdb | 4.34s | 48.15s | 18.56s | 13.66s |
| duckdb → postgres | 4.18s | 48.04s | 33.93s | 31.43s |
| mysql → postgres | 4.98s | 28.18s | 53.08s | 52.38s |
| postgres → duckdb | 6.08s | 39.11s | 26.79s | 21.42s |
| postgres → postgres | 6.14s | 20.97s | 44.44s | 41.11s |
// strategies
Six ways to load your data.
Pick the incremental strategy that fits the table you're moving. Two are new in v1.
replaceDefault. Swap the destination table for the source.- Download the source and overwrite the destination. v1 uses double buffering under the hood to keep transaction times short on large loads.
- No keys required
appendAdd new rows only, using an incremental key.- Filter the source by an incremental key (e.g. `updated_at`) and append rows newer than the last run. Ideal for event streams and audit logs where history matters.
- Requires `incremental_key`
mergeUpsert by primary key. Update existing rows, insert new ones.- Match rows by `primary_key`, update changed values, and insert anything new. The standard CDC pattern for evolving entities.
- Requires `primary_key` + `incremental_key`
delete+insertDelete the matching window, then insert fresh.- Delete destination rows that fall in the incremental window and re-insert from source. The right call for late-arriving data or backfills over a fixed range.
- Requires `incremental_key`
truncate+insertNew in v1. Empty the table and load fresh in one go.- Truncate the destination table and load the new rows in a single operation. Faster than full replace when you do not need the staging dance, and safer than a manual TRUNCATE + INSERT.
- No keys required
scd2New in v1. Slowly Changing Dimension Type 2 with row history.- Keep a full history per primary key with `valid_from` / `valid_to` columns, so you can query the state of any record at any point in time. The right pattern for evolving dimensions like customers, products, or accounts.
- Requires `primary_key`
// get.started
One binary. One command.
Install ingestr v1 and move your first table in under a minute.
$ curl -LsSf https://getbruin.com/install/ingestr | sh $ ingestr ingest \ --source-uri "postgres://user:***@host/db" \ --dest-uri "bigquery://" \ --source-table public.orders → loaded 1,000,000 rows in 2.86s