Skip to content

DuckDB alternative — DuckDB vs Skippr ​

DuckDB is MIT embedded analytics. Latest LTS is 2.0.0 "Cinnamon Teal" (21 Oct 2026), supported through 22 Oct 2027. 1.4 LTS ends 17 Nov 2026; 1.5 is supported through March 2027. Iceberg is the iceberg core extension (secondary, best-effort). iceberg_scan on a metadata path is read-only. Writes need an Iceberg REST catalog ATTACH: CREATE/DROP schema and table, INSERT, UPDATE, DELETE, MERGE INTO, ALTER TABLE. DELETE/UPDATE write positional deletes; copy-on-write is not supported. DML on partitioned or sorted tables errors. CDC is not DuckDB. Hosted: MotherDuck Lite is free (10 GB, 10 Pulse hours); Business is 250 USD/month plus usage (Pulse 0.60 USD per CU-hour). This is not Iceberg ∪ WAL you query in one binary.

Skippr is an open Streamhouse you run as one Rust binary. Write skippr.yml (or the same thing in Python), discover, sync. You query live state over Iceberg ∪ WAL, and the history is ordinary Iceberg in your bucket. DuckDB remains exquisite for a one-shot SELECT on files you already have. ELT into a warehouse is one path, not the product.

FeatureSkipprDuckDB
DeploySingle Rust binary, your VPC or on-premIn-process library, CLI, or MotherDuck
SchemaIn-stream evolution, sibling columnsSQL DDL. Iceberg schema after REST ATTACH
StorageOpen Iceberg on Parquet you own.duckdb file, or Iceberg via the extension
CDCLog-based; fails closed if the dest cannot honourNot a CDC product. You load a snapshot
Queryskipprd query on Iceberg ∪ WAL; history in any Iceberg engineDuckDB SQL in-process, or MotherDuck
PricingFree self-hosted engineMIT. MotherDuck Lite free; Business from 250 USD/month.

What DuckDB is good at ​

SQL on a laptop, in a notebook, or in a sidecar, without standing up a warehouse. That is the product. The Iceberg REST ATTACH (and MotherDuck persisted catalogs) is why some lakes get a DuckDB session on files Spark already wrote. If the job is "this SELECT on these Parquet files," DuckDB is the narrower tool, and it is a good one.

Where the job is wider ​

DuckDB is an embedded SQL engine. It is not a Streamhouse. There is no Iceberg ∪ WAL. There is no skipprd query on in-flight lake rows. Iceberg writes need a REST catalog; a metadata-path scan will not take INSERT. CDC still starts in Debezium or skipprd. Skippr will not replace DuckDB for ad-hoc SQL.

The process (or MotherDuck CUs) is the ops. Skippr will not run the DuckDB CLI. skipprd can land a Duckdb dest; that is still Skippr doing ingest.

If the job is "DuckDB we already staff," DuckDB is the narrower tool. If the job is live SQL on Iceberg you run, the embedded engine was never that.

Getting started ​

Install skipprd from the install guide, or pip install skippr. The three tabs write the same skippr.yml. Then discover, sync, and query.

yaml
skippr:
  workspace: analytics
  skipprd_el_storage_mode: local

pipelines:
  orders:
    data_source: data_sources.app_db
    data_sink: data_sinks.lake

data_sources:
  app_db:
    Postgres:
      host: db.internal
      user: skippr_reader
      password: ${APP_DB_PASSWORD}
      database: app
      tables: [orders, customers]
      cdc_mode: snapshot_then_cdc

data_sinks:
  lake:
    AthenaIceberg:
      warehouse: s3://my-iceberg-warehouse/
      glue_database_name: analytics
      athena_workgroup_name: primary
      athena_results_s3_bucket: my-athena-results
      region: us-east-1
    schema_sink: schema_sinks.lake_schema

schema_sinks:
  lake_schema:
    AthenaIceberg:
      warehouse: s3://my-iceberg-warehouse/
      glue_database_name: analytics
      athena_workgroup_name: primary
      athena_results_s3_bucket: my-athena-results
      region: us-east-1
bash
skipprd --workspace analytics --storage-mode local connect data-source postgres \
  --pipeline orders \
  --name app_db \
  --host db.internal \
  --user skippr_reader \
  --password '${APP_DB_PASSWORD}' \
  --database app \
  --tables orders \
  --tables customers \
  --cdc-mode snapshot_then_cdc

skipprd connect data-sink athenaiceberg \
  --pipeline orders \
  --name lake \
  --warehouse s3://my-iceberg-warehouse/ \
  --glue-database-name analytics \
  --athena-workgroup-name primary \
  --athena-results-s3-bucket my-athena-results \
  --region us-east-1

skipprd connect schema-sink athenaiceberg \
  --pipeline orders \
  --name lake_schema
python
from skippr import (
    Config,
    DataSinkAthenaIceberg,
    DataSourcePostgres,
    DataSourcePostgresSourceCdcMode,
    EnvRef,
    LocalStorage,
    Pipeline,
)

cfg = Config().workspace("analytics").storage(LocalStorage())

app_db = cfg.data_source(
    "app_db",
    DataSourcePostgres(
        host="db.internal",
        user="skippr_reader",
        password=EnvRef("APP_DB_PASSWORD"),
        database="app",
        tables=["orders", "customers"],
        cdc_mode=DataSourcePostgresSourceCdcMode.SNAPSHOTTHENCDC,
    ),
)

lake = cfg.data_sink(
    "lake",
    DataSinkAthenaIceberg(
        warehouse="s3://my-iceberg-warehouse/",
        glue_database_name="analytics",
        athena_workgroup_name="primary",
        athena_results_s3_bucket="my-athena-results",
        region="us-east-1",
    ),
    schema_sink="lake_schema",
)

cfg.pipeline("orders", Pipeline(data_source=app_db, data_sink=lake))
cfg.save("skippr.yml")
bash
export APP_DB_PASSWORD='your-postgres-password'
skipprd discover --pipeline orders
skipprd sync --pipeline orders --once
skipprd query "SELECT count(*) FROM analytics.orders"

Which to choose ​

Choose DuckDB if you want in-process SQL, and Iceberg as a REST-catalog ATTACH (or a read-only scan) is enough.

Choose Skippr if you want one binary, live SQL on Iceberg ∪ WAL, and files that stay yours. Skippr will not replace DuckDB.

Install from Install. Connector and query reference live in Developer Docs. For optional onboarding in your VPC, Enterprise Jumpstart or Contact.