Dit artikel vergelijkt de architectuur van de drie poolers: taal, poolingmodi, single- of multi-tenantmodel, functies die verder gaan dan pure pooling. Tembo en PkgPulse hebben numerieke vergelijkingen van deze drie tools gepubliceerd, maar we hebben zelf geen van hun metingen gereproduceerd. Ons redactionele standpunt over benchmarks, beschreven in onze benchmarkmethodologie, is om nooit een cijfer opnieuw te publiceren dat we niet zelf hebben geverifieerd. Wat je hier in plaats daarvan zult vinden: de daadwerkelijke architectuur van elke tool, en hoe Aurabase zijn Postgres-verkeer feitelijk routeert, sectie voor sectie geverifieerd in de broncode.
- PgBouncer (C) blijft de meest beproefde pooler en het beste geïntegreerd met Kubernetes: CloudNativePG vertrouwt er rechtstreeks op voor zijn
Pooler-bron. - Supavisor (Elixir, Supabase project) richt zich op een ander probleem: het bedienen van duizenden databases vanuit dezelfde dienst, in plaats van één pooler per database.
- PgCat (Rust) voegt applicatie-sharding, taakverdeling tussen replica's en automatische failover toe aan raw-pooling.
- De Aurabase-repository toont PgBouncer die op twee niveaus wordt gebruikt: een gedeelde implementatie voor de gedeelde vloot en een
Pooler-bron beheerd door CloudNativePG per specifieke tenant. Beide werken in transactiemodus. - PostgREST en de
aura-db-beheerpool blijven vrijwillig in directe verbinding met Postgres, zonder via de pooler te gaan: transactiepooling zou het herladen van hun schema's en hun sessievergrendelingen verbreken.
Drie poolers, drie filosofieën
PgBouncer minimaliseert Supavisor-pools op multi-tenant-schaal, PgCat voegt netwerkfuncties toe aan raw-pooling. Geen van de drie is een directe vervanging voor de andere twee, hoewel ze vaak term voor term op dezelfde pagina's worden vergeleken.
| Taal | C | Elixer (BEAM) | Roest |
|---|---|---|---|
| Pooling-modi | Sessie, transactie, verklaring | Sessie, transactie | Sessie, transactie, verklaring |
| Huurmodel | Eén doelcluster per exemplaar, ontworpen als single-tenant | Native multi-tenant: een dienst voor veel databases | Een doelcluster, geshard op partitiesleutel |
| Verder dan poolen | Geen extra functies, bewust minimaal | Beheerder HTTP API, dynamische huurderregistratie | Sharding, taakverdeling en failover tussen replica's |
| Native Kubernetes-integratie | Ja: CloudNativePG Resource Pooler | Tot op heden niet native gedocumenteerd | Tot op heden niet native gedocumenteerd |
| Oorsprong | De historische standaard van Postgres-pooling | Gebouwd door Supabase voor zijn eigen multi-tenant cloud | Geboren bij Instacart, vandaag onderhouden door PostgresML |
Kolommen, in volgorde: PgBouncer, Supavisor, PgCat. Architectuurkenmerken volgens de officiële documenten van elk project, te bevestigen op de versie die u implementeert; het ecosysteem evolueert snel op dit punt.
De historische standaard, lichtgewicht en geïntegreerd in Kubernetes
PgBouncer doet maar één ding: Postgres-verbindingen poolen, zonder enige extra functies. Deze opzettelijk beperkte reikwijdte verklaart grotendeels de lange levensduur en de acceptatie ervan als basisbouwsteen in de meeste Postgres-stacks in productie.
Er zijn drie poolingmodi beschikbaar. De sessiemodus opent één serververbinding per clientverbinding, de meest toegestane. De transactiemodus gebruikt een serververbinding tussen verschillende clients, die aan elk einde van een transactie wordt vrijgegeven. De Statement-modus gaat zelfs nog verder en wordt zelden gebruikt in de productie. Het is de transactiemodus die de echte poolwinst oplevert, maar deze legt strikte regels op. Elke sessiestatus (SETvariabelen, adviesvergrendelingen, LISTEN/NOTIFY) blijft niet bestaan na een transactie. We beschrijven deze regels en hun valkuilen in ons speciale artikel over de transactiepoolingmodus van PgBouncer.
Historisch gezien bestaat een PgBouncer-instantie uit één proces en gebruikt standaard één enkele CPU-kern. Het uitvoeren van meerdere instances achter dezelfde poort (via SO_REUSEPORT) is een recentere evolutie van het project, en geen initiële ontwerpfunctie. Aan de authenticatiekant ondersteunt PgBouncer een configureerbare auth_query, een SQL-functie die bij elke verbinding wordt uitgevoerd om het wachtwoord van een rol dynamisch op te lossen. Dit mechanisme vermijdt dat u afhankelijk bent van een statisch bestand waarin elke gebruiker vooraf wordt vermeld. Het is precies dit mechanisme dat Aurabase gebruikt voor zijn per-project-rollen (paragraaf 05).
PgBouncer is de pooler die CloudNativePG native implementeert achter zijn Pooler-bron. Op een Postgres-cluster beheerd door de CloudNativePG-operator komt het activeren van een beheerde pooler in de praktijk neer op het activeren van PgBouncer zonder deze handmatig te configureren.
De cloud-native multi-tenant pooler van Supabase
Supavisor pakt een probleem aan waarvoor PgBouncer nooit op deze schaal is ontworpen. Dit omvat het bedienen van een zeer groot aantal afzonderlijke tenantdatabases vanuit één enkele service, in plaats van één pooler-instantie per database. Het project is geschreven in Elixir en uitgevoerd op de Erlang virtuele machine (BEAM) en wordt ontwikkeld en onderhouden door Supabase, in open source, op zijn eigen GitHub-repository.
Het native multi-tenantmodel is het echte structurele verschil. Waar een klassieke PgBouncer-vloot één proces (of een reeks speciale verbindingen) per doelbasis vereist, werkt Supavisor anders. Het registreert tenants dynamisch via een HTTP-beheerinterface en stuurt elke inkomende verbinding naar de juiste database zonder de service opnieuw te starten. Juist om deze reden heeft Supabase haar eigen Cloud projecten gemigreerd van PgBouncer naar Supavisor. Een klassiek poolingcluster, één per database, schaalt niet naar een multi-tenant cloud die honderdduizenden projecten host.
Deze architectonische keuze heeft een gedocumenteerde keerzijde. Het kostte tijd om de pariteit van de functies met PgBouncer in geavanceerde gevallen te stabiliseren na de lancering van het project. Twee voorbeelden: bepaald gedrag van LISTEN/NOTIFYen het fijne beheer van voorbereide afschriften in de transactiemodus. Controleer uw versie vóór de migratie als uw toepassing afhankelijk is van dit specifieke gedrag.
De Rust-buitenstaander: native sharding en taakverdeling
PgCat wordt expliciet gepositioneerd als alternatief voor PgBouncer, geschreven in Rust. Het voegt netwerkfuncties toe aan de klassieke pooling die noch PgBouncer, noch Supavisor native insluiten. Drie in het bijzonder: toepassingssharding op basis van partitiesleutel, taakverdeling tussen leesreplica's en automatische failover weg van een mislukte replica. Het project ontstond bij Instacart voordat het vandaag werd overgenomen en onderhouden door PostgresML.
Concreet kan PgCat de rol spelen die twee afzonderlijke lagen normaal gesproken zouden vervullen: een verbindingspooler en een applicatieproxy voor routering tussen verschillende Postgres-instanties. Een team dat zijn gegevens al met de hand deelde, kan zijn code vereenvoudigen met PgCat. Hetzelfde geldt voor een logica voor het distribueren van leesbewerkingen tussen intern ontwikkelde replica's: een speciale netwerklaag vervangt deze rechtstreeks.
Het tegenovergestelde compromis bestaat ook: PgCat is een jonger project, met een veel kleiner ecosysteem van documentatie en productiefeedback dan PgBouncer. Het adopteren van de sharding- en failover-functies betekent ook dat je ermee instemt afhankelijk te zijn van de volwassenheid van dit specifieke onderdeel, en niet alleen van de poolingcapaciteit ervan.
Wat de Aurabase-code laat zien: PgBouncer overal, behalve waar transactiepooling alles kapot maakt
De Aurabase-repository implementeert PgBouncer op twee afzonderlijke niveaus, beide in transactiemodus. Voor de gedeelde vloot definieert het Helm-diagram een speciale PgBouncer-implementatie vóór het gedeelde datavlak (deploy/helm/aurabase/templates/infra/pgbouncer.yaml, afbeelding edoburu/pgbouncer). Voor een tenant op een speciaal exemplaar genereert de inrichting een bron Pooler die systeemeigen wordt beheerd door CloudNativePG (deploy/cnpg/tenant-pooler.yaml, weergegeven door k8s_tenant.rs). Geen van beide maakt gebruik van Supavisor of PgCat. De code documenteert geen expliciete vergelijking die aan deze keuze voorafging. Aan de andere kant toont het een diepe en reeds operationele integratie met het CloudNativePG-ecosysteem, consistent met het feit dat PgBouncer de native pooling brick is.
Niet alles gaat echter via de pooler, en dit is een bewuste keuze die in de code zelf is gedocumenteerd. PostgREST blijft live verbonden met Postgres, nooit via PgBouncer. Het Helm-diagramcommentaar is expliciet over de reden: transactiepooling zou het herladen van het schema verbreken, wat afhankelijk is van een LISTEN op het pgrstkanaal. Dit mechanisme is niet compatibel met gerecyclede serververbindingen tussen clients. Deaura-db-beheerpool (schema, DDL, sessie-adviesvergrendelingen) blijft om dezelfde fundamentele reden ook in directe verbinding. Niet-transactiegerichte SET search_path en sessievergrendelingen overleven een transactiemoduspooler niet.
Authenticatie volgt het auth_query-patroon dat wordt beschreven in sectie 02: AUTH_QUERY: SELECT * FROM pgbouncer.user_lookup($1), zonder een statisch userlist.txt-bestand. Hierdoor kunnen rollen die dynamisch per project zijn gemaakt (project_<uuid>_authenticator) worden geverifieerd via PgBouncer zonder de pooler voor elk nieuw project opnieuw te implementeren.
De PgBouncer-gezondheidscontrolecommentaar in de lokale Kubernetes manifesteert een echte bug, die al is opgelost. Een pg_isready-run tegen PgBouncer valideert alleen de proxy-handshake, nooit de daadwerkelijke verbinding met de Postgres-backend die deze doorgeeft. PgBouncer reageert met het accepteren van verbindingen, zelfs als de backend is gestopt en de verzoeken in de wachtrij worden geplaatst. Resultaat waargenomen tijdens een destructieve test: de service bleef healthy gedurende 5 opeenvolgende cycli terwijl Postgres onbereikbaar was. De oplossing vervangt de controle door een echt end-to-end psql-verzoek via de pooler, helemaal tot aan de backend. Resultaat na correctie, in dezelfde herhaalde test: unhealthy gedetecteerd in 7 cycli, ongeveer 35 seconden.
Nog een laatste detail, klein maar onthullend: de Helm-kaart pint standaard edoburu/pgbouncer:v1.24.1-p1, terwijl de lokale k3d-bench v1.25.2-p0gebruikt. Het is geen architecturale keuze, maar een klein gebrek aan versiesynchronisatie tussen twee omgevingen, het soort details dat een codebeoordeling sneller opmerkt dan een blogpost. We documenteren het zoals het is, in plaats van het te verkleden. Zie ons artikel overmulti-tenant RLS-isolatievoor meer informatie over de schemapartitionering die door deze pooler wordt gebruikt.
Hoe je tussen de drie kunt kiezen
Kies PgBouncer als…
- Postgres-cluster beheerd door CloudNativePG of Kubernetes in het algemeen
- U wilt de meest bewezen en goed gedocumenteerde pooler
- Een doelbasis per poolerinstantie past bij u
Kies Supavisor als…
- Honderden of duizenden bases achter dezelfde dienst
- Moet tenants dynamisch registreren via een API, zonder herimplementatie
- Zit al in het Supabase-ecosysteem of is bereid hiervan afhankelijk te zijn
Kies PgCat als…
- Het delen van applicaties is al aanwezig of gepland op poolerniveau
- Load-balancing en failover-replica zonder afzonderlijke applicatielaag
- Comfortabel met een jonger project, minder gedocumenteerd dan PgBouncer
Welke pooler er ook wordt gekozen, deze vervangt niet de maatvoering van Postgres zelf. Poolgrootte en server max_connections moeten samen worden bedacht, niet na elkaar. Een royaal zwembad voor een te lage max_connections verschuift eenvoudigweg de verzadiging van het ene niveau naar het andere. Onze gids over afstemmen van max_connections beschrijft de maatformule die u moet toepassen voordat u de grootte van uw zwembad instelt.
Wat ons het vaakst wordt gevraagd
Er is geen universele pooler, alleen een goede match voor uw huurovereenkomst
PgBouncer, Supavisor en PgCat lossen drie varianten van hetzelfde probleem op, niet drie versies van dezelfde tool. PgBouncer blijft de veiligste keuze wanneer uw platform al afhankelijk is van Kubernetes en CloudNativePG, of wanneer u simpelweg de meest gedocumenteerde pooler wilt. Supavisor wordt relevant vanaf een bepaald aantal bases die vanuit dezelfde dienst bedienen. PgCat is de omweg waard als u sharding en replica failover op netwerkniveau mist, op voorwaarde dat u de volwassenheid van een jonger project accepteert.
De Aurabase-code toont een consistente, niet neutrale, keuze: PgBouncer in transactiemodus, op twee niveaus, gedeelde vloot en CNPG-pooler per toegewijde huurder. Er blijven twee gedocumenteerde uitzonderingen bestaan, voor PostgREST en voor schemabeheer. Als u dit project in silo's in actie wilt zien in plaats van op papier, documenteert onze pagina Prestaties de bijbehorende meetmethodologie.