ingestr benchmark results

Duration vs. rows

Median time per tool across data sizes — log duration scale, lower is faster.

ingestr v1ingestr v0SlingdltAirbyteSpark
1K10K100K1M10M1s10s100s
Rows
Source
Dest

1K rows

Postgres → Postgres

ingestr v1
0.19s
Sling
0.45s2.4×
dlt
1.56s8.2×
ingestr v0
1.94s10.1×
Spark
6.21s32.4×
Airbyte
14.21s74.2×

Postgres → DuckDB

ingestr v1
0.28s
Sling
1.60s5.8×
dlt
1.71s6.2×
ingestr v0
1.99s7.2×
Spark
7.70s27.8×

DuckDB → DuckDB

ingestr v1
0.25s
Sling
1.77s7.2×
dlt
1.93s7.9×
ingestr v0
2.12s8.6×
Spark
7.42s30.3×

DuckDB → Postgres

ingestr v1
0.25s
Sling
0.63s2.5×
dlt
1.83s7.2×
ingestr v0
1.98s7.8×
Spark
6.98s27.6×

MySQL → Postgres

ingestr v1
0.19s
Sling
0.54s2.9×
dlt
1.49s7.9×
ingestr v0
1.86s9.9×
Spark
6.73s35.7×
Airbyte
18.35s97.3×

MongoDB → Postgres

ingestr v1
0.29s
Sling
0.69s2.4×
dlt
2.20s7.7×
ingestr v0
2.59s9.1×
Airbyte
13.83s48.4×

MongoDB → DuckDB

ingestr v1
0.41s
dlt
1.70s4.1×
Sling
1.89s4.5×
ingestr v0
2.63s6.3×

DuckDB → Snowflake

ingestr v1
3.71s
Sling
5.18s1.4×
dlt
7.97s2.2×

Postgres → SQL Server

ingestr v1
0.22s
Sling
1.10s5.1×
dlt
1.88s8.6×
ingestr v0
2.22s10.2×
Spark
6.62s30.4×

MySQL → SQL Server

ingestr v1
1.08s
Sling
1.16s1.1×
dlt
1.83s1.7×
ingestr v0
2.23s2.1×
Spark
6.71s6.2×

MongoDB → SQL Server

ingestr v1
1.63s
Sling
1.80s1.1×
dlt
2.69s1.6×

DuckDB → SQL Server

ingestr v1
0.28s
Sling
1.27s4.5×
dlt
2.08s7.4×
ingestr v0
2.36s8.3×
Spark
6.89s24.3×

10K rows

Postgres → Postgres

ingestr v1
0.37s
Sling
0.66s1.8×
dlt
1.93s5.2×
ingestr v0
2.24s6.0×
Spark
6.40s17.2×
Airbyte
15.85s42.7×

Postgres → DuckDB

ingestr v1
0.40s
dlt
1.90s4.7×
Sling
1.98s4.9×
ingestr v0
2.21s5.5×
Spark
11.27s28.0×

DuckDB → DuckDB

ingestr v1
0.38s
dlt
2.04s5.3×
Sling
2.26s5.9×
ingestr v0
2.26s5.9×
Spark
10.87s28.2×

DuckDB → Postgres

ingestr v1
0.37s
Sling
1.09s3.0×
dlt
2.11s5.7×
ingestr v0
2.28s6.2×
Spark
6.95s18.9×

MySQL → Postgres

ingestr v1
0.37s
Sling
0.81s2.2×
dlt
1.90s5.1×
ingestr v0
2.33s6.2×
Spark
6.63s17.7×
Airbyte
19.83s53.1×

MongoDB → Postgres

ingestr v1
0.97s
Sling
1.77s1.8×
dlt
5.36s5.5×
ingestr v0
5.64s5.8×
Airbyte
15.37s15.9×

MongoDB → DuckDB

ingestr v1
1.07s
dlt
2.24s2.1×
Sling
3.17s3.0×
ingestr v0
4.59s4.3×

Postgres → SQL Server

ingestr v1
0.50s
dlt
5.03s10.0×
ingestr v0
5.43s10.8×
Sling
6.35s12.6×
Spark
6.83s13.6×

MySQL → SQL Server

ingestr v1
3.00s
dlt
4.87s1.6×
ingestr v0
5.38s1.8×
Sling
6.47s2.2×
Spark
6.67s2.2×

MongoDB → SQL Server

ingestr v1
3.82s
dlt
10.83s2.8×
Sling
12.16s3.2×

DuckDB → SQL Server

ingestr v1
0.51s
dlt
5.20s10.3×
ingestr v0
5.42s10.7×
Sling
6.76s13.4×
Spark
6.88s13.6×

100K rows

Postgres → Postgres

ingestr v1
1.11s
Sling
2.51s2.3×
dlt
5.18s4.7×
ingestr v0
5.71s5.1×
Spark
7.18s6.5×
Airbyte
36.40s32.8×

Postgres → DuckDB

ingestr v1
1.27s
dlt
3.75s3.0×
ingestr v0
4.17s3.3×
Sling
5.42s4.3×
Spark
46.04s36.2×

DuckDB → DuckDB

ingestr v1
1.15s
dlt
3.13s2.7×
ingestr v0
3.34s2.9×
Sling
6.57s5.7×
Spark
45.47s39.5×

DuckDB → Postgres

ingestr v1
0.94s
dlt
4.49s4.8×
ingestr v0
4.72s5.0×
Sling
5.40s5.7×
Spark
7.53s8.0×

MySQL → Postgres

ingestr v1
1.45s
Sling
3.29s2.3×
dlt
5.26s3.6×
ingestr v0
6.64s4.6×
Spark
7.25s5.0×
Airbyte
39.56s27.3×

MongoDB → Postgres

ingestr v1
6.27s
Sling
10.09s1.6×
Airbyte
31.46s5.0×
ingestr v0
36.30s5.8×
dlt
39.65s6.3×

MongoDB → DuckDB

ingestr v1
6.18s
dlt
6.81s1.1×
Sling
13.05s2.1×
ingestr v0
28.29s4.6×

Postgres → Snowflake

ingestr v1
5.71s
Sling
8.20s1.4×
dlt
10.73s1.9×
ingestr v0
11.87s2.1×

MySQL → Snowflake

ingestr v1
4.24s
Sling
9.11s2.1×
dlt
11.52s2.7×
ingestr v0
12.17s2.9×

MongoDB → Snowflake

ingestr v1
5.58s
Sling
12.58s2.3×
dlt
18.48s3.3×
ingestr v0
18.79s3.4×

DuckDB → Snowflake

ingestr v1
4.19s
dlt
10.10s2.4×
Sling
10.70s2.6×
ingestr v0
10.84s2.6×

Postgres → SQL Server

ingestr v1
1.45s
Spark
8.85s6.1×
dlt
37.91s26.2×
ingestr v0
37.92s26.2×
Sling
54.86s37.9×

MySQL → SQL Server

ingestr v1
3.54s
Spark
8.62s2.4×
dlt
37.50s10.6×
ingestr v0
39.33s11.1×
Sling
48.38s13.7×

MongoDB → SQL Server

ingestr v1
7.60s
dlt
92.36s12.2×
Sling
112.8s14.8×

DuckDB → SQL Server

ingestr v1
1.19s
Spark
9.06s7.6×
ingestr v0
37.38s31.4×
dlt
37.52s31.5×
Sling
50.44s42.3×

1M rows

Postgres → Postgres

ingestr v1
6.90s
Spark
12.40s1.8×
Sling
20.83s3.0×
dlt
36.27s5.3×
ingestr v0
41.09s6.0×
Airbyte
240.6s34.9×

Postgres → DuckDB

ingestr v1
8.20s
dlt
18.91s2.3×
ingestr v0
21.25s2.6×
Sling
38.99s4.8×
Spark
386.1s47.1×

DuckDB → DuckDB

ingestr v1
7.63s
dlt
12.38s1.6×
ingestr v0
12.45s1.6×
Sling
47.61s6.2×
Spark
384.7s50.4×

DuckDB → Postgres

ingestr v1
4.98s
Spark
13.35s2.7×
dlt
27.75s5.6×
ingestr v0
30.48s6.1×
Sling
47.15s9.5×

MySQL → Postgres

ingestr v1
11.43s
Spark
13.04s1.1×
Sling
27.60s2.4×
dlt
38.32s3.4×
ingestr v0
52.59s4.6×
Airbyte
239.2s20.9×

MongoDB → Postgres

ingestr v1
59.59s
Sling
90.69s1.5×
Airbyte
183.0s3.1×
ingestr v0
319.0s5.4×
dlt
382.5s6.4×

MongoDB → DuckDB

dlt
47.94s
ingestr v1
54.46s1.1×
Sling
110.6s2.3×
ingestr v0
261.6s5.5×

Postgres → Snowflake

ingestr v1
11.59s
dlt
30.62s2.6×
ingestr v0
31.78s2.7×
Sling
32.70s2.8×

MySQL → Snowflake

ingestr v1
10.18s
dlt
38.23s3.8×
Sling
40.85s4.0×
ingestr v0
42.54s4.2×

MongoDB → Snowflake

ingestr v1
23.48s
Sling
70.85s3.0×
ingestr v0
93.07s4.0×
dlt
101.4s4.3×

DuckDB → Snowflake

ingestr v1
8.88s
ingestr v0
22.69s2.6×
dlt
23.04s2.6×
Sling
58.59s6.6×

Postgres → SQL Server

ingestr v1
8.58s
Spark
21.84s2.5×
ingestr v0
91.88s10.7×
dlt
377.8s44.0×
Sling
629.9s73.4×

MySQL → SQL Server

ingestr v1
13.57s
Spark
26.98s2.0×
ingestr v0
104.3s7.7×
dlt
372.6s27.5×
Sling
430.9s31.7×

MongoDB → SQL Server

ingestr v1
49.61s
dlt
930.9s18.8×
Sling
1,642.80s33.1×

DuckDB → SQL Server

ingestr v1
5.72s
Spark
25.19s4.4×
ingestr v0
81.45s14.2×
dlt
372.6s65.1×
Sling
453.1s79.1×

10M rows

Postgres → Postgres

ingestr v1
64.50s
Spark
65.34s1.0×
Sling
205.5s3.2×
dlt
344.2s5.3×
ingestr v0
384.0s6.0×

Postgres → DuckDB

ingestr v1
73.26s
dlt
158.1s2.2×
ingestr v0
191.5s2.6×
Sling
373.4s5.1×
Spark
3,887.86s53.1×

DuckDB → DuckDB

ingestr v1
71.97s
dlt
92.74s1.3×
ingestr v0
102.6s1.4×
Sling
454.9s6.3×
Spark
3,853.76s53.5×

DuckDB → Postgres

ingestr v1
45.21s
Spark
70.56s1.6×
dlt
257.6s5.7×
ingestr v0
279.3s6.2×
Sling
466.5s10.3×

MySQL → Postgres

Spark
70.70s
ingestr v1
111.4s1.6×
Sling
274.1s3.9×
dlt
368.8s5.2×
ingestr v0
513.5s7.3×

MongoDB → Postgres

ingestr v1
597.4s
Sling
885.8s1.5×
ingestr v0
3,204.22s5.4×
dlt
4,043.57s6.8×

MongoDB → DuckDB

dlt
451.1s
ingestr v1
529.5s1.2×
Sling
1,086.43s2.4×
ingestr v0
2,624.34s5.8×

Postgres → SQL Server

ingestr v1
80.62s
Spark
216.1s2.7×
ingestr v0
738.9s9.2×
dlt
3,718.56s46.1×

MySQL → SQL Server

ingestr v1
93.58s
Spark
210.6s2.3×
ingestr v0
877.9s9.4×
dlt
3,693.68s39.5×

DuckDB → SQL Server

ingestr v1
53.16s
Spark
182.6s3.4×
ingestr v0
629.2s11.8×
dlt
3,637.23s68.4×

Methodology

Each tool runs the same source-to-destination copy for a fixed number of rows. Times are wall-clock, measured with hyperfine, with a warmup run discarded and the mean of the timed runs reported. The multiplier shows how many times slower a tool is than the fastest one in that chart.

All tools were run on the same machine with identical source data and warehouse targets. Numbers are reproducible from the raw benchmark dumps — see the benchmark code. Runs are refreshed as engines change — the most recent run wins for each source / destination / row-count combination.

Benchmarks were executed on a Hetzner Cloud CCX63 instance (48 dedicated AMD EPYC-Milan vCPUs, 192 GB RAM, NVMe SSD), running Ubuntu 24.04.4 LTS.