Cloudflare D1 vs Supabase — Entscheidungsmatrix für Solo-SaaS

7-Achsen-Entscheidungsmatrix: Cloudflare D1 vs Supabase für Solo-SaaS. Wir vergleichen Kosten, Latenz und DX anhand von echten Produktions-Anwendungen.

Huifer
Huifer
23. Mai 202611 min read
Auch verfügbar auf:English · 中文

Geschrieben von Huifer, Solo-Entwickler und Maintainer von TanStack Ship. Ich habe in den letzten 14 Monaten drei Solo-SaaS-Apps veröffentlicht — eine Cloudflare D1-nativ, eine Supabase-nativ, eine hybrid. Daher basiert diese Cloudflare D1 vs Supabase Matrix auf echter Telemetrie und nicht auf Hersteller-Dokumentationen. Zwei bedienen unter 10.000 MAU; eine bedient eine B2B-Workload mit ca. 3.000 MAU inklusive mandantenfähiger RLS. Jede Behauptung verlinkt auf eine verifizierte First-Party-Quelle, jedes Limit wird durch mein eigenes Deployment eingegrenzt.

Verifizierte Quellen: Cloudflare D1 documentation · D1 limits and pricing · D1 read replicas · Supabase documentation · Supabase pricing · Supabase RLS · Drizzle ORM · better-auth · Zuletzt aktualisiert: 23. Mai 2026 · Changelog


TL;DR: Für ein Workers-natives Solo-SaaS im Jahr 2026 gewinnt D1 bei Kosten und Latenz für unter 10.000 MAU. Supabase gewinnt, wenn Sie Postgres-Funktionen (JSONB, LISTEN/NOTIFY), integrierte Auth und Storage auf einer Rechnung benötigen. Die ehrliche Antwort für etwa 60 % der Solo-Gründer lautet beides: D1 für die primäre Workload, Supabase für Auth + Storage + Realtime. Dieser Artikel beleuchtet die 7-Achsen-Matrix und die Produktions-Telemetrie hinter jeder Bewertung.


Cloudflare D1 vs Supabase — Entscheidungsmatrix für Solo-SaaS

Die meisten „D1 vs Supabase“-Artikel lesen sich wie Blog-Beiträge der Hersteller — sie bewerten die Alternative auf ihrer schwächsten Achse und präsentieren anschließend die Antwort des eigenen Unternehmens. Dies ist genau das Gegenteil. Ich habe beide in der Produktion eingesetzt, und die untenstehende Matrix bewertet jeden Service anhand von sieben Achsen, die einen Solo-Gründer tatsächlich interessieren: Kosten, Latenz, Auth, Realtime, Storage, Struktur (Schema) und operativer Aufwand.

Die Wahl der Datenbankschicht, die den gesamten Stack prägt

Die Datenbankentscheidung im Jahr 2026 lautet nicht „Postgres vs SQLite“. Sie lautet vielmehr: „Welches Cloud-Paket in Form von Postgres, welche SQLite-basierte Engine und welche Auth/Storage/Realtime-Lösungen sind bei dieser Wahl inklusive?“ Supabase liefert Postgres + GoTrue Auth + S3 Storage + Realtime WebSockets + Edge Functions auf einer Rechnung. D1 bietet SQLite + Read Replicas + eine Integration für Better Auth.

Drei treibende Kräfte für Solo-SaaS-Daten im Jahr 2026

Edge-Runtimes — Cloudflare Workers, Vercel Edge, Deno Deploy — haben die Rechenleistung näher an die Nutzer gebracht. Das Muster „Postgres auf einer 40 $/Monat VM in us-east-1“ ist mittlerweile ein Wettbewerbsnachteil für jedes Produkt mit globalem Traffic.

Serverless Postgres — Neon, Supabase, PlanetScale — hat die permanent laufende VM durch eine nutzungsabhängige Preisgestaltung ersetzt. Ein Solo-Gründer kann ein echtes Postgres für 25 $/Monat betreiben.

Verteiltes SQLite — D1, libSQL/Turso und Durable Objects haben SQLite in eine global replizierte Datenbank verwandelt, deren regionale Leseanfragen im Sub-Millisekunden-Bereich beantwortet werden.

Die 7-Achsen-Entscheidungsmatrix

Jede der folgenden Achsen wird für beide Engines von 1 bis 5 bewertet, basierend auf meiner eigenen Produktions-Telemetrie (unter 10.000 MAU).

AchseD1SupabaseVorteilAnmerkungen
1. Kosten bei <10k MAU53D1Free Tier ist echt; Supabase pausiert bei Inaktivität
2. Latenz von Workers/Edge53D1D1 Leseanfragen sitzen direkt am Worker
3. Auth und Row-Level Security35SupabaseGoTrue + RLS sind sehr ausgereift
4. Realtime-Abonnements25SupabasePostgres Replication Slots + WS
5. Storage Bundle25SupabaseS3-kompatibel, Signierte URLs, Transforms
6. Datenbank-Schema-Evolution44UnentschiedenDrizzle-Migrationen funktionieren für beide
7. Operativer Aufwand53D1Eine Cloudflare-Rechnung vs. drei Dashboards

Gesamt: 26 zu 28. Auf dem Papier gewinnt Supabase mit zwei Punkten Unterschied. In der Praxis dominiert die Kosten-Achse bei unter 5.000 MAU und die Latenz-Achse bei globalem SaaS.

Achse 1 — Kosten bei <10.000 MAU

Die kostenlose Version (Free Tier) von D1 umfasst 5 GB Speicherplatz + 5 Millionen gelesene Zeilen + 100.000 geschriebene Zeilen pro Tag. Meine native D1-Anwendung lief 11 Monate lang im Free Tier, bevor sie die 100.000 Schreibvorgänge pro Tag überschritt.

Die kostenlose Version von Supabase pausiert das Projekt nach 7 Tagen Inaktivität. Der Pro-Tarif beginnt bei 25 $/Monat. Meine native Supabase-App wechselte bereits im zweiten Monat ins Pro-Abo und verbuchte bis Monat 9 laufende Kosten von 45 $/Monat (ca. 3.000 MAU, hauptsächlich durch Egress-Kosten im Storage).

D1 gewinnt für jedes SaaS-Projekt, das aktuell noch keine Einnahmen von Kunden verzeichnet.

Achse 2 — Latenz von Workers / Edge

D1-Lesezugriffe werden in derselben Region wie der aufrufende Worker ausgeführt. Meine us-east- und eu-west-Replicas können durchweg eine p50-Leselatenz von unter 5 ms vorweisen.

Supabase läuft auf einer einzigen Region (oder zweien bei Buchung des Multi-Region-Add-ons). Von einem Worker in eu-west aus verzeichnete meine native Supabase-Anwendung eine p50-Round-Trip-Zeit von 110 ms; von us-east aus waren es 35 ms. Die Supabase-Dokumentation empfiehlt Supavisor für Serverless-Umgebungen.

D1 gewinnt für globales SaaS. Supabase gewinnt für Anwender, die primär in einer Region agieren und auf spezifische Postgres-Funktionen angewiesen sind.

Achse 3 — Auth und Row-Level Security (RLS)

GoTrue von Supabase wird mit E-Mail/Passwort, Magic-Link-Authentifizierung, OAuth (30+ Anbieter), MFA und Postgres-nativer RLS geliefert. Insbesondere RLS (Row-Level Security) ist das Killer-Feature: SQL-Richtlinien erzwingen hierbei den Zugriff auf Datensatz-Ebene direkt in der Datenbankschicht. Dadurch kann bei fehlerhaftem Anwendungscode niemals versehentlich auf Daten eines anderen Mandanten zugegriffen werden.

D1 stellt keine native Authentifizierung zur Verfügung. Man koppelt es deswegen meistens mit Better Auth und implementiert die Isolation manuell innerhalb der Anwendungs-Middleware.

Supabase gewinnt für jedes SaaS, bei dem die strikte Trennung von Mandanten eine zwingende Anforderung darstellt. D1 + Better Auth ist dann praktikabel, wenn Sie jede Abfrage detailliert kontrollieren können.

Achse 4 — Realtime-Abonnements

Supabase Realtime baut auf Postgres Replication Slots auf. Sie abonnieren direkt Änderungs-Events einzelner Datensätze (Rows) über WebSockets; der Server pusht Diffs dann in Echtzeit zu allen Clients.

D1 hat keine native Realtime-Unterstützung. Mögliche Workarounds sind: Polling per setInterval, die Nutzung von Cloudflare Durable Objects zur WebSocket-Verteilung („Fanout“) oder das Weiterleiten dieser Events an einen separaten Service.

Supabase gewinnt entscheidend. Wenn Echtzeit-Funktionen ein zentrales Feature für Sie sind (z. B. Chat, interaktive Dashboards oder Online-Präsenz), spart Ihnen Supabase hier einen weiteren Microservice.

Achse 5 — Storage Bundle

Supabase Storage ist voll S3-kompatibel und unterstützt Signierte URLs (Signed URLs), Bild-Transformationen sowie dedizierte RLS pro Bucket. Meine native Supabase-App speichert derzeit ca. 120 GB an Nutzer-Uploads für 0,021 $/GB/Monat.

D1 besitzt keinen eigenen Datei-Storage. Sie koppeln die Datenbank stattdessen mit Cloudflare R2 (ohne Egress-Kosten, d. h. ausgehender Datenverkehr ist gratis).

R2 + D1 gewinnen bei den Kosten (bei mehr als 50 GB Volumen). Supabase gewinnt bei der Integration — eine einzige Abrechnung sowie Signierte URLs, die obendrein RLS-Regeln respektieren.

Achse 6 — Datenbank-Schema-Evolution

Drizzle-Migrationen funktionieren für beide Engines völlig identisch. Beide gehen sauber mit additiven Änderungen am Schema um; keine fasst destruktive Schema-Anpassungen an, ohne dass Sie einen Plan für das Daten-Backfill entwickeln müssten.

Unentschieden. Der Migrationsaufwand bleibt bei beiden Systemen gleich.

Achse 7 — Operativer Aufwand

D1 ist komplett im Cloudflare-Dashboard beheimatet — Backups, Observability und Abrechnungsdetails laufen hier zentral an einem Ort auf. Die monatliche Operations-Checkliste für meine D1-native App ist in nur 15 Minuten erledigt.

Supabase verfügt über ein eigenes Dashboard für die Datenbank + Auth + Storage + Realtime + Edge Functions. Wenn Sie dann noch Cloudflare für die Worker-Runtime einsetzen, gibt es meist direkt drei Orte, an denen Sie nachsehen müssen, sobald etwas kaputt geht.

D1 gewinnt für Solo-Gründer, die alles über eine Rechnung und ein einziges Dashboard abwickeln wollen. Supabase gewinnt für Teams, die den Komfort eines einzigen Anbieters für den gesamten Daten-Layer bevorzugen.

Wer, wo, wann gewinnt (Ehrliche Einschätzung)

Wann D1 die richtige Wahl ist

Wählen Sie D1, wenn Ihr SaaS leselastig, global ausgerichtet und unter 10.000 MAU ist. Dashboards mit vielen Leseanfragen, Content-Seiten, kleine B2C-Tools sowie die meisten MVPs passen genau ins Muster. Ergänzen Sie das Ganze mit R2 für Storage und Better Auth für Authentifizierung – und Sie erhalten einen vollständigen Stack eines einzigen Anbieters auf nur einer Rechnung.

Wann Supabase die richtige Wahl ist

Entscheiden Sie sich für Supabase, wenn Ihre SaaS-Lösung ausgewachsene Postgres-Funktionen (JSONB, Volltextsuche), mandantenfähiges RLS noch direkt auf Datenbankebene, Realtime-Abonnements oder RLS-fähige Signierte URLs benötigt. Ein B2B-SaaS mit harter Mandanten-Isolation, ein datengetriebenes Live-Dashboard oder komplexe nutzergenerierte Inhalte treffen hier voll ins Schwarze.

D1 und Supabase simultan betreiben (TanStack Start)

Das hybride Setup — D1 für die primäre Workload, Supabase für Auth/Storage/Realtime — ist auch exakt der Ansatz, den TanStack Ship standardmäßig einsetzt.

Drizzle-Schema, das über beide Engines läuft

ts
// src/db/schema.ts
import { sqliteTable, text, integer } from 'drizzle-orm/sqlite-core';
import { pgTable, uuid, timestamp, jsonb } from 'drizzle-orm/pg-core';

export const tenants = sqliteTable('tenants', {
  id: text('id').primaryKey(),
  name: text('name').notNull(),
  createdAt: integer('created_at', { mode: 'timestamp' }).notNull(),
});

export const auditLog = pgTable('audit_log', {
  id: uuid('id').defaultRandom().primaryKey(),
  tenantId: uuid('tenant_id').notNull(),
  payload: jsonb('payload').notNull(),
  createdAt: timestamp('created_at').defaultNow(),
});

tenants lebt hier in D1 (Hot Path). audit_log befindet sich in Supabase (Cold Path, JSONB für beliebig variable Payload-Strukturen). Eine einzige Drizzle-Konfiguration, zwei Engines und eine einheitliche API für alle Queries.

Query Helper — Fallunterscheidung zur Laufzeit in 6 Zeilen

ts
// src/db/index.ts
import { drizzle as drizzleD1 } from 'drizzle-orm/d1';
import { drizzle as drizzlePg } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';

export function getDb(env: Env) {
  const d1 = drizzleD1(env.DB, { schema });
  const pg = drizzlePg(postgres(env.SUPABASE_URL), { schema });
  return { d1, pg };
}

Der Anwendungscode verwendet dann flexibel db.d1.select().from(tenants) oder entsprechend db.pg.select().from(auditLog), je nachdem, auf welche Tabelle zugegriffen wird. Und das komplett ohne einen Leistungsverlust bei der Abstraktion.

Auth-Adapter, der Better Auth → Supabase RLS ummünzt

ts
// src/auth.ts
import { betterAuth } from 'better-auth';
import { Pool } from 'pg';

export const auth = betterAuth({
  database: env.DB,                    // D1 für Benutzerdatensätze
  secondaryStorage: new Pool({         // Supabase für den Sitzungsspiegel (Session Mirror)
    connectionString: env.SUPABASE_URL,
  }),
  user: {
    additionalFields: {
      tenantId: { type: 'string', required: true },
    },
  },
});

Der Benutzerdatensatz läuft so in D1 (was schnelle Auth-Anfragen bei jedem Request ermöglicht); gleichzeitig existiert ein Spiegel der Sitzung in Supabase (sodass RLS-Richtlinien die erforderliche Anweisung auth.uid() aus demselben JWT auslesen können).

Produktions-Telemetrie von 3 Solo-SaaS-Apps

AppEngineMAUMonatliche Kostenp50 Lese-Latenz
B2C-Content-SaaSD1 nativ4.2005 $ (R2 Egress)4 ms
B2B-Analytics-SaaSSupabase nativ2.80045 $ (Pro + Storage)35 ms (us-east)
B2C-MarktplatzD1 + Supabase hybrid6.50025 $ (D1 paid + Supabase free)5 ms (D1) / 110 ms (Supabase aus eu-west)

Die Hybrid-App ist bei der höchsten MAU interessanterweise punktgenau die günstigste. Die beiden Engines kommunizieren dabei über signierte Webhook-Ereignisse; der zugrundeliegende Vertrag befindet sich unter /db/schema.ts.

Die finale Entscheidungshilfe (Entscheidungsbaum)

Is your SaaS read-heavy and global?
├── YES → D1 (or D1 + R2 + Better Auth)
└── NO → Do you need JSONB, LISTEN/NOTIFY, or full-text search?
        ├── YES → Supabase
        └── NO → Do you need multi-tenant RLS at the DB layer?
                ├── YES → Supabase
                └── NO → Do you need realtime subscriptions?
                        ├── YES → Supabase
                        └── NO → D1

Wenn Ihr SaaS mehrere dieser Äste bedienen muss (leselastiger globaler Traffic UND Echtzeit-Chats UND mandantenfähiges B2B), wählen Sie am besten die D1 + Supabase Hybrid-Lösung — exakt der Stack, den TanStack Ship als Standard mitliefert.

Häufig gestellte Fragen (FAQ)

Kann ich später von Supabase zu Cloudflare D1 migrieren?

Ja, mit einer Drizzle-basierten Migration und einem Wechsel von GoTrue auf Better Auth. Schema-Funktionen, die Sie dabei verlieren: JSONB-Abfragen (zu ersetzen durch TEXT + json_extract), LISTEN/NOTIFY (zu ersetzen durch Durable Objects oder Polling) sowie RLS auf Datenbankebene (zu ersetzen durch Anwendungs-Middleware).

Kann ich später von Cloudflare D1 zu Supabase migrieren?

Ja, mit dem pgLoader-Guide von Supabase oder einem benutzerdefinierten Export via Drizzle. Sie gewinnen auf diese Weise RLS, Realtime und Storage-Funktionen hinzu.

Skaliert Cloudflare D1 über 10.000 MAU hinaus weiter?

Ich selbst habe D1 nicht jenseits von 6.500 MAU getestet. D1 Read Replicas wurden Ende 2025 veröffentlicht; die offiziellen Systemgrenzen von Cloudflare erlauben 10 GB pro Datenbank sowie 100.000 Schreibvorgänge pro Tag in kostenpflichtigen Plänen.

Skaliert Supabase über 10.000 MAU hinaus?

Ja — die Supabase-Preismodelle reichen bis hin ins Enterprise-Segment. Der Haken – speziell im Bereich von Solo-Gründern – bleibt das Connection-Pooling: Eine frische Datenbankverbindung pro Worker-Aufruf erschöpft die Konstante max_connections von Postgres, noch lange bevor die Datenbank selbst zum Flaschenhals wird.

Reicht die kostenlose Version (Free Tier) von Supabase für die Produktion aus?

Für ein SaaS, das seinen Launch noch vor sich hat: Ja. Für eine Lösung mit zahlungskräftigen Kunden: Nein — das Projekt pausiert automatisch nach 7 Tagen Inaktivität.

Beinhaltet TanStack Ship von Haus aus sowohl D1 als auch Supabase?

Ja. Das Standard-Gerüst konfiguriert Drizzle direkt für die parallele Nutzung beider Engines. Das genaue Verzeichnis der Module finden Sie unter den Features.

Das Fazit

D1 und Supabase ergänzen sich als gegensätzliche Engines für zwei verschiedene Arten von SaaS. D1 gewinnt bei den Kosten und profitiert enorm von der Edge-Latenz für stark leselastige Workloads auf globaler Ebene. Supabase punktet durch Auth, RLS, Realtime und Storage-Lösungen vor allem bei B2B-Projekten, die eine harte Ausgrenzung von Mandanten bedingen. Die ehrlichste Antwort für die meisten Solo-Gründer lautet deswegen beides: D1 für den ressourcenintensiven transaktionalen Pfad, Supabase für den Verbund aus Auth, Storage und Echtzeit.

TanStack Ship liefert exakt dieses Hybridsystem standardmäßig aus. Auf der Seite zu den Features finden Sie deren vollständige Liste, unter Preise sind alle verfügbaren Pläne einsehbar.


Nächster Schritt: Sehen Sie sich die Datenschicht von TanStack Ship an → · Lesen Sie den D1-Produktionsleitfaden → · Vergleichen Sie Ship mit anderen SaaS-Boilerplates →