Dieser Artikel vergleicht die Architektur der drei Pooler: Sprache, Pooling-Modi, Single- oder Multi-Tenant-Modell, Funktionen über das reine Pooling hinaus. Tembo und PkgPulse haben numerische Vergleiche dieser drei Tools veröffentlicht, wir haben jedoch keine ihrer Messungen selbst reproduziert. Unser redaktioneller Standpunkt zu Benchmarks, der in unserer Benchmark-Methodik detailliert beschrieben wird, besteht darin, niemals eine Zahl erneut zu veröffentlichen, die wir nicht selbst überprüft haben. Was Sie stattdessen hier finden: die tatsächliche Architektur jedes Tools und wie Aurabase seinen Postgres-Verkehr tatsächlich weiterleitet, Abschnitt für Abschnitt im Quellcode überprüft.
- PgBouncer (C) bleibt der bewährteste Pooler und lässt sich am besten in Kubernetes integrieren: CloudNativePG verlässt sich für seine
Pooler-Ressource direkt darauf. - Supavisor (Elixir, Supabase-Projekt) zielt auf ein anderes Problem ab: die Bereitstellung tausender Datenbanken über denselben Dienst und nicht über einen Pooler pro Datenbank.
- PgCat (Rust) fügt Anwendungs-Sharding, Lastausgleich zwischen Replikaten und automatisches Failover zum Raw-Pooling hinzu.
- Das Aurabase-Repository zeigt, dass PgBouncer auf zwei Ebenen verwendet wird: eine gemeinsame Bereitstellung für die gemeinsame Flotte und eine von CloudNativePG verwaltete
Pooler-Ressource pro dediziertem Mandanten. Beide arbeiten im Transaktionsmodus. - PostgREST und der Verwaltungspool
aura-dbbleiben freiwillig in direkter Verbindung mit Postgres, ohne den Pooler zu durchlaufen: Das Transaktionspooling würde das Neuladen ihres Schemas und ihre Sitzungssperren unterbrechen.
Drei Pooler, drei Philosophien
PgBouncer minimiert, Supavisor poolt im Multi-Tenant-Maßstab, PgCat fügt dem Raw-Pooling Netzwerkfunktionen hinzu. Keiner der drei ist ein direkter Ersatz für die anderen beiden, obwohl sie oft Begriff für Begriff auf denselben Seiten verglichen werden.
| Sprache | C | Elixier (STRAHL) | Rost |
|---|---|---|---|
| Pooling-Modi | Sitzung, Transaktion, Anweisung | Sitzung, Transaktion | Sitzung, Transaktion, Anweisung |
| Mietmodell | Ein Zielcluster pro Instanz, der als Einzelmandant konzipiert ist | Native Multi-Tenant: ein Dienst für viele Datenbanken | Ein Zielcluster, Sharding nach Partitionsschlüssel |
| Über das Pooling hinaus | Keine zusätzlichen Funktionen, bewusst minimal | Admin-HTTP-API, dynamische Mieterregistrierung | Sharding, Lastausgleich und Failover zwischen Replikaten |
| Native Kubernetes-Integration | Ja: CloudNativePG Resource Pooler | Bisher nicht nativ dokumentiert | Bisher nicht nativ dokumentiert |
| Herkunft | Der historische Standard des Postgres-Poolings | Entwickelt von Supabase für seine eigene Multi-Tenant-Cloud | Geboren bei Instacart, heute gepflegt von PostgresML |
Spalten in der Reihenfolge: PgBouncer, Supavisor, PgCat. Architekturmerkmale gemäß den offiziellen Einreichungen jedes Projekts, die anhand der von Ihnen bereitgestellten Version bestätigt werden müssen. Das Ökosystem entwickelt sich in diesem Punkt schnell weiter.
Der historische Standard, leichtgewichtig und in Kubernetes integriert
PgBouncer macht nur eines: Postgres-Verbindungen bündeln, ohne zusätzliche Funktionen. Dieser bewusst enge Anwendungsbereich erklärt größtenteils seine Langlebigkeit und seine Verwendung als Grundbaustein in den meisten Postgres-Stacks in der Produktion.
Es stehen drei Pooling-Modi zur Verfügung. Der Sitzungsmodus öffnet eine Serververbindung pro Clientverbindung, was die freizügigste ist. Im Transaktionsmodus wird eine Serververbindung zwischen mehreren Clients wiederverwendet, die an jedem Ende einer Transaktion freigegeben wird. Der Anweisungsmodus geht noch weiter und wird in der Produktion selten verwendet. Es ist der Transaktionsmodus, der den eigentlichen Pooling-Gewinn bringt, aber er legt strenge Regeln fest. Jeder Sitzungsstatus (SET-Variablen, Empfehlungssperren, LISTEN/NOTIFY) bleibt nicht über eine Transaktion hinaus bestehen. Wir beschreiben diese Regeln und ihre Fallstricke in unserem speziellen Artikel über den -Transaktions-Pooling-Modus von PgBouncer.
In der Vergangenheit war eine PgBouncer-Instanz ein einzelner Prozess und nutzte standardmäßig einen einzelnen CPU-Kern. Das Ausführen mehrerer Instanzen hinter demselben Port (über SO_REUSEPORT) ist eine neuere Weiterentwicklung des Projekts und kein anfängliches Designmerkmal. Auf der Authentifizierungsseite unterstützt PgBouncer eine konfigurierbare auth_query, eine SQL-Funktion, die bei jeder Verbindung ausgeführt wird, um das Passwort einer Rolle dynamisch aufzulösen. Dieser Mechanismus vermeidet die Abhängigkeit von einer statischen Datei, in der jeder Benutzer im Voraus aufgelistet wird. Genau diesen Mechanismus nutzt Aurabase für seine projektbezogenen Rollen (Abschnitt 05).
PgBouncer ist der Pooler, den CloudNativePG nativ hinter seiner Ressource Poolerbereitstellt. Auf einem Postgres-Cluster, der vom CloudNativePG-Betreiber verwaltet wird, kommt die Aktivierung eines verwalteten Poolers in der Praxis der Aktivierung von PgBouncer gleich, ohne ihn manuell zu konfigurieren.
Der cloudnative Multi-Tenant-Pooler von Supabase
Supavisor geht ein Problem an, für dessen Lösung PgBouncer in dieser Größenordnung nie konzipiert wurde. Dies beinhaltet die Bereitstellung einer sehr großen Anzahl unterschiedlicher Mandantendatenbanken über einen einzigen Dienst und nicht über eine Pooler-Instanz pro Datenbank. Das in Elixir geschriebene und auf der Erlang Virtual Machine (BEAM) ausgeführte Projekt wird von Supabase als Open Source in seinem eigenen GitHub-Repository entwickelt und verwaltet.
Der eigentliche strukturelle Unterschied ist das native Multi-Tenant-Modell. Während eine klassische PgBouncer-Flotte einen Prozess (oder eine Reihe dedizierter Verbindungen) pro Zielbasis erfordert, funktioniert Supavisor anders. Es registriert Mieter dynamisch über eine HTTP-Verwaltungsschnittstelle und leitet jede eingehende Verbindung an die richtige Datenbank weiter, ohne den Dienst neu zu starten. Aus genau diesem Grund hat Supabase seine eigenen Cloud-Projekte von PgBouncer auf Supavisor migriert. Ein klassischer Pooling-Cluster, einer pro Datenbank, lässt sich nicht auf eine mandantenfähige Cloud skalieren, die Hunderttausende Projekte hostet.
Diese architektonische Wahl hat einen dokumentierten Nachteil. Es dauerte einige Zeit, bis sich die Funktionsgleichheit mit PgBouncer in fortgeschrittenen Fällen nach dem Projektstart stabilisierte. Zwei Beispiele: bestimmte Verhaltensweisen von LISTEN/NOTIFYund die Feinverwaltung vorbereiteter Anweisungen im Transaktionsmodus. Überprüfen Sie Ihre Version vor der Migration, wenn Ihre Anwendung von diesen spezifischen Verhaltensweisen abhängt.
Der Rust-Außenseiter: natives Sharding und Load-Balancing
PgCat wird ausdrücklich als Alternative zu PgBouncer positioniert, das in Rust geschrieben ist. Es fügt dem klassischen Pooling Netzwerkfunktionen hinzu, die weder PgBouncer noch Supavisor nativ einbetten. Drei im Besonderen: Anwendungs-Sharding nach Partitionsschlüssel, Lastausgleich zwischen Lesereplikaten und automatisches Failover weg von einem ausgefallenen Replikat. Das Projekt wurde bei Instacart geboren, bevor es heute von PostgresML übernommen und gepflegt wird.
Konkret kann PgCat die Rolle spielen, die normalerweise zwei unterschiedliche Schichten einnehmen würden: ein Verbindungspooler und ein Anwendungsproxy für das Routing zwischen mehreren Postgres-Instanzen. Ein Team, das seine Daten bereits manuell fragmentiert hat, kann seinen Code mit PgCat vereinfachen. Das Gleiche gilt für eine Logik zur Verteilung von Lesevorgängen zwischen intern entwickelten Replikaten: Eine dedizierte Netzwerkschicht ersetzt sie direkt.
Es gibt auch den gegenteiligen Kompromiss: PgCat ist ein jüngeres Projekt mit einem viel kleineren Ökosystem an Dokumentation und Produktionsfeedback als PgBouncer. Die Übernahme der Sharding- und Failover-Funktionen bedeutet auch, dass man sich auf die Reife dieser spezifischen Komponente und nicht nur auf deren Pooling-Kapazität verlassen muss.
Was der Aurabase-Code zeigt: PgBouncer überall, außer dort, wo Transaktionspooling alles kaputt macht
Das Aurabase-Repository stellt PgBouncer auf zwei separaten Ebenen bereit, beide im Transaktionsmodus. Für die gemeinsam genutzte Flotte definiert das Helm-Diagramm eine dedizierte PgBouncer-Bereitstellung vor der gemeinsam genutzten Datenebene (deploy/helm/aurabase/templates/infra/pgbouncer.yaml, Bild edoburu/pgbouncer). Für einen Mandanten auf einer dedizierten Instanz generiert der Provisioner eine Ressource Pooler, die nativ von CloudNativePG verwaltet wird (deploy/cnpg/tenant-pooler.yaml, gerendert von k8s_tenant.rs). Weder verwendet Supavisor noch PgCat. Der Code dokumentiert keinen expliziten Vergleich, der dieser Auswahl vorausging. Andererseits zeigt es eine tiefe und bereits operative Integration mit dem CloudNativePG-Ökosystem, was mit der Tatsache übereinstimmt, dass PgBouncer der native Pooling-Baustein ist.
Allerdings läuft nicht alles über den Pooler, und dies ist eine bewusste Entscheidung, die im Code selbst dokumentiert ist. PostgREST bleibt live mit Postgres verbunden, niemals über PgBouncer. Der Helm-Chart-Kommentar geht explizit auf den Grund ein: Das Transaktionspooling würde das Neuladen des Schemas unterbrechen, das von einem LISTEN auf dem pgrst-Kanal abhängt. Dieser Mechanismus ist mit recycelten Serververbindungen zwischen Clients nicht kompatibel. Aus dem gleichen Grund bleibt auch deraura-db-Verwaltungspool (Schema, DDL, Sitzungsberatungssperren) in direkter Verbindung. Nicht transaktionsbezogene SET search_path- und Sitzungssperren überleben einen Transaktionsmodus-Pooler nicht.
Die Authentifizierung folgt dem in Abschnitt 02 beschriebenen auth_query-Muster: AUTH_QUERY: SELECT * FROM pgbouncer.user_lookup($1), ohne eine statische userlist.txt-Datei. Dies ermöglicht es dynamisch pro Projekt erstellten Rollen (project_<uuid>_authenticator), sich über PgBouncer zu authentifizieren, ohne den Pooler für jedes neue Projekt erneut bereitzustellen.
Der PgBouncer-Gesundheitscheck-Kommentar in den lokalen Kubernetes-Manifesten dokumentiert einen echten Fehler, der bereits behoben ist. Ein pg_isready-Lauf gegen PgBouncer validiert nur den Proxy-Handshake, niemals die tatsächliche Verbindung zum Postgres-Backend, die er weiterleitet. PgBouncer antwortet mit „Annehmen von Verbindungen“, selbst wenn das Backend gestoppt ist, und stellt die Anfragen in die Warteschlange. Während eines destruktiven Tests beobachtetes Ergebnis: Der Dienst blieb 5 aufeinanderfolgende Zyklen lang healthy, während Postgres nicht erreichbar war. Der Fix ersetzt die Prüfung durch eine echte End-to-End-psql-Anfrage über den Pooler bis hin zum Backend. Ergebnis nach der Korrektur, im selben Test wiederholt: unhealthy in 7 Zyklen, ca. 35 Sekunden, erkannt.
Ein letztes, kleines, aber aufschlussreiches Detail: Das Helm-Diagramm pinnt standardmäßig edoburu/pgbouncer:v1.24.1-p1, während die lokale k3d-Bank v1.25.2-p0verwendet. Dabei handelt es sich nicht um eine architektonische Entscheidung, sondern nur um einen geringfügigen Mangel an Versionssynchronisierung zwischen zwei Umgebungen, also um die Art von Details, die bei einer Codeüberprüfung schneller erfasst werden als bei einem Blogbeitrag. Wir dokumentieren es so, wie es ist, anstatt es zu beschönigen. Einzelheiten zur Schemapartitionierung, die dieser Pooler bedient, finden Sie in unserem Artikel übermehrinstanzenfähige RLS-Isolation.
So wählen Sie zwischen den dreien
Wählen Sie PgBouncer, wenn…
- Von CloudNativePG oder Kubernetes im Allgemeinen verwalteter Postgres-Cluster
- Sie möchten den bewährtesten und am besten dokumentierten Pooler
- Eine Zielbasis pro Pooler-Instanz passt zu Ihnen
Wählen Sie Supavisor, wenn…
- Hunderte oder Tausende von Stützpunkten hinter demselben Dienst
- Mieter müssen dynamisch über eine API registriert werden, ohne erneute Bereitstellung
- Bereits im Supabase-Ökosystem oder bereit, sich darauf zu verlassen
Wählen Sie PgCat, wenn…
- Anwendungsfreigabe ist auf Pooler-Ebene bereits vorhanden oder geplant
- Lastausgleich und Failover-Replik ohne separate Anwendungsschicht
- Fühlt sich wohl mit einem jüngeren Projekt, das weniger dokumentiert ist als PgBouncer
Welcher Pooler auch immer gewählt wird, er ersetzt nicht die Dimensionierung von Postgres selbst. Poolgröße und Server max_connections sollten zusammen betrachtet werden, nicht nacheinander. Ein großzügiger Pool vor einem zu niedrigen max_connections verschiebt einfach die Sättigung von einer Ebene zur anderen. Unser Leitfaden zum Tuning max_connections beschreibt detailliert die Größenformel, die Sie anwenden müssen, bevor Sie die Größe Ihres Pools festlegen.
Was wir am häufigsten gefragt werden
Es gibt keinen universellen Pooler, sondern nur einen, der gut zu Ihrem Mietverhältnis passt
PgBouncer, Supavisor und PgCat lösen drei Varianten desselben Problems, nicht drei Versionen desselben Tools. PgBouncer bleibt die sicherste Wahl, wenn Ihre Plattform bereits auf Kubernetes und CloudNativePG basiert oder Sie einfach den am besten dokumentierten Pooler wünschen. Supavisor wird ab einer bestimmten Anzahl von Stützpunkten relevant, die von demselben Dienst bedient werden. PgCat ist den Umweg wert, wenn Sie Sharding und Replikat-Failover auf Netzwerkebene vermissen, vorausgesetzt, Sie akzeptieren die Reife eines jüngeren Projekts.
Der Aurabase-Code zeigt eine konsistente, nicht neutrale Auswahl: PgBouncer im Transaktionsmodus, auf zwei Ebenen, gemeinsam genutzte Flotte und CNPG-Pooler pro dediziertem Mieter. Es bleiben zwei dokumentierte Ausnahmen bestehen, für PostgREST und für die Schemaverwaltung. Wenn Sie dieses Siloprojekt in Aktion und nicht auf Papier sehen möchten, dokumentiert unsere Seite Leistung die zugehörige Messmethodik.