Zum Hauptinhalt springen
Neoinsights

So baust du ein Data Lakehouse auf AWS für unter 200 $/Monat mit DuckLake

Wie du ein lauffähiges Data Lakehouse auf AWS für unter 200 $ pro Monat baust, mit DuckLake, DuckDB, Postgres und einer Terraform-Referenzimplementierung.

Mory KabaMory Kaba24 Min. Lesezeit

Du fängst bei einem neuen SaaS-Unternehmen an, das noch keine Dateninfrastruktur hat. Dein Chef hat von etwas namens Data Lakehouse gehört und dich engagiert, um eines zu bauen. Er will so schnell wie möglich datengetrieben werden, mit einer Einschränkung: Die Lösung soll so günstig wie möglich sein.

Als erfahrener Datenprofi weißt du, dass du nicht am ersten Tag mit dem Provisionieren von Warehouses anfangen solltest. Also setzt du einen Workshop auf, um zu verstehen, was das Unternehmen tatsächlich braucht. Du findest heraus, dass das Unternehmen keinerlei Sichtbarkeit über seinen Vertriebsmotor hat, das CRM chaotisch und unzuverlässig ist und die Finanzzahlen in jedem Leadership Meeting in Frage gestellt werden.

Nach ein paar Sessions kristallisieren sich die Anforderungen heraus:

  • Die Organisation möchte Reports und Dashboards für technische und nicht-technische Nutzer.
  • Sie benötigt täglichen Zugriff auf Daten aus einer Handvoll Quellen: CRM, Sales-Tools, Finanzsysteme und ein paar Anwendungsdatenbanken.
  • Das Datenvolumen liegt im zweistelligen Gigabyte-Bereich, nicht im Petabyte-Bereich.
  • Die Gesamtkosten des Systems sollen unter 500 $ pro Monat bleiben, mit Spielraum, um über die Zeit weitere Quellen und Use Cases hinzuzufügen.

Das ist ein sehr typisches Profil für ein SaaS-Unternehmen in der Series A oder B. Die Daten sind nicht riesig. Das Team ist nicht groß. Aber der Bedarf ist real und der Schmerz akut. Hier ist, wie du ein System dafür designen könntest.

Wichtigste Erkenntnisse

  • Ein Lakehouse kombiniert günstigen Objektspeicher mit Warehouse-Zuverlässigkeit über ein offenes Tabellenformat
  • DuckLake fasst Tabellenformat und Katalog in einem zusammen, mit Metadaten in Postgres statt einer Ansammlung kleiner Dateien
  • DuckDB ist eine in-process OLAP-Engine, keine Server zu provisionieren, nur eine Bibliothek, die du importierst
  • Concurrency wird über den Postgres-Katalog gesteuert, sodass Transformationsjobs und Dashboards den gleichen Datensatz sicher lesen und schreiben können
  • Metabase mit dem MotherDuck-DuckDB-Treiber gibt nicht-technischen Nutzern ein UI auf denselben Gold-Tabellen, die Analysten direkt aus DuckDB heraus abfragen
  • Ein tägliches Batch-Lakehouse für ein kleines SaaS-Unternehmen passt komfortabel unter 200 $ pro Monat, wobei der größte Kostenblock die dauerhaft laufende Metabase-Instanz ist

Was ist ein Data Lakehouse?

Ein Lakehouse kombiniert die besten Eigenschaften zweier älterer Paradigmen: des Data Lakes und des Data Warehouses. Ein Data Lake liefert dir günstigen Speicher auf Object Stores wie S3, GCS oder Azure Blob Storage. Ein Data Warehouse liefert dir Struktur, Schema Enforcement und transaktionale Garantien. Ein Lakehouse ist der Versuch, beides gleichzeitig zu bekommen: Lake-günstigen Speicher mit Warehouse-Zuverlässigkeit.

Der entscheidende Baustein ist das offene Tabellenformat. Delta Lake, Apache Iceberg und DuckLake (auf das sich dieser Artikel konzentriert) liegen alle über rohen Dateien im Objektspeicher und ergänzen das, was ein Warehouse als selbstverständlich voraussetzt: ACID-Garantien, damit parallele Writes deine Tabellen nicht korrumpieren, Schema Enforcement, damit eine fehlerhafte Upstream-Änderung deine Daten nicht still und leise zerstört, und Time Travel, damit du die Tabelle so abfragen kannst, wie sie letzten Dienstag aussah.

Egal, welches Format du wählst, jedes Lakehouse zerfällt in dieselben drei Stufen.

  • Ingestion zieht Daten aus den Quellsystemen und legt sie im Speicher ab.
  • Transformation bereinigt, verknüpft und modelliert die Rohdaten zu etwas, dem Analysten vertrauen können. In einem Lakehouse fließen die Daten meist durch verschiedene Layer: Bronze, Silver und Gold. Dieses geschichtete Design stellt sicher, dass Daten in aufeinander aufbauenden Stufen vorbereitet, bereinigt und transformiert werden.
  • Serving stellt diese modellierten Daten für Dashboards und Abfragen bereit.

Unter allen drei Stufen halten zwei Komponenten das Lakehouse zusammen: der Katalog und das Dateiformat.

Der Katalog

Der Katalog ist der Einstiegspunkt für Query Engines. Er verzeichnet, welche Tabellen existieren, wo deren Dateien liegen und welche Metadaten sie beschreiben. So entdeckt eine Compute Engine eine Tabelle, ohne dass du Dateipfade überall hartcodieren musst.

Für Apache Iceberg ist der Katalog üblicherweise AWS Glue, ein Hive Metastore oder ein REST-Katalog. Für Delta Lake ist es typischerweise Unity Catalog. Das sind separate Services, die du betreiben und bezahlen musst, und bei kleinem Scale ist dieser Overhead spürbar. Merk dir das, denn genau hier macht DuckLake etwas anderes.

Das Dateiformat

Die Daten selbst liegen in Parquet. Parquet ist ein spaltenbasiertes Format, das heißt Werte derselben Spalte werden zusammen gespeichert und nicht zeilenweise. Für Analytics ist das der entscheidende Punkt. Eine Dashboard-Abfrage, die den Umsatz über einen Datumsbereich aufsummiert, berührt nur zwei Spalten. Mit einem spaltenbasierten Layout liest die Engine nur diese beiden und überspringt den Rest. Parquet enthält außerdem Datei-Statistiken wie Min- und Max-Werte, sodass eine Query Engine ganze Dateien, die einen Filter nicht erfüllen können, ausschließt, ohne ein einziges Byte davon zu lesen.

Die Storage-Schicht ist also einfach eine Sammlung von Parquet-Dateien in einem Bucket. Tabellenformat und Katalog verwandeln diesen Haufen Dateien in etwas, das sich wie eine echte Datenbank verhält.

DuckDB und DuckLake

DuckDB ist eine in-process OLAP Query Engine. “In-process” bedeutet, dass sie innerhalb deiner Anwendung läuft, ähnlich wie SQLite, und nicht als separater Server, mit dem du dich über ein Netzwerk verbindest. Es gibt nichts zu provisionieren und nichts dauerhaft laufen zu lassen. Du importierst eine Bibliothek, zeigst auf ein paar Parquet-Dateien, und hast eine schnelle analytische Query Engine. Bei zweistelligen Gigabytes auf einer einzelnen Maschine ist es wirklich faszinierend, wie weit eine einzelne Maschine dich bringen kann.

DuckDB allein fragt Dateien ab. DuckLake verwandelt diese Dateien in ein Lakehouse. Es lohnt sich hier präzise zu sein, denn DuckLake ist nicht ganz dasselbe wie Iceberg oder Delta. Iceberg und Delta sind Tabellenformate, die noch einen externen Katalog brauchen. DuckLake ist Tabellenformat und Katalog in einem, und es trifft eine spezifische Architekturentscheidung: Metadaten gehören in eine echte Datenbank, nicht in eine Ansammlung kleiner JSON- und Avro-Dateien im Objektspeicher.

Ein DuckLake-Setup hat also zwei Speicher:

  • Daten liegen in Parquet im Objektspeicher, genau wie bei jedem anderen Lakehouse.
  • Metadaten liegen in einer SQL-Datenbank. SQLite oder DuckDB selbst funktionieren für lokale Entwicklung, aber für alles Geteilte nimmst du Postgres.

Diese Trennung ist der eigentliche Punkt. Iceberg und Delta schreiben ihre Metadaten als Dateien neben den Daten, was bedeutet, dass jede Abfrage einen Haufen kleiner Dateien übers Netzwerk listen und lesen muss, nur um einen Query-Plan zu erstellen. Wenn du dieselben Metadaten in Postgres ablegst, werden aus diesen Lookups schnelle indizierte Abfragen gegen eine Datenbank, die genau dafür gebaut wurde. Die Metadaten sind winzig, üblicherweise deutlich unter ein Prozent der Datenmenge, sodass eine kleine Postgres-Instanz das mühelos verarbeitet. Ein Postgres-basiertes DuckLake skaliert auf hunderte Terabyte, was deutlich mehr Spielraum ist, als unser SaaS-Unternehmen in den nächsten Jahren brauchen wird.

Wie DuckLake im Vergleich zu Iceberg und Delta Lake abschneidet

Drei offene Tabellenformate dominieren heute die Lakehouse-Diskussion, und sie treffen unterschiedliche Architekturentscheidungen. Die folgende Tabelle zeigt, wo sie sich unterscheiden.

MerkmalDuckLakeApache IcebergDelta Lake
KatalogIntegriert, gestützt auf Postgres, SQLite oder DuckDBExtern: Glue, REST, Hive, Nessie oder andereExtern: Unity Catalog, Hive oder dateibasiert
Metadaten-SpeicherSQL-DatenbankJSON- und Avro-Dateien im ObjektspeicherJSON- und Parquet-Dateien im Objektspeicher
ACID-TransaktionenJa, über die Katalog-DatenbankJa, über atomares Manifest-CommitJa, über das Transaktionslog
Time TravelJaJaJa
Schema-EvolutionJaJaJa
Parallele SchreiberÜber die Katalog-Datenbank koordiniertOptimistic Concurrency ControlOptimistic Concurrency Control
Primäre Query EnginesDuckDBSpark, Trino, Flink, DuckDBSpark, Trino, Polars
ReifegradNeu, 2025 als Open Source veröffentlichtReif, breite AdoptionReif, von Databricks getrieben
Bestes EinsatzgebietKleine bis mittlere Teams mit einer EngineGroßer Scale, Multi-Engine-UmgebungenDatabricks- und Spark-lastige Stacks

Für unser SaaS-Unternehmen ist die Rechnung einfach. Es gibt eine Engine (DuckDB), keinen Spark-Cluster zu füttern und eine klare Präferenz für weniger bewegliche Teile. Der integrierte Postgres-Katalog ist hier ein Feature, keine Einschränkung, weil Postgres ohnehin ein Service ist, den wir betreiben würden.

Das günstigste Lakehouse designen

Mit diesen Bausteinen ergibt sich die Architektur fast von selbst. Parquet in einem Bucket, Metadaten in Postgres, DuckDB als Engine und eine dünne Schicht günstiger Compute drumherum für Ingestion und Serving.

QuellenCRMSales-ToolsFinanceApp-DatenbankenIngestionContainerisierteExtract-JobsEventBridge +Step FunctionsTransformationDuckDB inContainernBronze → Silver→ GoldServingMetabase+ DuckDBObjektspeicher (Parquet)S3 / GCS / Azure BlobPostgres-KatalogDuckLake-MetadatenAbbildung: Jede Compute-Schicht spricht mit denselben zwei Speichern. Parquet hält die Daten, Postgres hält den Katalog.

Referenz-Implementierung

Ein vollständiger Terraform-Stack, der diese Architektur auf AWS aufbaut, ist Open Source unter github.com/m-l-kaba/ducklake_aws. Deploy-Schritte und Kostendetails findest du weiter unten.

Ingestion

Du brauchst keine schwergewichtige Ingestion-Plattform für eine Handvoll Quellen, die einmal am Tag abgerufen werden. Schreib kleine Extract-Jobs, einen pro Quelle, die die Source-API oder -Datenbank anfragen und Rohdaten als Parquet im Objektspeicher ablegen. Verpacke jeden als Container-Image.

Für Scheduling und Orchestration auf AWS triggert EventBridge die Jobs per täglichem Cron und Step Functions koordiniert alles mit Abhängigkeiten, zum Beispiel das Warten, bis alle Extracts fertig sind, bevor die Transformation startet. Die Jobs selbst laufen auf Fargate, sodass du nur für die Minuten zahlst, in denen sie tatsächlich laufen. Ein täglicher Extract, der fünf Minuten braucht, kostet fast nichts. Die übergeordneten Prinzipien, die diese Zahlen klein halten (das günstigste Compute-Primitive für den Workload wählen, von Tag eins an alles taggen, feature-basierte Kosten im Blick behalten), behandeln wir ausführlich in unserem Leitfaden zur AWS-Kostenoptimierung. Dasselbe Muster lässt sich sauber auf andere Clouds übertragen: Cloud Run Jobs mit Cloud Scheduler auf GCP oder Container Apps Jobs mit Logic Apps auf Azure.

Falls dir das Schreiben eigener Extraktoren zu viel ist, bringt eine Ingestion-Bibliothek wie dlt out-of-the-box ein DuckLake-Destination mit und übernimmt Schema-Inferenz und inkrementelle Loads für dich. So oder so ist der Output derselbe: Roh-Quelldaten in Parquet, bereit zum Modellieren.

Transformation

Hier zahlt sich DuckLake aus. Lass DuckDB innerhalb von Containern laufen, auf demselben Fargate- oder Cloud-Run-Setup wie deine Ingestion-Jobs, und lass sie die Rohdaten lesen, transformieren und die Ergebnisse zurück ins Lakehouse committen. Jeder Commit schreibt Parquet in den Objektspeicher und protokolliert die Metadaten-Transaktion in Postgres.

Strukturiere die Transformationen als die üblichen Medallion-Layer. Bronze sind die rohen, unberührt gelandeten Daten. Silver ist bereinigt und vereinheitlicht, mit korrigierten Typen, entfernten Duplikaten und über das chaotische CRM und die Finanzsysteme hinweg abgeglichenen Schlüsseln. Gold sind die geschäftsreifen Modelle, von denen die Dashboards lesen, etwa eine tägliche Revenue-Tabelle oder ein sauberer Opportunities-to-Closed-Won-Funnel.

Einen DuckLake-Katalog von DuckDB aus zu attachen ist ein einziges Statement:

INSTALL ducklake;
INSTALL postgres;
 
ATTACH 'ducklake:postgres:dbname=lakehouse host=your-postgres-host' AS lake
  (DATA_PATH 's3://your-bucket/lake/');
 
USE lake;

Von da an ist es einfach SQL. Du liest aus einem Layer, schreibst in den nächsten, und jeder Write ist eine ACID-Transaktion, die im Katalog festgehalten wird.

Wie der Bucket tatsächlich aussieht

Nach ein paar Pipeline-Läufen ist der Bucket selbst auffällig unauffällig. Kein _delta_log/-Verzeichnis voller JSON-Dateien, kein metadata/-Ordner mit Avro-Manifesten. Nur Parquet, organisiert nach Schema und Tabelle:

s3://your-bucket/lake/
├── bronze/
│   ├── crm_accounts/
│   │   ├── ducklake-019081d0-aa44-7c8a-95f4-2fe7d1eb2cea.parquet
│   │   └── ducklake-01908224-bb55-7e9c-a651-3fd8e2fc31db.parquet
│   └── stripe_invoices/
│       └── ducklake-019082f7-cc66-7f0a-b762-4fe9f3fd42ec.parquet
├── silver/
│   └── customers/
│       └── ducklake-01908391-dd77-7e1b-c873-5ff0f4fe53fd.parquet
└── gold/
    ├── revenue_daily/
    │   └── ducklake-01908452-ee88-7f2c-d984-6ff1f5ff64fe.parquet
    └── opportunities_closed_won/
        └── ducklake-019084c1-ff99-7f3d-e095-7ff2f6ff75ff.parquet

Die Katalog-Information liegt in Postgres, wo indizierte Abfragen die Frage “welche Dateien gehören gerade zu gold.revenue_daily?” in Millisekunden beantworten. Alles im Bucket ist Daten, was Lifecycle-Policies, Replikation und Ad-hoc-Inspektion erfrischend einfach macht.

Serving

Die Notizen aus den Workshops markierten das als den heiklen Teil, und historisch war es das auch. Vanilla DuckDB hat ein hartes Concurrency-Limit: Ein einzelner Prozess kann lesen und schreiben, oder mehrere Prozesse können lesen, aber du kannst nicht gleichzeitig Schreiber und Leser auf derselben Datenbank haben. Das ist ein Problem, wenn Transformationsjobs schreiben wollen, während ein Dashboard lesen möchte.

DuckLake hebt diese Einschränkung auf, und das ist der leise Grund, warum es so gut zu dieser Architektur passt. Da Concurrency über den transaktionalen Postgres-Katalog statt über ein File-Lock gesteuert wird, können mehrere DuckDB-Prozesse denselben Datensatz sicher lesen und schreiben. Deine Transformationscontainer können weiter in Gold-Tabellen committen, während das Dashboard daraus liest, ohne Korruption und ohne Koordination deinerseits.

Für die Dashboard-Schicht selbst nimmst du Metabase mit dem Community-DuckDB-Treiber, der von MotherDuck gepflegt wird. Metabase gibt sowohl technischen als auch nicht-technischen Nutzern ein sauberes Interface, um Dashboards zu bauen und Fragen zu stellen, ohne SQL zu schreiben, was genau das ist, was der Workshop als Bedarf herausgearbeitet hat.

Das Deployment ist klein, aber es lohnt sich, es sauber durchzuziehen.

Container-Image

Metabase liefert ein offizielles Docker-Image, aber der DuckDB-Treiber muss in dessen /plugins-Verzeichnis liegen. Der sauberste Weg ist ein winziges abgeleitetes Image, das den Treiber direkt einbacked:

FROM metabase/metabase:latest
 
ADD --chmod=644 \
  https://github.com/motherduckdb/metabase_duckdb_driver/releases/latest/download/duckdb.metabase-driver.jar \
  /plugins/duckdb.metabase-driver.jar

Zwei praktische Stolperfallen. Metabase Cloud erlaubt keine Custom-Driver, du brauchst also eine selbst gehostete Instanz, was ohnehin ein kleiner Always-on-Container ist. Und der DuckDB-Treiber braucht glibc, bleib also beim Debian-basierten Image und meide jedes -alpine-Tag.

Wo es laufen sollte

Auf AWS lässt du das Image als Always-on Fargate-Service hinter einem Application Load Balancer laufen. Eine vCPU und 2 GB Memory reichen für ein kleines Team locker. Zeige mit den MB_DB_*-Umgebungsvariablen auf eine Datenbank für Metabase’s eigene Anwendungsdaten. Du kannst dieselbe Managed Postgres nutzen, die auch den DuckLake-Katalog hält (als separate Datenbank auf derselben Instanz), was dir eine zweite Managed DB spart, ohne die beiden Schemas zu vermischen. Das Äquivalent auf GCP ist ein Cloud Run Service im Always-on-Modus, auf Azure eine Container App mit minReplicas gleich 1.

Metabase mit DuckLake verbinden

Erstelle in Metabase eine neue Datenbankverbindung vom Typ DuckDB. Der Treiber erlaubt dir, Init-SQL anzugeben, das beim Start des eingebetteten DuckDB-Prozesses ausgeführt wird. Nutze das, um die DuckLake- und Postgres-Extensions zu installieren, den Katalog read-only zu attachen und hineinzuwechseln:

INSTALL ducklake;
INSTALL postgres;
ATTACH 'ducklake:postgres:dbname=lakehouse host=<host> user=<readonly-user> password=<pw>'
  AS lake (DATA_PATH 's3://your-bucket/lake/', READ_ONLY);
USE lake;

Aus Sicht des Nutzers wirkt das wie eine ganz normale Datenbank in Metabase. Sie klicken sich in das gold-Schema, wählen die Tabelle revenue_daily und beginnen, Charts zu bauen. Dass die Daten in S3 liegen und der Katalog in Postgres lebt, ist für sie unsichtbar.

Bereitstellung für nicht-technische Nutzer

Ein paar kleine Schritte machen den Unterschied zwischen “sie haben Zugriff” und “sie nutzen es tatsächlich”:

  • Beschränke die Datenrechte in Metabase so, dass Business-User nur das gold-Schema sehen. Verberge bronze und silver komplett, damit der Datenbank-Browser aufgeräumt bleibt.
  • Definiere für jede Gold-Tabelle ein Metabase Model mit klarem Namen, Beschreibung und Spaltendokumentation. Models werden für Nutzer ohne SQL-Kenntnisse zum Einstiegspunkt im Query Builder.
  • Verbinde die Authentifizierung mit SSO (Google, Microsoft oder Okta via SAML), statt einzelne Metabase-Konten zu verteilen. Mappe SSO-Gruppen auf Metabase-Berechtigungsgruppen: Sales sieht die Sales-Models, Finance sieht Revenue, alle sehen das übergeordnete KPI-Dashboard.
  • Bau vor dem Rollout für jede Funktion ein Starter-Dashboard. Leere Metabase-Instanzen wirken einschüchternd; ein Dashboard mit fünf vorgebauten Charts gibt nicht-technischen Nutzern einen Ausgangspunkt zum Kopieren und Anpassen.
  • Das READ_ONLY-Flag im ATTACH zusammen mit einem Read-only-Postgres-User auf der Katalog-Verbindung sorgt dafür, dass selbst eine entgleiste Abfrage in Metabase das Lakehouse nicht beschädigen kann.

Wenn SQL schneller ist als Klicken

Nicht jeder Nutzer will ein Dashboard. Analysten, die SQL beherrschen, wollen oft einfach DuckDB auf das Lakehouse zeigen und losexplorieren. Aus einem Notebook oder einer lokalen DuckDB-Shell sieht die Verbindung fast genauso aus wie die von Metabase:

import duckdb
 
con = duckdb.connect()
con.execute("INSTALL ducklake; INSTALL postgres;")
con.execute("""
    ATTACH 'ducklake:postgres:dbname=lakehouse host=<host> user=<readonly-user>'
      AS lake (DATA_PATH 's3://your-bucket/lake/', READ_ONLY)
""")
 
weekly_revenue = con.execute("""
    SELECT
        date_trunc('week', closed_at) AS week,
        SUM(amount)                   AS revenue,
        COUNT(*)                      AS deals_won
    FROM lake.gold.opportunities_closed_won
    WHERE closed_at >= current_date - INTERVAL 12 WEEK
    GROUP BY week
    ORDER BY week
""").df()

Die Abfrage liest Parquet direkt aus S3, der Katalog beantwortet “welche Dateien sind aktuell?” aus Postgres, und das Ergebnis landet in einem Pandas DataFrame. Kein Warehouse hochzufahren, kein Cluster warmzuhalten. Derselbe Ansatz funktioniert für Ad-hoc-Untersuchungen, geplante Reports als Scripts oder das Einspeisen von Daten in ein Notebook für tiefere Analysen.

Auf AWS mit Terraform deployen

Die Referenz-Implementierung lässt sich auf einem frischen AWS-Account in rund 15 Minuten ausrollen. Voraussetzungen sind awscli v2, Terraform 1.6 oder neuer, Docker, Python 3.12, make sowie AWS-Credentials mit Administratorrechten.

Der Deploy-Flow besteht aus vier make-Targets:

cp .env.example .env          # REGION und METABASE_ADMIN_EMAIL setzen
make deploy                   # provisioniert alle AWS-Ressourcen (~7 Minuten)
make build-images             # baut und pusht die Jobs- und Metabase-Images
make run-once                 # befüllt den Lake mit dem ersten Datentag
make setup-metabase METABASE_ADMIN_EMAIL=you@example.com

Sobald setup-metabase durchgelaufen ist, gibt Terraform die Metabase-ALB-URL aus. Die Verbindung zum DuckLake-Katalog ist automatisch eingerichtet, sodass die durch make run-once erzeugten Tabellen sofort im Query Builder von Metabase abfragbar sind.

Die Betriebskosten in eu-central-1 liegen bei rund 130 $ pro Monat, solange der Stack voll aktiv ist. Die größten Posten sind das NAT Gateway, der dauerhaft laufende Metabase-Fargate-Task, der ALB und die kleine Managed Postgres. Das Repo liefert die Targets make pause und make resume, damit du den Metabase-Service nachts und am Wochenende abschalten kannst, wenn niemand Dashboards anschaut, was die Rechnung mit einem aggressiven Pause-Schedule in Richtung 100 $ pro Monat drückt. Die Kosten variieren je nach Region, und aktive AWS-Free-Tier-Guthaben auf einem neuen Account senken die Katalog-Position weiter.

Was kostet das?

Bei zweistelligen Gigabyte mit täglichen Batch-Jobs sind die Zahlen klein genug, um fast langweilig zu sein.

KomponenteWas du betreibstUngefähre Monatskosten
ObjektspeicherS3 mit zweistelligen GB Parquetwenige Dollar
KatalogKleine Managed Postgres (z. B. db.t4g.micro + 20 GB gp3)15 $ bis 30 $
Ingestion + TransformationFargate Tasks, Minuten pro Tag1 $ bis 5 $
ServingAlways-on Metabase Fargate Task (1 vCPU / 2 GB)30 $ bis 45 $
NetworkingNAT Gateway, ALB, Secrets Manager VPC Endpoint65 $ bis 85 $
OrchestrationEventBridge + Step Functionsbei diesem Scale praktisch kostenlos

Das landet komfortabel unter 200 $ pro Monat, deutlich innerhalb des Budgets von 500 $. Die größten Posten (NAT Gateway, ALB und der dauerhaft laufende Metabase-Task) sind Fixkosten und skalieren nicht mit dem Datenvolumen. Die nächste Datenquelle hinzuzufügen bedeutet, einen weiteren Extract-Job und ein paar zusätzliche Transformationsmodelle zu schreiben. Die Rechnung bewegt sich kaum. Die Zahlen oben gelten für eu-central-1 ohne AWS-Free-Tier-Guthaben; andere Regionen weichen um 10–20 % nach oben oder unten ab.

Wann dieses Design an seine Grenzen kommt

Jede Architektur hat eine Größenordnung, jenseits derer ihre Annahmen nicht mehr halten. Bei dieser sind vier Dinge im Blick zu behalten.

Multi-Engine-Anforderungen. Das gesamte Design lehnt sich an DuckDB an. Wenn du Spark für verteiltes ML-Training, Flink für Stream Processing oder Trino brauchst, um Queries über mehrere Lakehouses zu föderieren, wird die DuckDB-zentrierte Haltung von DuckLake schwierig. Iceberg mit AWS Glue oder einem REST-Katalog ist die Standardantwort, wenn mehrere Engines dieselben Tabellen lesen und schreiben müssen.

Skalierung jenseits weniger Terabyte. Ein einzelner DuckDB-Prozess verdaut zweistellige Gigabyte komfortabel und schafft auch noch niedrige einstellige Terabyte für gut modellierte Gold-Tabellen. Darüber hinaus werden Transformationsjobs langsamer und das Single-Node-Modell ächzt. Der Postgres-Katalog selbst skaliert deutlich weiter (DuckLake nennt dreistellige Terabyte), aber die Engine wird zum Bottleneck. Spätestens dann ist ein Managed Warehouse (Snowflake, BigQuery, Athena auf Iceberg) meist die bessere Wahl.

Sub-Minuten-Frische. Tägliches Batch-Processing ist die Prämisse dieses Artikels. DuckLake unterstützt häufige Micro-Batch-Commits, ist aber nicht auf Streaming-Ingestion auf Zeilenebene ausgelegt. Wenn Business-User Dashboards brauchen, die Events innerhalb von Sekunden widerspiegeln (Fraud Monitoring, Live Ops, Echtzeit-Pricing), willst du Kafka + Flink + Iceberg oder ein Streaming-first-Warehouse.

Team-Wachstum über 5–10 Analysten hinaus. Kleine Teams kommen ohne schwere Governance aus. Sobald du mehrere Geschäftsdomänen, regulierte Daten und Dutzende Dashboards über verschiedene Funktionen hinweg hast, spürst du das Fehlen ausgereifter Tools wie spaltenbasiertes Lineage, fein-granulares RBAC und Data Contracts. DuckLake liefert das nicht out-of-the-box; Iceberg mit Unity Catalog oder eine Managed-Lakehouse-Plattform schließen diese Lücke.

DuckLake ist außerdem neu, 2025 als Open Source veröffentlicht, also sind produktive Deployments noch selten. Wenn du keinen frischen Bug tolerieren oder auf fehlende Features warten kannst, sind die ausgereifteren Optionen sicherer.

Abschließende Gedanken

Das Interessante an diesem Design ist nicht, dass es günstig ist. Es ist, dass günstig und leistungsfähig kein Tradeoff mehr ist. Vor ein paar Jahren bedeutete der Zugang zu ACID-Tabellen, Time Travel und einem echten Katalog noch, ein Warehouse zu bezahlen oder einen Spark-Cluster plus separaten Metastore zu betreiben. Heute ist es Parquet in einem Bucket, eine kleine Postgres und eine in-process Engine, die nichts kostet, wenn sie nicht läuft. Das Unternehmen, das einfach nur aufhören wollte, sich in Leadership Meetings über seine Zahlen zu streiten, kann das zum Preis eines Team-Lunchs haben und von genau diesem Fundament aus zu einer ernsthaften Plattform wachsen.

Das Fundament zählt, aber was du darauf baust ebenfalls. Selbst das eleganteste Lakehouse wird zum Sunk Cost, wenn eine klare Datenstrategie fehlt, die definiert, welche Entscheidungen die Daten tatsächlich verbessern sollen.


Häufig gestellte Fragen

Was ist DuckLake?

DuckLake ist ein offenes Tabellenformat, das 2025 von DuckDB Labs veröffentlicht wurde und einen Parquet-basierten Data Lake mit einem SQL-Katalog (Postgres, SQLite oder DuckDB selbst) für Metadaten kombiniert. Anders als Apache Iceberg oder Delta Lake speichert DuckLake alle transaktionalen Metadaten in einer Datenbank statt in Dateien neben den Daten, was Katalog-Operationen schneller macht und einen separaten Katalogdienst überflüssig macht.

Worin unterscheidet sich DuckLake von Apache Iceberg oder Delta Lake?

Iceberg und Delta Lake speichern ihre Metadaten als JSON-, Avro- oder Parquet-Dateien im Objektspeicher und benötigen für den Produktionseinsatz beide einen externen Katalog (Glue, REST, Hive, Unity Catalog). DuckLake bündelt den Katalog ins Format selbst, indem Metadaten in einer SQL-Datenbank liegen. Das Ergebnis sind weniger bewegliche Teile, schnellere Metadaten-Lookups und eine Architektur, die besser zu Single-Engine-Deployments passt. Iceberg und Delta bleiben die bessere Wahl, wenn du Multi-Engine-Support über Spark, Trino, Flink und Databricks brauchst.

Ist DuckDB produktionsreif für ein echtes Lakehouse?

Für kleine bis mittlere analytische Workloads (zweistellige bis niedrige dreistellige Gigabyte, tägliche Batch-Transformationen, Dashboards für Dutzende gleichzeitige Nutzer), ja. DuckDB ist für dieses Profil breit im produktiven Einsatz, und der Postgres-basierte Katalog von DuckLake skaliert bequem bis in den dreistelligen Terabyte-Bereich. Es ist nicht die richtige Wahl für Workloads im Petabyte-Bereich, Sub-Minuten-Streaming-Anforderungen oder Multi-Engine-Architekturen.

Kann DuckLake Echtzeit- oder Streaming-Daten verarbeiten?

Nicht nativ. DuckLake ist auf Batch-Ingestion und transaktionale Commits ausgelegt, nicht auf Streaming auf Zeilenebene. Für Sub-Minuten-Frische brauchst du Kafka oder eine andere Streaming-Schicht davor, die in Micro-Batches alle paar Minuten in DuckLake schreibt. An dem Punkt ist eine Iceberg + Flink-Architektur oft die bessere Wahl.

Wann sollte man DuckLake NICHT verwenden?

Vermeide DuckLake, wenn du Multi-Engine-Support brauchst (Spark für ML, Trino für föderierte Queries), Daten im Petabyte-Bereich, Streaming-first Ingestion oder ausgereifte Governance-Tools wie fein-granulares RBAC, spaltenbasiertes Lineage oder Data Contracts. In dieser Größenordnung sind Iceberg mit einem Managed Catalog oder Delta Lake auf Databricks besser erprobte Optionen.

Wie viel kostet ein kleines DuckLake-basiertes Lakehouse pro Monat?

Für ein SaaS-Unternehmen mit zweistelligen GB an Daten und täglichen Batch-Jobs liegen die Gesamtkosten komfortabel unter 200 $ pro Monat. Die größten Posten sind die Netzwerk-Infrastruktur (NAT Gateway, ALB und ein Secrets Manager VPC Endpoint, etwa 65–85 $), der dauerhaft laufende Metabase-Fargate-Task (30–45 $) und die Managed Postgres als Katalog (15–30 $). Objektspeicher, Compute für Ingestion und Transformation sowie Orchestration bleiben zusammen typischerweise unter 10 $. Die Zahlen gelten für eu-central-1 und gehen von keinem aktiven AWS-Free-Tier-Guthaben aus.

Gibt es eine Referenz-Implementierung, die ich deployen kann?

Ja. Die Architektur aus diesem Artikel ist als Open-Source-Terraform-Referenzimplementierung auf GitHub verfügbar. Sie provisioniert die VPC, den RDS-Postgres-Katalog, die ECS-Fargate-Tasks für Ingestion und Transformation, den Metabase-Visualisierungsservice hinter einem ALB sowie die EventBridge- plus Step-Functions-Orchestration auf AWS. Das Deployment besteht aus vier make-Targets. Die Betriebskosten in eu-central-1 liegen bei rund 130 $ pro Monat mit voll aktivem Stack, oder bei etwa 100 $ pro Monat, wenn der Metabase-Service außerhalb der Geschäftszeiten über die mitgelieferten make pause und make resume Targets pausiert wird.

Mory Kaba

Mory Kaba

Senior Data Platform Engineer und Berater für Data Engineering, KI und Cloud-Architektur im DACH-Raum.