Zurück zum Blog
Daten
FortgeschrittenFürBackend EngineersData EngineersPlatform Engineers
11 min

Brauchst du eine Vektordatenbank? Postgres vs. dedizierte Engines 2026

Die meisten Teams, die semantische Suche einbauen, brauchen keine separate Vektordatenbank. Ein praktischer Leitfaden 2026: was pgvector wirklich kann, an welchen vier Mechanismen es scheitert und wofür du bei einer dedizierten Engine tatsächlich bezahlst.

vektordatenbankpgvectorpostgres-vektorpineconeopen-source-vektordatenbanksemantische-sucherag
Inhalt

Jedes Team, das semantische Suche einbaut, steht irgendwann an derselben Weggabelung. Die Embeddings funktionieren, der Prototyp beantwortet Fragen, und dann fragt jemand, welche Vektordatenbank in Produktion soll. Der Markt hat eine selbstbewusste Antwort parat — ein Dutzend Anbieter ist dafür finanziert, eine zu liefern.

Die ehrliche Antwort ist unspektakulärer: Die meisten Teams brauchen dafür keine separate Datenbank. Postgres beherrscht approximative Nearest-Neighbor-Suche, seit pgvector existiert, und zwar direkt neben den relationalen Daten, in derselben Transaktion und demselben Backup. Aber „nimm einfach Postgres” ist genauso fauler Rat, denn pgvector stößt tatsächlich an Grenzen — an vier konkreten, mechanischen Stellen, die nichts mit Anbieter-Benchmarks zu tun haben. Dieser Text erklärt diese Mechanismen, damit du erkennst, auf welcher Seite der Linie du stehst.

Brauchst du eine Vektordatenbank? Ein Entscheidungsleitfaden, der Postgres mit pgvector gegen dedizierte Vektor-Engines 2026 stellt.

Was eine Vektordatenbank wirklich tut

Ohne Positionierung bleibt genau eine Aufgabe: Zu einem Abfragevektor die gespeicherten Vektoren zurückgeben, die ihm nach einer Distanzfunktion am nächsten liegen.

Dafür gibt es nur zwei Wege.

Exakte Suche vergleicht die Abfrage mit jedem gespeicherten Vektor. Sie ist konstruktionsbedingt korrekt — perfekte Recall, immer — und ihre Kosten wachsen linear mit der Zeilenzahl. Genau das macht pgvector standardmäßig, ganz ohne Index.

Approximative Suche baut eine Struktur, mit der sich der Großteil der Daten überspringen lässt. Du gewinnst Geschwindigkeit und bezahlst mit Recall: Einige echte nächste Nachbarn werden übersehen. Die pgvector-Dokumentation benennt die Konsequenz unmissverständlich — nach dem Anlegen eines approximativen Index siehst du andere Ergebnisse für dieselben Abfragen.

Dieser Satz verdient mehr Aufmerksamkeit, als er üblicherweise bekommt. Ein approximativer Index ist keine schnellere Variante eines exakten Index. Er ist eine andere Antwort. Jede Vektordatenbank am Markt, gehostet oder selbst betrieben, geht denselben Handel ein; sie unterscheiden sich darin, wie sie ihn verwalten, nicht ob sie ihn eingehen.

Exakte Suche prüft jeden Vektor für perfekte Recall; HNSW baut einen mehrschichtigen Graphen mit dem besten Verhältnis von Geschwindigkeit zu Recall bei höherem Speicherbedarf; IVFFlat clustert Vektoren in Listen, die günstiger zu bauen, pro Recall-Einheit aber schwächer sind.

pgvector bietet zwei approximative Indextypen, und die Wahl dazwischen ist eine echte Engineering-Entscheidung:

  • HNSW baut einen mehrschichtigen Graphen, basierend auf der Arbeit von Malkov und Yashunin zu Hierarchical Navigable Small World Graphs. Besseres Verhältnis von Geschwindigkeit zu Recall, langsamere Builds, mehr Speicher. Da es keinen Trainingsschritt gibt, kannst du den Index auf einer leeren Tabelle anlegen und sie danach befüllen.
  • IVFFlat partitioniert Vektoren in Listen und durchsucht nur die nächstgelegenen. Schnellere Builds, weniger Speicher, schwächere Abfrageleistung bei gleicher Recall. Der Index muss angelegt werden, nachdem die Tabelle repräsentative Daten enthält, weil k-Means über echte Vektoren läuft. Die dokumentierten Startwerte: rows / 1000 Listen bis zu einer Million Zeilen, sqrt(rows) darüber, und etwa sqrt(lists) Probes zur Abfragezeit.

Wenn du aus diesem Abschnitt eine Sache mitnimmst: Die interessante Arbeit bei der Vektorsuche ist das Tuning der Recall, nicht die Anbieterwahl.

Postgres kann das längst

Das ist das komplette Setup, von null bis zur indizierten Ähnlichkeitssuche:

CREATE EXTENSION vector;
CREATE TABLE documents (
id bigserial PRIMARY KEY,
tenant_id int NOT NULL,
body text,
embedding vector(1536)
);
CREATE INDEX ON documents
USING hnsw (embedding vector_cosine_ops);
SELECT id, body
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;

Mehr ist es nicht. Kosinus-Distanz über <=>, daneben L2 (<->), inneres Produkt (<#>), L1 (<+>), Hamming und Jaccard. Wichtig: Du legst pro Distanzfunktion einen eigenen Index an.

Eine Falle, die man früh kennen sollte: Der Index wird nur genutzt, wenn die Abfrage sowohl ORDER BY auf einem Distanzoperator als auch ein LIMIT hat, aufsteigend sortiert. Packst du die Distanz in einen Ausdruck — etwa um sie mit 1 - (embedding <=> $1) DESC in einen Ähnlichkeitswert zu drehen — fällt der Planer stillschweigend auf einen sequenziellen Scan zurück. Die Abfrage liefert weiterhin korrekte Ergebnisse, nur langsam. Das ist die unangenehmste Sorte Bug.

Kostenlos dazu bekommst du den Teil, den Anbieter nicht liefern können, weil er nicht ihr Produkt ist:

  • JOINs. Hol die nächstgelegenen Chunks zusammen mit Dokument-Metadaten, Berechtigungen und Autor in einer Abfrage — statt zwei Roundtrips und einem Merge in der Anwendung.
  • ACID-Transaktionen. Embedding und beschriebene Zeile committen gemeinsam oder gar nicht. Kein Abgleichjob für doppelte Schreibvorgänge.
  • WAL-Replikation und Point-in-Time-Recovery. Vektoren fallen unter die Backup-Strategie, die du ohnehin betreibst.
  • Hybride Suche an einem Ort. Die Postgres-Volltextsuche liefert die lexikalische Hälfte; kombiniere sie per Reciprocal Rank Fusion oder Cross-Encoder mit der Vektordistanz. Beide Muster sind im pgvector-Projekt dokumentiert.

Wer den Entscheidungsleitfaden SQL vs. NoSQL gelesen hat, erkennt dasselbe Argument im neuen Gewand: Ein zweiter Datenspeicher bedeutet ein Konsistenzproblem, das du vorher nicht hattest.

Die Grenze ist der Index, nicht die Tabelle

Das erste harte Limit überrascht, weil es überhaupt nichts mit Skalierung zu tun hat.

Der Typ vector speichert bis zu 16.000 Dimensionen. Ein HNSW- oder IVFFlat-Index verarbeitet 2.000.

Genau in dieser Lücke leben reale Embeddings. OpenAIs text-embedding-3-small liefert 1.536 Dimensionen und lässt sich sauber indizieren. text-embedding-3-large liefert 3.072 — speicherbar, aber kein einfacher vector-Index möglich. Deine Ähnlichkeitssuche wird stillschweigend zum Full Scan.

Die dokumentierten Auswege, grob nach Praxistauglichkeit:

Die Grenze ist der Index, nicht die Tabelle
Option Indizierbare Dimensionen Preis
halfvec halbe Präzision 4.000 Etwas Präzisionsverlust
Binäre Quantisierung 64.000 Reranking auf den Originalvektoren nötig
Subvektor indizieren Modellabhängig Reranking nötig, Modell muss es unterstützen
Weniger Dimensionen anfordern Hängt vom Embedding-Modell ab

halfvec ist meist der stille Gewinner. Es halbiert das Working Set auf dem Weg: Ein vector kostet 4 × Dimensionen + 8 Byte, ein halfvec kostet 2 × Dimensionen + 8. Für eine Million Embeddings mit 1.536 Dimensionen sind das rund 6,2 GB reine Vektordaten gegenüber 3,1 GB — vor dem Index, der zusätzlich dazukommt.

Diese Rechnung ist die ehrliche Art, das zu dimensionieren. Ein Index muss nicht in den Speicher passen, läuft aber deutlich besser, wenn er es tut — und genau dort wird aus „kostenloser Open Source” ein Posten auf deiner Postgres-Rechnung.

Die Filter-Falle

Das ist die Stelle, die Produktionsvorfälle erzeugt — und im Prototyp fast niemand trifft.

Echte Abfragen filtern. Du willst die nächstgelegenen Chunks für diesen Mandanten, in dieser Sprache, nicht archiviert. Das intuitive Modell: Die Datenbank grenzt auf passende Zeilen ein und sucht darin die nächsten Nachbarn.

So läuft es nicht. Bei einem approximativen Index wird der Filter nach dem Index-Scan angewendet.

Die pgvector-Dokumentation liefert die Rechnung direkt: Beim Standardwert hnsw.ef_search von 40 bleiben bei einer Bedingung, die 10 % der Zeilen trifft, im Schnitt etwa 4 Ergebnisse übrig. Du hast die Top 20 angefordert und bekommst 4. Kein Fehler, keine Warnung — nur eine leise unvollständige Antwort, die plausibel genug aussieht, um in Produktion zu gehen.

Die Filter-Falle: Der approximative Index-Scan liefert eine feste Kandidatenliste, danach filtert die WHERE-Klausel, sodass bei selektiven Bedingungen nur eine Handvoll Zeilen übrig bleibt; iterative Scans scannen weiter, bis genug Treffer gefunden sind.

pgvector 0.8.0 hat genau dafür iterative Index-Scans eingeführt, und sie sind opt-in:

SET hnsw.iterative_scan = strict_order;

Der Index scannt weiter, bis genug Ergebnisse vorliegen oder hnsw.max_scan_tuples (Standard 20.000) erreicht ist. strict_order garantiert die exakte Distanzsortierung, relaxed_order erlaubt leicht abweichende Reihenfolge zugunsten besserer Recall.

Zwei strukturelle Alternativen sind oft besser als Tuning:

  • Filter auf wenige unterschiedliche Werte? Nutze einen partiellen Index — CREATE INDEX ... WHERE (category_id = 123). Jeder Index enthält nur seinen eigenen Ausschnitt.
  • Filter auf viele Werte? Partitioniere die Tabelle. Jede Partition bekommt ihren eigenen Index, der Filter wird strukturell statt nachträglich verworfen.

Und wenn die Bedingung nur einen kleinen Prozentsatz der Zeilen trifft, gewinnt die langweilige Antwort: ein schlichter B-Tree-Index auf der Filterspalte und exakte Suche über den Rest. Schnell, exakt korrekt, keine Recall zu tunen. Approximative Indizes verdienen ihr Geld bei breiten Filtern, nicht bei engen — dieselbe Disziplin des „erst messen, dann optimieren” wie bei der SQL-Query-Optimierung.

Wo pgvector wirklich an Grenzen stößt

Vier Mechanismen, kein Bauchgefühl. Wenn keiner davon auf dich zutrifft, hast du kein Vektordatenbank-Problem.

1. Mandantenfähigkeit mit geteiltem Index. Das ist der schärfste Punkt. Teilen sich Mandanten einen approximativen Index, beeinflussen die Vektoren des einen Mandanten die Recall und die Geschwindigkeit der Abfragen des anderen. Das ist kein Bug, sondern die Bedeutung eines geteilten Graphen. Der dokumentierte Ausweg sind Listen-Partitionierung oder eigene Tabellen pro Mandant — machbar bei Dutzenden, unhandlich bei Tausenden und richtig schmerzhaft, wenn Mandanten bei der Registrierung entstehen.

2. Speicherdruck. Der Index muss nicht in den RAM passen, aber du willst es. Wachstum schiebt dich die Instanzgrößenleiter hinauf, und vertikale Skalierung hat eine Obergrenze und eine Preiskurve.

3. Betrieblicher Aufwand bei großen Indizes. Das Vacuuming eines HNSW-Index dauert, und zwar so spürbar, dass die Dokumentation empfiehlt, vorher zu reindizieren. Index-Builds konkurrieren um maintenance_work_mem. In Produktion baust du mit CREATE INDEX CONCURRENTLY, um Schreibvorgänge nicht zu blockieren — was wiederum langsamer ist. Nichts davon ist tödlich, aber es ist echte Arbeit, die nun jemand in deinem Team verantwortet.

4. Horizontale Skalierung. Postgres skaliert bei dieser Last vertikal. Darüber hinaus bleiben Read Replicas oder Sharding mit Citus oder PgDog. Das ist eine legitime Antwort — und zugleich der Punkt, an dem „wir betreiben ohnehin Postgres” aufhört, die einfache Option zu sein.

Bemerkenswert ist, was nicht auf dieser Liste steht: die reine Zeilenzahl. Eine nicht partitionierte Postgres-Tabelle fasst standardmäßig bis zu 32 TB. Der Speicherplatz ist nicht die Einschränkung. Der Index und sein Arbeitsspeicher sind es.

Was eine dedizierte Vektordatenbank tatsächlich verkauft

Nehmen wir Pinecone als Referenz, weil die meisten genau damit vergleichen.

Du kaufst keine bessere Ähnlichkeitsmathematik. Du kaufst:

  • Namespaces. Datensätze werden in Namespaces partitioniert, die beim Schreiben implizit entstehen, und jeder Lese- und Schreibvorgang trifft genau einen. Das ist Mandantenisolation als erstklassiges Primitiv statt als Partitionierungsschema, das du pflegst — bis zu 100.000 Namespaces pro Index in den Plänen Standard und Enterprise.
  • Serverless-Elastizität. Indizes liegen auf verteiltem Objektspeicher. Kapazität ist keine Instanz, die du um 2 Uhr nachts vergrößerst.
  • Metadatenfilterung als entworfenes Feature, mit dem erwartbaren Operatorensatz ($eq, $in, $gte, $and und Verwandte) — allerdings in realen Grenzen: nur flaches JSON, keine verschachtelten Objekte, keine Nullwerte, 40 KB Metadaten pro Datensatz und maximal 10.000 Werte bei $in.
  • Einen Betriebsmodus, den du nicht selbst fährst. Kein Vacuum, kein Reindex-Fenster, kein maintenance_work_mem.

Dazu die Compliance- und Isolationsstufen, die häufig der eigentliche Beschaffungsgrund sind: SOC 2 in allen Plänen, DSGVO und ISO 27001 ab Builder, ein HIPAA-Add-on bei Standard, dedizierte Read Nodes, damit Abfragen sich keine Warteschlange teilen, und Bring-your-own-Cloud bei Enterprise.

Wichtiger als jede Einzelzahl ist die Form der Preisgestaltung. Pinecones Standard-Plan hat ein Monatsminimum von 50 Dollar, danach 0,33 Dollar pro GB Speicher und Monat, Write-Units zu 4 bis 4,50 Dollar pro Million und Read-Units zu 16 bis 18 Dollar pro Million, je nach Cloud und Region. Enterprise startet bei 500 Dollar Minimum mit 99,95 % Uptime-SLA.

Lies diese Struktur genau. Speicher ist billig — eine Million Embeddings mit 1.536 Dimensionen sind einstellige Gigabyte, also ein paar Dollar im Monat. Was deine Rechnung bewegt, sind Read-Units, also Abfragevolumen. Die Kosten einer Vektordatenbank skalieren damit, wie viel du suchst, nicht wie viel du speicherst. Das ist die umgekehrte Intuition zu den meisten Datenbanken — und die Zahl, die du vor einer Migration modellieren solltest.

Die Entscheidung

Entscheidungspfad: Mit Postgres und pgvector starten und erst zu einer dedizierten Vektordatenbank wechseln, wenn ein konkreter Mechanismus bricht — Mandantenisolation im großen Maßstab, Index-Speicher jenseits einer einzelnen Instanz oder ein Betriebsmodus, den du nicht selbst tragen willst.

Die Entscheidung
Signal Postgres + pgvector Dedizierte Vektordatenbank
Embeddings liegen neben relationalen Daten ✅ Gleicher JOIN, gleiche Transaktion ❌ Zwei Speicher abzugleichen
Wenige Mandanten oder statische Mandanten ✅ Partitionierung reicht ➖ Überdimensioniert
Tausende Mandanten, bei Registrierung erzeugt ➖ Schmerzhaft ✅ Namespaces
Index passt in eine bezahlbare Postgres-Instanz ➖ Elastizität, die du nicht nutzt
Abfragevolumen unvorhersehbar oder spitz ➖ Instanz vergrößern ✅ Serverless fängt es ab
Kleines Team ohne Datenbankbetrieb ➖ Vacuum und Reindex sind deins ✅ Fremder Pager
Strikte Mandantenisolation als Compliance-Auflage ➖ Eigene Tabellen oder Instanzen ✅ Erstklassiges Primitiv
Embeddings über 2.000 Dimensionen ➖ halfvec oder Quantisierung ✅ Abgedeckt

Es gibt eine dritte Option, die gern vergessen wird: verwaltetes Postgres mit pgvector. AWS RDS, Google Cloud SQL und AlloyDB sowie Azure Database for PostgreSQL bieten es an — AlloyDB legt zusätzlich seinen eigenen ScaNN-Index darüber. Du bekommst die JOINs und die Transaktionen und einen fremden Pager, ohne einen zweiten Datenspeicher einzuführen. Für einen großen Teil der Teams ist das die eigentlich richtige Antwort — und sie taucht in keinem Anbietervergleich auf, weil sie dir niemand verkauft.

Die ehrliche Antwort

Fang mit Postgres an. Nicht weil es einen Benchmark gewinnt, sondern weil es eine Entscheidung entfernt, für die du noch keine Grundlage hast — und weil die Retrieval-Qualität aus Chunking, Modellwahl und Reranking dein Ergebnis lange vor dem Speicher bestimmt.

Dann miss. pgvector dokumentiert, wie: Führe die Abfrage mit enable_indexscan = off aus, um exakte Ergebnisse zu erhalten, vergleiche sie mit den approximativen — und du hast eine echte Recall-Zahl statt eines Gefühls.

BEGIN;
SET LOCAL enable_indexscan = off; -- exakte Suche, perfekte Recall
SELECT id FROM documents ORDER BY embedding <=> $1 LIMIT 10;
COMMIT;

Wechsle, wenn ein konkreter Mechanismus bricht — Mandantenisolation, aus der du dich nicht herauspartitionieren kannst, ein Index, der nicht mehr in eine Instanz passt, die du bezahlen willst, oder eine Betriebslast, die dein Team nicht tragen sollte. Das sind echte Gründe, und du erkennst sie ohne Diagramm.

Die Migration von pgvector zu einer dedizierten Engine ist später ein ausgetretener Pfad: Du berechnest nichts neu, du kopierst Vektoren und Metadaten. Der teure Fehler ist die Gegenrichtung — vom ersten Tag an eine zweite Datenbank zu betreiben für eine Last, die in eine Tabelle gepasst hätte, und diese Trennung jahrelang in jeder Abfrage, jedem Backup und jedem Vorfall zu bezahlen.

Die Standardantwort auf „brauche ich eine Vektordatenbank?” lautet nein. Wenn du genau weißt, welcher der vier Mechanismen das ändern würde, erkennst du auch den Moment, in dem die Antwort kippt.

Häufig gestellte Fragen

Brauche ich für RAG eine Vektordatenbank?

Am Anfang meistens nicht. Wenn deine Embeddings ohnehin neben relationalen Daten liegen, liefert pgvector die Nearest-Neighbor-Suche in derselben Transaktion, demselben Backup und demselben JOIN. Eine dedizierte Vektordatenbank lohnt sich, wenn du strikte Mandantenisolation im großen Maßstab brauchst, elastische Serverless-Kapazität willst oder über das hinausgewachsen bist, was eine einzelne Postgres-Instanz im Speicher halten kann. Baue zuerst die Retrieval-Qualität — die Speicher-Engine lässt sich später leichter tauschen.

Was ist der Unterschied zwischen HNSW und IVFFlat in pgvector?

HNSW baut einen mehrschichtigen Graphen. Es bietet das bessere Verhältnis von Geschwindigkeit zu Recall und kann auf einer leeren Tabelle angelegt werden, weil es keinen Trainingsschritt gibt — dafür baut es langsamer und braucht mehr Speicher. IVFFlat teilt Vektoren in Listen auf und durchsucht nur die nächstgelegenen. Es baut schneller und braucht weniger Speicher, hat aber bei gleicher Recall die schwächere Abfrageleistung, und es muss angelegt werden, wenn die Tabelle bereits repräsentative Daten enthält, weil es k-Means über echte Vektoren laufen lässt.

Warum liefert meine Abfrage nach dem Anlegen eines Vektor-Index weniger Zeilen?

Weil approximative Indizes in pgvector den WHERE-Filter nach dem Index-Scan anwenden, nicht währenddessen. Beim Standardwert hnsw.ef_search von 40 bleiben bei einer Bedingung, die 10 % der Zeilen trifft, im Schnitt etwa 4 Ergebnisse übrig. Der dokumentierte Ausweg sind iterative Index-Scans ab pgvector 0.8.0, die weiterscannen, bis genug Zeilen gefunden sind. Mit hnsw.iterative_scan auf strict_order bleibt die exakte Distanzsortierung erhalten, relaxed_order erlaubt leichte Umsortierung zugunsten besserer Recall.

Wie viele Dimensionen kann pgvector indizieren?

Der Typ vector speichert bis zu 16.000 Dimensionen, ein HNSW- oder IVFFlat-Index ist jedoch auf 2.000 begrenzt. Das ist praxisrelevant: Ein Vektor von OpenAIs text-embedding-3-large hat 3.072 Dimensionen und lässt sich nicht als einfacher vector indizieren. Dokumentierte Optionen sind halfvec mit bis zu 4.000 Dimensionen in halber Präzision, binäre Quantisierung für bis zu 64.000, die Indizierung von Subvektoren oder schlicht weniger Dimensionen vom Embedding-Modell anzufordern.

Ist pgvector im Vergleich zu Pinecone kostenlos?

Die Erweiterung ist Open Source, die Ressourcen sind es nicht. Ein approximativer Index muss nicht in den Arbeitsspeicher passen, läuft aber deutlich besser, wenn er es tut — du zahlst also in Instanzgröße statt in Abo. Pinecones Standard-Plan hat ein Monatsminimum von 50 Dollar plus Nutzung: 0,33 Dollar pro GB Speicher und Monat sowie Read- und Write-Units pro Million. Bei kleinen Workloads dominiert der Sockelbetrag, im größeren Maßstab wird es eine ehrliche Abwägung zwischen Infrastruktur und Service.

Kann Postgres hybride Suche?

Ja. Postgres hat seit Jahren Volltextsuche, du kannst also eine lexikalische Abfrage im BM25-Stil und eine Vektorähnlichkeitsabfrage über dieselbe Tabelle laufen lassen und beide per Reciprocal Rank Fusion oder Cross-Encoder-Reranker kombinieren. Das pgvector-Projekt dokumentiert beide Muster. Das ist eines der unterschätzten Argumente fürs Bleiben: Die lexikalische Hälfte der hybriden Suche ist bereits da — in derselben Datenbank, unter derselben Transaktion.

Aus der Community

Diskussion im Fediverse

Antworten von Mastodon und Bluesky — direkt aus dem offenen Netz, ohne Tracking.

Antworten werden geladen …

ENDE