SQLite vs PostgreSQL ist eine andere Frage als „MySQL oder PostgreSQL“. Dort vergleichst du zwei Datenbank-Server. Hier vergleichst du einen Datenbank-Server mit einer Bibliothek, die eine einzige Datei beschreibt. Die kurze Antwort vorweg: Läuft deine Anwendung auf genau einem Server und schreiben selten viele Prozesse gleichzeitig, ist SQLite fast immer die einfachere und oft die schnellere Wahl. Brauchst du mehrere Anwendungsserver, viele gleichzeitige Schreiber, schwere Auswertungen oder Zugriffe über das Netzwerk, nimm PostgreSQL.
Wir betreiben beide produktiv. Auf unserem Hauptserver liegen gerade rund 30 aktive SQLite-Dateien (Spiele, kleine Werkzeuge, Statistik-Dienste) und etwa ein Dutzend PostgreSQL-Datenbanken (Shop-Software, Ticket-System, Community-Plattform). Damit dieser Artikel nicht nur aus Erfahrungswerten besteht, haben wir am 11. Oktober 2026 beide mit exakt denselben Daten gegeneinander laufen lassen: SQLite 3.51.3 (eingebaut in Node.js 22) und PostgreSQL 17.11 im offiziellen Docker-Image, mit Standardeinstellungen, 2 Millionen Bestellungen und 100.000 Kunden. Drei Ergebnisse vorweg:
1. Einen einzelnen Datensatz über einen Index holen: SQLite rund 5 Mikrosekunden, PostgreSQL rund 105 Mikrosekunden. Das ist kein Tippfehler. SQLite spart sich den kompletten Weg über das Netzwerk.
2. Eine große Auswertung (Join über 2 Millionen Zeilen, gruppiert nach Stadt): SQLite 2,9 Sekunden, PostgreSQL 0,3 Sekunden. Bei schweren Abfragen gewinnt PostgreSQL deutlich, unter anderem weil es mehrere CPU-Kerne gleichzeitig nutzt.
3. 16 Prozesse schreiben gleichzeitig: Ohne die richtige Einstellung lieferte SQLite über 1,6 Millionen „database is locked“-Fehler in 5 Sekunden. Mit einer einzigen Zeile Konfiguration waren es 3. PostgreSQL schaffte im selben Test 22.208 Einfügungen pro Sekunde, SQLite rund 4.900.

SQLite vs PostgreSQL: Der grundlegende Unterschied
Der wichtigste Satz dieses Artikels: SQLite ist kein Server. Es gibt keinen Dienst, der im Hintergrund läuft, keinen Port, keinen Benutzer, kein Passwort. SQLite ist eine Programmbibliothek, die direkt in deine Anwendung eingebaut wird. Deine Anwendung öffnet eine Datei, zum Beispiel daten.db, und liest und schreibt sie über SQL. Die gesamte Datenbank mit allen Tabellen, Indizes und Daten steckt in dieser einen Datei (plus zwei kleinen Hilfsdateien, solange sie geöffnet ist).
PostgreSQL ist ein Server. Es läuft als eigener Prozess, wartet auf einem Netzwerk-Port (standardmäßig 5432) auf Verbindungen, verwaltet Benutzer und Rechte und organisiert seine Daten in einem eigenen Verzeichnis mit vielen Dateien. Deine Anwendung schickt SQL-Befehle über eine Verbindung an diesen Server und bekommt Ergebnisse zurück. Das funktioniert vom selben Rechner aus, aber genauso von zehn anderen Servern.
Daraus folgt fast alles, was in diesem Vergleich wichtig ist:
- Geschwindigkeit bei kleinen Abfragen: SQLite liest direkt aus dem Speicher deines Prozesses. PostgreSQL muss jede Anfrage verpacken, verschicken, im Server ausführen und zurückschicken. Selbst auf demselben Rechner kostet das pro Abfrage Zeit.
- Gleichzeitiges Schreiben: Eine Datei, auf die viele Prozesse schreiben wollen, braucht eine Sperre. SQLite erlaubt deshalb immer nur einen Schreiber gleichzeitig. PostgreSQL koordiniert viele Schreiber intern und lässt sie parallel arbeiten.
- Betrieb: SQLite musst du nicht installieren, starten, absichern, aktualisieren oder überwachen. PostgreSQL schon.
- Mehrere Server: Auf eine SQLite-Datei können nur Programme auf demselben Rechner zugreifen. Netzwerk-Dateisysteme wie NFS sind ausdrücklich nicht empfohlen. Wer zwei Anwendungsserver hat, braucht einen Datenbank-Server.

Wer hinter SQLite steht
SQLite wurde im Jahr 2000 von D. Richard Hipp entwickelt, ursprünglich für Software auf einem Schiff der US-Marine, die ohne Datenbank-Administrator funktionieren sollte. Gepflegt wird es bis heute von einem sehr kleinen Kernteam rund um Hipp. Der Code ist gemeinfrei (Public Domain), also nicht einmal unter einer Open-Source-Lizenz, sondern komplett frei. Beiträge von außen nimmt das Projekt nur sehr eingeschränkt an, dafür ist es für seine extrem gründlichen Tests bekannt: Die Testsuite ist um ein Vielfaches größer als der eigentliche Code.
SQLite ist vermutlich die am häufigsten installierte Datenbank der Welt. Sie steckt in jedem Android- und iOS-Gerät, in Firefox, Chrome und Safari, in macOS, Windows 10 und 11, in Flugzeugen, Autos, Fernsehern und in unzähligen Desktop-Programmen. Wenn dein Browser sich deinen Verlauf merkt, macht er das sehr wahrscheinlich mit SQLite.
Wer hinter PostgreSQL steht
PostgreSQL entstand ab 1986 als Forschungsprojekt an der University of California in Berkeley und wird seit den 1990ern von der PostgreSQL Global Development Group weiterentwickelt, einer Gemeinschaft ohne einzelnen Eigentümer. Die Lizenz ist die freizügige PostgreSQL License. Jedes Jahr erscheint eine Hauptversion, die fünf Jahre gepflegt wird. Wir haben bewusst mit Version 17 getestet, weil sie in den meisten produktiven Setups läuft. Wer mehr über die Geschichte und den Vergleich mit MySQL lesen will: In unserem Artikel PostgreSQL vs MySQL haben wir das ausführlich aufgeschrieben, ebenfalls mit eigenem Benchmark.
Deutschsprachiger Performance-Vergleich von Deployn (Juni 2025). Andere Hardware und andere Testfälle als bei uns, die Grundtendenz ist dieselbe.Unser Testaufbau
Damit du die Zahlen einordnen kannst, hier genau, was wir gemacht haben. Alles lief am 11. Oktober 2026 auf unserem eigenen Server (12 virtuelle CPU-Kerne, 23 GB RAM, NVMe-SSD).
- SQLite 3.51.3, direkt im Node.js-Prozess über das eingebaute Modul
node:sqlite. Journal-Modus WAL (dazu gleich mehr), sonst Standardeinstellungen. - PostgreSQL 17.11 im offiziellen Docker-Image
postgres:17, begrenzt auf 2 CPU-Kerne und 2 GB RAM, Standardkonfiguration. Zugriff aus Node.js über die Bibliothekpg, über den lokalen Docker-Port. - Daten: 100.000 Kunden (15 Städte) und 2.000.000 Bestellungen mit Betrag und Datum, erzeugt mit einem festen Zufalls-Startwert, also für beide Datenbanken bit-genau identisch. Indizes auf
orders.customer_idundcustomers.city, danachANALYZE.
Zwei Dinge sind am Aufbau nicht fair, und das sagen wir lieber vorher: SQLite hatte keine CPU-Begrenzung, nutzt pro Abfrage aber ohnehin nur einen Kern. PostgreSQL lief hinter dem Docker-Netzwerk, was jede einzelne Anfrage etwas langsamer macht als ein direkter Unix-Socket. Beides entspricht aber ziemlich genau dem, wie die meisten Leute die beiden Datenbanken tatsächlich betreiben.
Benchmark-Ergebnisse: Lesen, Auswerten, Schreiben
| Test | SQLite 3.51 | PostgreSQL 17 |
|---|---|---|
| Import 2,1 Mio. Zeilen + Indizes | 2,7 s | 10,9 s |
| 20.000 Einzelabfragen per Primärschlüssel | 0,10 s (≈ 5 µs pro Abfrage) | 2,15 s (≈ 108 µs) |
| 20.000 Abfragen „5 Bestellungen eines Kunden“ | 0,10 s | 2,08 s |
| Gruppieren nach Monat (2 Mio. Zeilen) | 726–731 ms | 205–207 ms |
| Join + Gruppieren nach Stadt (2 Mio. Zeilen) | 2.879–2.938 ms | 265–299 ms |
| dasselbe, PostgreSQL ohne Parallelisierung | 2.879–2.938 ms | 727–777 ms |
| 5.000 Updates, jedes einzeln bestätigt | 0,89 s (FULL) / 0,14 s (NORMAL) | 1,36 s |
| Größe auf der Platte | 87 MB | 187 MB |
| Arbeitsspeicher | 4–7 MB (gesamter CLI-Prozess) | 21 MB im Leerlauf, 167 MB nach dem Test |
Einzelne Abfragen: SQLite ist rund zwanzigmal schneller
Das ist der Teil, den viele unterschätzen. Eine typische Webseite macht vor allem eines: einzelne Datensätze über einen Index holen. „Zeig mir den Benutzer mit dieser ID“, „zeig mir die letzten fünf Bestellungen dieses Kunden“. Bei genau diesen Abfragen war SQLite in unserem Test rund zwanzigmal schneller: 20.000 Abfragen in 0,1 Sekunden gegenüber gut 2 Sekunden.
Der Grund ist nicht, dass PostgreSQL schlecht sucht. Beide finden den Datensatz über den Index in Mikrosekunden. Der Unterschied ist der Weg: Bei PostgreSQL geht jede Abfrage durch den Datenbanktreiber, über eine Netzwerkverbindung in den Server, wird dort ausgeführt und wandert zurück. Das kostet in unserem Aufbau rund 100 Mikrosekunden pro Runde. SQLite liest einfach Speicherseiten im eigenen Prozess.
Was heißt das praktisch? Für eine einzelne Seite, die zehn Abfragen macht, sind 1 Millisekunde gegen 0,05 Millisekunden egal. Spürbar wird es bei Code, der viele kleine Abfragen hintereinander macht, zum Beispiel das berüchtigte „N+1-Problem“ (für jede von 200 Bestellungen einzeln den Kunden nachladen). Mit SQLite fällt so ein Fehler kaum auf. Mit PostgreSQL macht er eine Seite schnell eine halbe Sekunde langsamer.
Große Auswertungen: PostgreSQL ist drei- bis zehnmal schneller
Sobald eine Abfrage Millionen Zeilen anfassen muss, dreht sich das Bild. Beim Join über alle Bestellungen, gruppiert nach Stadt, brauchte SQLite knapp 3 Sekunden, PostgreSQL 0,3 Sekunden. Zwei Gründe:
- Parallele Abfragen. PostgreSQL verteilt große Abfragen auf mehrere CPU-Kerne. Schalten wir das ab (
max_parallel_workers_per_gather = 0), braucht PostgreSQL rund 0,75 Sekunden. Immer noch viermal schneller als SQLite, aber der Abstand halbiert sich. - Bessere Join-Strategien. SQLite hat diese Abfrage mit einer sogenannten Nested-Loop-Strategie gelöst: Es läuft alle 100.000 Kunden durch und sucht für jeden über den Index seine Bestellungen. PostgreSQL nimmt einen Hash-Join, liest beide Tabellen einmal komplett und verbindet sie im Speicher. SQLite kennt keinen Hash-Join. Für Auswertungen über große Datenmengen ist das ein echter Nachteil.
Wenn dein Projekt also Berichte, Statistiken oder Dashboards über viele Millionen Zeilen erzeugt, ist PostgreSQL klar im Vorteil.
Schreiben: Hier entscheidet eine einzige Einstellung
Bei 5.000 Updates, die jeweils einzeln bestätigt wurden, brauchte PostgreSQL 1,36 Sekunden. SQLite brauchte mit der sicheren Standardeinstellung synchronous=FULL 0,89 Sekunden und mit synchronous=NORMAL nur 0,14 Sekunden.
Was bedeutet das? Bei FULL wartet SQLite nach jeder Transaktion, bis die Daten wirklich auf der SSD gelandet sind. Bei NORMAL im WAL-Modus wartet es nur beim regelmäßigen Zurückschreiben in die Hauptdatei. Die Datenbank bleibt dabei immer konsistent. Im schlimmsten Fall, also bei einem Stromausfall oder Absturz des Betriebssystems, können die letzten bestätigten Transaktionen fehlen. Ein Absturz deiner Anwendung allein verliert nichts. Für die meisten Webanwendungen ist NORMAL ein vernünftiger Kompromiss, für Buchhaltung oder Zahlungen würden wir bei FULL bleiben.
Beim Import lag SQLite ebenfalls vorne: 2,7 gegenüber 10,9 Sekunden. Fairerweise: Wir haben PostgreSQL mit normalen INSERT-Befehlen in Paketen à 2.000 Zeilen befüllt. Mit dem Spezialbefehl COPY wäre PostgreSQL deutlich schneller gewesen, im MySQL-Vergleich lag es damit bei 2,3 Sekunden für dieselbe Datenmenge.
Das größte Problem von SQLite: gleichzeitige Schreiber
Jetzt zum Punkt, an dem die meisten SQLite-Projekte in Produktion zum ersten Mal Ärger bekommen. Wir haben 1, 4 und 16 Prozesse gleichzeitig 5 Sekunden lang so schnell wie möglich in dieselbe Tabelle schreiben lassen.
| Gleichzeitige Schreiber | SQLite ohne busy_timeout | SQLite mit busy_timeout=5000 | PostgreSQL |
|---|---|---|---|
| 1 | 5.237 / s, 0 Fehler | 5.192 / s, 0 Fehler | 3.855 / s |
| 4 | 2.001 / s, 1.492.576 Fehler | 5.249 / s, 0 Fehler | 10.676 / s |
| 16 | 547 / s, 1.619.145 Fehler | 4.929 / s, 3 Fehler | 22.208 / s |

Drei Dinge fallen auf.
Erstens: Die Standardeinstellung ist gefährlich. Ohne busy_timeout gibt SQLite sofort auf, wenn gerade ein anderer Prozess schreibt, und meldet database is locked (in manchen Treibern SQLITE_BUSY). Bei 16 Schreibern waren das über 1,6 Millionen Fehlversuche in 5 Sekunden, und nur 547 Einfügungen pro Sekunde kamen durch. In einer echten Anwendung landet so ein Fehler beim Benutzer.
Zweitens: Eine Zeile behebt das fast vollständig. Mit PRAGMA busy_timeout = 5000; wartet SQLite bis zu 5 Sekunden darauf, dass die Sperre frei wird. Plötzlich laufen auch mit 16 Schreibern knapp 5.000 Einfügungen pro Sekunde durch, praktisch fehlerfrei. Diese Zeile gehört in jede SQLite-Anwendung, die mehr als einen Prozess oder Thread hat. Viele Frameworks setzen sie inzwischen automatisch, viele aber auch nicht. Prüf es.
Drittens: Fast fehlerfrei ist nicht fehlerfrei. Bei 16 Schreibern sahen wir trotz Timeout drei Fehler. Das passiert typischerweise, wenn eine Transaktion erst liest und dann schreiben will, während ein anderer Prozess schon schreibt. Dann kann SQLite nicht warten, ohne dass sich beide gegenseitig blockieren, und bricht sofort ab. Die Lösung in der Praxis: Schreibende Transaktionen mit BEGIN IMMEDIATE statt BEGIN starten. Den genauen Auslöser der drei Fehler haben wir nicht weiter untersucht, wir erwähnen ihn, weil er im echten Betrieb genauso auftauchen kann.
Und PostgreSQL? Wird mit mehr Schreibern schneller, nicht langsamer. Mit einem Schreiber war es sogar langsamer als SQLite (wieder der Netzwerkweg), mit 16 Schreibern viereinhalbmal schneller. Wenn deine Anwendung viele gleichzeitige Schreibzugriffe hat (Chat, Tracking, viele Nutzer, die gleichzeitig Daten speichern), ist das der wichtigste einzelne Grund für PostgreSQL.
Wichtig zur Einordnung: 5.000 Schreibvorgänge pro Sekunde sind sehr viel. Das sind 18 Millionen pro Stunde. Ein Online-Shop mit tausend Bestellungen am Tag, ein Blog mit Kommentaren oder ein internes Werkzeug kommen da nicht einmal in die Nähe. Das Schreib-Limit von SQLite ist real, aber es liegt höher, als die meisten denken.
WAL-Modus: Die wichtigste SQLite-Einstellung
Fast alles, was in diesem Artikel für SQLite gut aussieht, setzt den WAL-Modus voraus (Write-Ahead Log, eingeführt 2010 mit Version 3.7.0). Standardmäßig arbeitet SQLite noch mit dem älteren „Rollback Journal“. Dort blockiert ein Schreiber auch alle Leser. Im WAL-Modus schreiben Änderungen zuerst in eine Zusatzdatei (daten.db-wal), und Leser und der eine Schreiber stören sich nicht mehr.
PRAGMA journal_mode = WAL; -- einmal setzen, bleibt in der Datei gespeichert
PRAGMA busy_timeout = 5000; -- bei jeder Verbindung setzen
PRAGMA synchronous = NORMAL; -- bei jeder Verbindung, wenn du den Kompromiss willst
PRAGMA foreign_keys = ON; -- bei jeder Verbindung, sonst werden Fremdschlüssel ignoriert
Wir haben auf unserem Server nachgeschaut: Alle unsere großen produktiven SQLite-Dateien laufen im WAL-Modus. Das ist kein Zufall, sondern das Ergebnis früherer Fehler.
Achte auf die letzte Zeile: SQLite prüft Fremdschlüssel standardmäßig nicht. Du kannst eine Bestellung für einen Kunden anlegen, den es nicht gibt, obwohl du einen Fremdschlüssel definiert hast. Erst mit PRAGMA foreign_keys = ON (pro Verbindung!) wird er durchgesetzt. Das ist aus Gründen der Rückwärtskompatibilität so und überrascht fast jeden, der von PostgreSQL kommt.
Datentypen: SQLite ist großzügig, PostgreSQL streng
Ein Test, den du in zehn Sekunden selbst machen kannst:
CREATE TABLE t (n INTEGER);
INSERT INTO t VALUES ('hallo');
SELECT n, typeof(n) FROM t;
SQLite speichert das ohne Murren und antwortet hallo|text. In einer Spalte, die du als Ganzzahl angelegt hast, steht jetzt ein Wort. SQLite nennt das „Type Affinity“: Der Spaltentyp ist eher eine Empfehlung. PostgreSQL lehnt denselben Befehl ab: invalid input syntax for type integer: "hallo".
Seit Version 3.37 (2021) gibt es in SQLite STRICT-Tabellen. Mit CREATE TABLE t (n INTEGER) STRICT; verhält sich SQLite wie erwartet und meldet in unserem Test cannot store TEXT value in INTEGER column t.n. Für neue Projekte empfehlen wir, alle Tabellen als STRICT anzulegen. Allerdings: STRICT-Tabellen kennen nur die Typen INTEGER, REAL, TEXT, BLOB und ANY. Ein Datum, eine Uhrzeit, ein Dezimalwert mit fester Nachkommastelle oder ein Wahrheitswert hat in SQLite keinen eigenen Typ. Datumsangaben speicherst du als Text (2026-10-11) oder Zahl, Geldbeträge am besten als Ganzzahl in Cent.
PostgreSQL bringt dagegen eine große Typenwelt mit: numeric für exakte Geldbeträge, timestamptz für Zeitstempel mit Zeitzone, uuid, jsonb mit Index-Unterstützung, Arrays, IP-Adressen, Bereiche, und über Erweiterungen Geodaten (PostGIS) oder Vektoren für KI-Anwendungen (pgvector).
Gute Nachricht: Schemaänderungen sind bei beiden sicher
Ein Punkt, an dem MySQL in unserem letzten Vergleich durchgefallen ist: Wird ein ALTER TABLE innerhalb einer Transaktion zurückgerollt, bleibt die Änderung bei MySQL trotzdem bestehen. SQLite und PostgreSQL rollen beide sauber zurück. Wir haben es getestet: Spalte hinzugefügt, ROLLBACK, Spalte bei beiden wieder weg. Das macht Migrationen bei beiden angenehm sicher.
Eine Einschränkung hat SQLite trotzdem: ALTER TABLE kann nur Spalten hinzufügen, umbenennen und (seit 3.35) löschen. Den Typ einer Spalte ändern oder eine Einschränkung nachträglich hinzufügen geht nicht direkt. Dafür musst du eine neue Tabelle anlegen, die Daten kopieren und die alte ersetzen. Die meisten Migrations-Werkzeuge machen das automatisch, aber bei großen Tabellen dauert es.
Backup: Die Falle, in die fast jeder einmal tappt
SQLite ist eine Datei, also kopierst du sie einfach, oder? Nein. Wir haben das nachgestellt: Datenbank im WAL-Modus, 1.000 Zeilen geschrieben, Datei mit einem normalen Kopierbefehl gesichert, während die Anwendung noch lief.
- Die laufende Datenbank enthielt 1.000 Zeilen.
- Die kopierte Datei enthielt 0 Zeilen.
Der Grund: Die neuen Daten standen noch in der Zusatzdatei -wal und waren noch nicht in die Hauptdatei zurückgeschrieben. Wer nur daten.db kopiert, bekommt einen alten Stand, im schlimmsten Fall eine beschädigte Datei. Das Tückische: Die Kopie lässt sich öffnen, es gibt keine Fehlermeldung, es fehlen einfach Daten.

So sicherst du SQLite richtig:
# Konsistente Kopie, auch während die Anwendung läuft
sqlite3 /pfad/daten.db ".backup /backup/daten-$(date +%F).db"
# Alternative: kompakte Kopie per SQL
sqlite3 /pfad/daten.db "VACUUM INTO '/backup/daten-$(date +%F).db'"
Mit .backup enthielt unsere Kopie alle 1.000 Zeilen. Genau so sichern wir auch unsere eigene wichtigste SQLite-Datei: per .backup, und danach prüft das Skript, ob in der Kopie eine Mindestanzahl Datensätze steht. Eine Kopie, die man nie geöffnet hat, ist kein Backup. Wie du daraus eine vollständige Strategie mit Kopien an verschiedenen Orten baust, steht in unserem Artikel zur 3-2-1-Backup-Strategie.
Für SQLite gibt es außerdem Litestream, ein kleines Programm, das jede Änderung laufend in einen S3-kompatiblen Speicher repliziert. Damit kommst du auf wenige Sekunden Datenverlust im Ernstfall, ohne einen zweiten Datenbank-Server zu betreiben.
Bei PostgreSQL gilt dasselbe Prinzip: Das Datenverzeichnis im laufenden Betrieb einfach zu kopieren ist keine gute Idee. Richtig ist pg_dump für einzelne Datenbanken, pg_basebackup plus WAL-Archivierung für Wiederherstellung auf eine bestimmte Sekunde, oder Werkzeuge wie pgBackRest. Das ist mächtiger, aber auch mehr Arbeit.
Betrieb und Kosten
SQLite: Es gibt nichts zu betreiben. Keine Installation (die Bibliothek steckt in Python, PHP, Node.js, Go-Treibern und fast allem anderen), kein Dienst, kein Port, der abgesichert werden muss, keine Passwörter, keine Updates eines Datenbank-Servers. Die Rechteverwaltung ist das Dateisystem: Wer die Datei lesen darf, darf die Datenbank lesen. Arbeitsspeicher: In unserem Test brauchte der komplette SQLite-Kommandozeilen-Prozess 4,5 MB im Leerlauf und 6,5 MB während einer Abfrage über 2 Millionen Zeilen.
PostgreSQL: Ein eigener Dienst, der installiert, konfiguriert, aktualisiert und überwacht werden will. Mit Docker ist das in wenigen Minuten erledigt (ein fertiges Beispiel findest du in unserem Docker-Compose-Artikel), aber du musst dich um Hauptversions-Upgrades kümmern, die bei PostgreSQL ein pg_upgrade oder einen Dump und Re-Import erfordern. Beim Arbeitsspeicher ist PostgreSQL genügsam: 21 MB im Leerlauf, nach unserem Test 167 MB, weil es Daten im Speicher zwischenspeichert. Wie viel RAM ein Server insgesamt braucht, haben wir in Wie viel RAM braucht ein Server? gemessen.
Kosten: Beide sind kostenlos. Bei verwalteten Angeboten sieht es anders aus. Eine gemanagte PostgreSQL-Datenbank bei einem Cloud-Anbieter kostet schnell 15 bis 50 Euro im Monat zusätzlich, eine SQLite-Datei kostet nichts außer dem Speicherplatz auf dem VPS, den du ohnehin hast.
Speicherplatz: Dieselben Daten belegten bei SQLite 87 MB, bei PostgreSQL 187 MB. PostgreSQL speichert pro Zeile mehr Verwaltungsinformationen (unter anderem für die Versionsverwaltung paralleler Transaktionen) und unser Betrag lag dort als exakter numeric-Wert statt als Gleitkommazahl.
Grenzen von SQLite, ehrlich aufgelistet
Die SQLite-Entwickler selbst sind sehr offen dazu, wofür ihre Datenbank nicht gedacht ist. Zusammengefasst:
- Mehrere Server, die schreiben. Eine SQLite-Datei gehört zu einem Rechner. Für mehrere Anwendungsserver brauchst du einen Datenbank-Server oder Spezialwerkzeuge wie LiteFS oder libSQL/Turso.
- Viele gleichzeitige Schreiber. Siehe Test oben: Es geht, aber nur einer schreibt wirklich gleichzeitig. Lange schreibende Transaktionen blockieren alle anderen Schreiber.
- Sehr große Datenmengen mit schweren Auswertungen. Die theoretische Grenze liegt bei rund 281 Terabyte pro Datei, die praktische Grenze ist eher die fehlende Parallelisierung von Abfragen.
- Netzwerk-Dateisysteme. NFS, SMB und ähnliche haben oft fehlerhafte Dateisperren. Die Folge kann eine beschädigte Datenbank sein.
- Feine Rechteverwaltung. Es gibt keine Benutzer und keine Rechte auf Tabellenebene.
Was keine Grenze ist, obwohl man es oft hört: „SQLite ist nur zum Testen.“ Die offizielle SQLite-Dokumentation nennt als grobe Faustregel, dass Webseiten mit weniger als 100.000 Aufrufen pro Tag problemlos mit SQLite laufen, und betont, dass das eine konservative Schätzung ist. Die SQLite-Webseite selbst läuft auf SQLite.
Was wir selbst einsetzen (und warum)
Bei uns hat sich eine einfache Regel entwickelt:
- SQLite für alles, was auf einem Server läuft und einen überschaubaren Schreibverkehr hat: unser eigenes Analytics-Werkzeug, Statusseiten, Formulare, kleine Spiele-Backends, Preisbeobachter, interne Werkzeuge. Auch unsere größte SQLite-Datei (ein Spiele-Server mit Nachrichten, rund 65 MB plus WAL) läuft seit Monaten stabil. Alle im WAL-Modus, alle mit busy_timeout.
- PostgreSQL für Shop-Software, unser Ticket-System und die Community-Plattform. Also überall dort, wo die Software es verlangt, wo mehrere Dienste auf dieselbe Datenbank zugreifen oder wo wir die strengen Datentypen und Erweiterungen brauchen.
Der häufigste Fehler, den wir früher selbst gemacht haben: Für jedes kleine Projekt reflexartig einen PostgreSQL-Container hochzuziehen. Das ist ein weiterer Dienst, ein weiteres Passwort, ein weiteres Update, ein weiteres Backup, für Projekte, die am Tag ein paar hundert Datensätze schreiben. Der zweithäufigste Fehler in die andere Richtung: SQLite ohne WAL und ohne busy_timeout, und dann wundern, warum unter Last „database is locked“ im Log steht.
SQLite vs PostgreSQL: Für wen sich welche Datenbank lohnt
SQLite ist die richtige Wahl, wenn:
- deine Anwendung auf einem einzigen Server läuft,
- überwiegend gelesen wird und Schreibzugriffe überschaubar sind (Faustregel: deutlich unter einigen tausend pro Sekunde),
- du möglichst wenig Betriebsaufwand willst,
- es um eine Desktop-, Mobil- oder Embedded-Anwendung geht (dort ist SQLite praktisch Standard),
- du Prototypen, Tests oder Datenanalysen auf deinem Rechner machst,
- du Daten als eine Datei weitergeben willst.
PostgreSQL ist die richtige Wahl, wenn:
- mehrere Anwendungsserver oder Dienste auf dieselben Daten zugreifen,
- viele Nutzer gleichzeitig schreiben,
- du schwere Auswertungen über viele Millionen Zeilen machst,
- du strenge Datentypen, Rechteverwaltung oder Erweiterungen wie PostGIS und pgvector brauchst,
- deine Software es voraussetzt,
- du Hochverfügbarkeit mit Replikation und automatischem Umschalten brauchst.

Und später wechseln?
Ein Wechsel von SQLite zu PostgreSQL ist machbar, wenn du ein Framework mit Datenbank-Abstraktion nutzt (Django, Laravel, Rails, Prisma, Drizzle und ähnliche). Werkzeuge wie pgloader übertragen eine SQLite-Datei in einem Befehl nach PostgreSQL. Die typischen Stolpersteine: Daten, die in SQLite den falschen Typ hatten (siehe oben), Datumswerte als Text und Abfragen, die SQLite-spezifische Funktionen nutzen. Wenn du von Anfang an STRICT-Tabellen nutzt und Fremdschlüssel einschaltest, ist der spätere Umzug deutlich einfacher.
Checkliste: SQLite oder PostgreSQL in fünf Fragen
- Läuft die Anwendung auf mehr als einem Server? Ja → PostgreSQL.
- Schreiben regelmäßig viele Nutzer oder Prozesse gleichzeitig? Ja, dauerhaft hunderte pro Sekunde und mehr → PostgreSQL.
- Brauchst du große Auswertungen, Geodaten, Vektoren oder strenge Typen? Ja → PostgreSQL.
- Verlangt deine Software eine bestimmte Datenbank? Dann nimm die.
- Nichts davon trifft zu? → SQLite, mit WAL, busy_timeout, foreign_keys=ON, STRICT-Tabellen und einem Backup per
.backup.
Häufige Fragen zu SQLite vs PostgreSQL
Ist SQLite schneller als PostgreSQL?
Bei einzelnen, kleinen Abfragen ja, und zwar deutlich: In unserem Test rund zwanzigmal, weil der Netzwerkweg wegfällt. Bei großen Auswertungen über Millionen Zeilen ist PostgreSQL drei- bis zehnmal schneller, und bei vielen gleichzeitigen Schreibern ebenfalls.
Kann man SQLite in Produktion einsetzen?
Ja, wenn die Anwendung auf einem Server läuft und der Schreibverkehr überschaubar ist. Wichtig sind WAL-Modus, busy_timeout, eingeschaltete Fremdschlüssel und ein konsistentes Backup. Wir betreiben selbst rund 30 produktive SQLite-Datenbanken.
Wie viele Nutzer schafft SQLite?
Das hängt nicht an der Zahl der Nutzer, sondern an den Schreibvorgängen. Lesen skaliert sehr gut. Beim Schreiben schafften wir mit 16 gleichzeitigen Prozessen rund 4.900 Einfügungen pro Sekunde. Die offizielle Faustregel nennt Webseiten mit bis zu 100.000 Aufrufen pro Tag als unproblematisch, und das ist eher vorsichtig.
Was bedeutet „database is locked“?
Ein anderer Prozess schreibt gerade, und SQLite hat nicht gewartet. Lösung: PRAGMA busy_timeout = 5000; bei jeder Verbindung setzen, WAL-Modus einschalten, schreibende Transaktionen kurz halten und mit BEGIN IMMEDIATE starten.
Brauche ich für SQLite einen Server?
Nein. SQLite ist eine Bibliothek, die in deine Anwendung eingebaut ist. Die Datenbank ist eine Datei. Du brauchst nur den Rechner, auf dem deine Anwendung ohnehin läuft.
Kann ich eine SQLite-Datei einfach kopieren, um ein Backup zu machen?
Nur wenn die Anwendung gestoppt ist. Im laufenden Betrieb fehlen sonst Daten aus der WAL-Datei, in unserem Test enthielt die Kopie 0 statt 1.000 Zeilen. Nutze sqlite3 daten.db ".backup ziel.db" oder VACUUM INTO.
Ist SQLite sicher?
SQLite selbst ist sehr gründlich getestet und sehr stabil. Es hat aber keine Benutzer und Passwörter: Wer die Datei lesen kann, kann alle Daten lesen. Sicherheit kommt also über die Dateirechte. Verschlüsselung gibt es nur über Erweiterungen wie SQLCipher.
Wie groß darf eine SQLite-Datenbank werden?
Theoretisch rund 281 Terabyte. In der Praxis laufen Datenbanken mit vielen Gigabyte problemlos. Die eigentliche Grenze ist eher, dass große Auswertungen nicht parallelisiert werden und Schemaänderungen bei großen Tabellen lange dauern.
Was ist mit Turso, libSQL, LiteFS oder Cloudflare D1?
Das sind Projekte, die SQLite um Replikation über mehrere Server oder Standorte erweitern. Spannend für verteilte Anwendungen, aber jeweils mit eigenem Betriebsmodell und eigenen Kompromissen. Für ein Projekt auf einem Server brauchst du sie nicht.
Wie wechsle ich von SQLite zu PostgreSQL?
Mit pgloader lässt sich eine SQLite-Datei direkt in PostgreSQL übertragen. Vorher solltest du prüfen, ob in Spalten Werte mit falschem Typ stehen, und Datumsangaben vereinheitlichen. Mit einem ORM musst du im Code oft nur die Verbindungsadresse ändern.
Welche Datenbank ist besser für Anfänger?
Zum Lernen von SQL ist SQLite unschlagbar: nichts installieren, eine Datei öffnen, loslegen. Programme wie DB Browser for SQLite zeigen die Daten grafisch an. PostgreSQL lohnt sich als nächster Schritt, sobald du Server-Anwendungen baust.
Fazit
SQLite vs PostgreSQL ist weniger eine Frage von „besser“ und „schlechter“ als von Architektur. SQLite ist eine Datei in deiner Anwendung, unschlagbar einfach und bei kleinen Abfragen rund zwanzigmal schneller als PostgreSQL. PostgreSQL ist ein Server, der viele gleichzeitige Schreiber, mehrere Anwendungsserver und große Auswertungen souverän bewältigt.
Unsere Empfehlung: Starte kleine und mittlere Projekte auf einem Server mit SQLite, aber richtig eingestellt (WAL, busy_timeout, Fremdschlüssel, STRICT, .backup). Nimm PostgreSQL, sobald mehrere Server, viele gleichzeitige Schreiber oder schwere Auswertungen ins Spiel kommen. Und wenn du zwischen PostgreSQL und MySQL schwankst, hilft dir unser Vergleich PostgreSQL vs MySQL weiter.