PRODSouveräne europäische BaaS-PlattformÖffnen Sie das Dashboard →

Leistung · 9 Min. Lesezeit

Postgres max_connections ohne Pooler

Affane Daylami · Fondateur · 6. Juni 2026

Zurück zum Blog

Ohne Pooling vor Ihrem Server sollte max_connections alle offenen Clientverbindungen gleichzeitig abdecken und nicht die Anzahl der Anfragen, die Postgres parallel effizient verarbeiten kann. Die Verwechslung dieser beiden Zahlen ist die häufigste Ursache für falsch eingestellte max_connections: zu niedrig, um die Last aufzunehmen, oder zu hoch für den tatsächlich verfügbaren Speicher.

Dieser englische Text wurde automatisch aus dem französischen Original generiert und wurde noch nicht überprüft.
Diese Seite wurde automatisch übersetzt. Maßgeblich ist die englische Version.

Dieser Artikel enthält die vom PostgreSQL-Wiki veröffentlichte Formel zur Berechnung der idealen Parallelität Ihrer Hardware (die am häufigsten zitierte Verbindungspool-Größenformel im Ökosystem), erklärt, warum jede Verbindung mehr kostet als ein Anwendungsthread, und beschreibt dann die Vorgehensweise zum Festlegen von max_connections ohne zu raten. Unsere Benchmark-Methodik dokumentiert das Messprotokoll, das für alle Leistungsansprüche in diesem Blog verwendet wird.

Das Wesentliche

  • Ohne Pooling sollte max_connections alle gleichzeitigen Clientverbindungen abdecken, nicht nur diejenigen, die Postgres effizient parallel verarbeiten kann.
  • PostgreSQL-Wiki-Referenzformel: ideale aktive Parallelität = (physische Kerne × 2) + effiziente Festplatten. Ein durch Messung zu validierender Ausgangspunkt, keine feste Grenze.
  • max_connections ist ein postmaster-Kontextparameter: Für seine Änderung ist ein vollständiger Neustart des Servers erforderlich, kein einfaches Neuladen.
  • Jede Postgres-Verbindung ist ein separater Systemprozess und kein leichtgewichtiger Thread: Dies macht den Overhead deutlich, sobald die Anzahl der Verbindungen steigt.
  • Im Code verifiziert: Auf seinen dedizierten Postgres-Clustern variiert Aurabase max_connections von 50 (kostenlose Stufe) bis 400 (Enterprise-Stufe), abhängig von der Größe des Clusters.
#
Diagnose

Warum eine Postgres-Verbindung mehr kostet als ein Anwendungsthread

Postgres verwendet für seine Verbindungen keinen Lightweight-Thread-Pool. Jede Client-Verbindung löst einen vollwertigen Systemprozess aus.

Der postmaster-Prozess erstellt für jeden Verbindungsversuch einen neuen („Fork“), der dieser einzelnen Sitzung gewidmet ist, bis sie geschlossen wird. Die offizielle Projektdokumentation beschreibt genau diesen Mechanismus in ihrem Kapitel über Architekturgrundlagen (postgresql.org/docs/current/connect-estab.html, Abschnitt „Verbindungssemantik“, abgerufen am 24. August 2026).

Diese Wahl hat einen echten Vorteil: Ein Absturz einer Verbindung hat keine Auswirkungen auf die anderen, da jeder Prozess vom Rest des Servers isoliert ist. Es verursacht auch direkte Kosten: Jede zusätzliche Verbindung fügt einen gesamten Betriebssystemprozess zur Planung hinzu, mit eigenem Speicherplatz und eigenem Kontextwechsel-Overhead für den Kernel.

Was es in der Praxis verändert

Eine Anwendung, die 500 direkte Verbindungen zu Postgres ohne Pooling öffnet, zwingt den Server, 500 gleichzeitige Systemprozesse zu verwalten, selbst wenn die überwiegende Mehrheit davon zwischen zwei Anfragen inaktiv bleibt.

#
Speicherkosten

Was eine Verbindung tatsächlich verbraucht: Shared Memory und Work_Mem

Zwei unterschiedliche Mechanismen wirken sich auf das Gedächtnis aus und ihre Verwechslung führt fast immer zu einer Fehldiagnose.

Das erste ist behoben. Beim Start reserviert Postgres gemeinsam genutzte Speicherstrukturen (Sperren, Prozesstabelle), deren Größe dem Wert von max_connections entspricht, unabhängig davon, ob diese Verbindungen anschließend geöffnet werden oder nicht. In der offiziellen Dokumentation der Einstellung wird ausdrücklich darauf hingewiesen, dass eine Erhöhung möglicherweise mehr gemeinsam genutzten Systemspeicher erfordert, als die Standardkonfiguration Ihres Betriebssystems zulässt (postgresql.org/docs/current/runtime-config-connection.html, abgerufen am 24. August 2026).

Die zweite Möglichkeit ist variabel und im Maßstab viel gefährlicher: work_mem wird nicht einmal pro Verbindung zugewiesen, sondern einmal pro Sortier- oder Hashing-Vorgang im Abfrageplan. Die offizielle Dokumentation ist in diesem Punkt explizit: Eine komplexe Abfrage kann mehrere dieser Vorgänge parallel starten, und mehrere Sitzungen können dasselbe gleichzeitig tun, sodass der tatsächlich verwendete Speicher ein Mehrfaches von work_mem wert sein kann (postgresql.org/docs/current/runtime-config-resource.html, abgerufen am 24. August 2026).

Der wirklich schlimmste Fall, an den man sich erinnern sollte

Es ist nicht allein max_connections × work_mem, das den Speicher eines Servers bedroht. Es ist max_connections × work_mem × Anzahl gleichzeitiger Vorgänge pro Abfrage. Es ist dieses Produkt, das einen Server erklärt, der nach einer als harmlos angesehenen Erhöhung der max_connections auswechselt oder ihm der Speicher ausgeht.

#
Formel

Die PostgreSQL-Wiki-Größenformel

Das offizielle PostgreSQL-Projekt-Wiki dokumentiert eine Benchmark-Formel zur Berechnung, wie viele aktive -Verbindungen Ihre Hardware effizient parallel verarbeiten kann, und nicht, wie viele Verbindungen insgesamt geöffnet sind (wiki.postgresql.org/wiki/Number_Of_Database_Connections, abgerufen am 24. August 2026).

Die Formel

ideale aktive Parallelität = (physische Kerne × 2) + effiziente Festplatten. Die Anzahl der Kerne schließt Hyperthreading aus. Die Anzahl der effektiven Festplatten bleibt bei modernen SSD-Speichern nahe bei 1, wobei der Begriff einer separaten physischen Festplatte („Spindel“) viel von seiner ursprünglichen Bedeutung verliert.

Auf einem Server mit 8 physischen Kernen und SSD-Speicher ergibt die Formel (8 × 2) + 1 = 17 aktive Verbindungen, bevor der Durchsatz nachzulassen beginnt. Diese Zahl ist oft überraschend: Im Vergleich zu den Hunderten von Verbindungen, die eine Anwendung in der Praxis öffnet, erscheint sie winzig. Genau darum geht es im folgenden Absatz.

Die durch die Formel berechnete Zahl misst die Parallelität, die die CPU und die Festplatte aufnehmen können, und nicht die Anzahl der Clientverbindungen, die Ihre Anwendung öffnen muss. Eine Flotte von 20 Anwendungsprozessen, von denen jeder über einen eigenen Pool von 10 Verbindungen verfügt, öffnet 200 gleichzeitige Verbindungen zu Postgres, auch wenn jeweils nur 17 davon aktiv arbeiten. Ohne Pooler muss max_connections die 200 abdecken, nicht die 17. Es ist diese Lücke, die die meisten Architekturen dazu drängt, einen -Pooler im Transaktionsmodushinzuzufügen, auch wenn das bedeutet, dass man sich für einen entscheiden muss (siehe unseren -Vergleich PgBouncer, Supavisor und PgCat).

#
Vorgehensweise

So ändern Sie max_connections (und warum ein Neustart erforderlich ist)

max_connections wird nicht im laufenden Betrieb ausgetauscht. Dies ist ein postmaster-Kontextparameter: Postgres liest ihn einmal beim Start, um die Größe seines gemeinsam genutzten Speichers zu bestimmen. Ein Neuladen der Konfiguration (pg_reload_conf() oder SIGHUP) reicht nicht aus, Sie müssen den Server neu starten.

Überprüfen Sie zunächst den aktuellen Wert und seinen Kontext, um sicherzustellen, dass ein Neustart erforderlich ist:

psqlsql
SHOW max_connections;

SELECT name, setting, context
FROM pg_settings
WHERE name = 'max_connections';

-- context='postmaster' bestätigt, dass ein Neustart erforderlich ist

Wenden Sie dann den neuen Wert an und starten Sie neu:

psqlsql
ALTER SYSTEM SET max_connections = '300';

-- Geschrieben in postgresql.auto.conf.
-- Keine Auswirkung, bis Postgres neu gestartet wird.
terminalbash
# Mit systemd
sudo systemctl restart postgresql

# Ohne systemd, direkt mit pg_ctl
pg_ctl restart -D $PGDATA -m fast
Eine Marge, die viele vergessen

max_connections enthält standardmäßig superuser_reserved_connections (standardmäßig 3): Diese Verbindungen sind im Falle einer Sättigung für einen Superuser reserviert, sie sind für Ihre Anwendung nie verfügbar, auch wenn der globale Zähler noch nicht erreicht ist.

#
Code eingecheckt

Wie Aurabase max_connections auf seinen Postgres-Clustern budgetiert

Die Dimensionierung von max_connections ist nicht nur eine theoretische Übung. So budgetiert Aurabase seine verwalteten Postgres-Cluster:

100
POSTGRES-STANDARD
max_connections vor jeder Optimierung
50→400
SPEZIELLE AURABASE-LAGER
Kostenlos für Unternehmen, per CNPG-Cluster
3
SUPERUSER RESERVIERT
superuser_reserved_connections, Postgres-Standard

Dedizierte Cluster: ein Postgres-Cluster pro Projekt

Auf dieser Ebene (siehe unseren Vergleich dediziert vs. gemeinsam genutzte Basis) erhält jedes Projekt seinen eigenen CloudNativePG-Cluster und sein eigenes max_connections-Budget, dessen Größe sich an der Größe der Instanz orientiert:

kostenlos (gewidmet)max_connections 501 Instanz · 500 m vCPU · 512 Mi
Profi (Standard)max_connections 2002 Instanzen · 1 vCPU · 2Gi
Teammax_connections 3003 Instanzen · 2 vCPU · 3Gi
Geschäftmax_connections 4003 Instanzen · 2 vCPU · 4Gi

Gemeinsame Cluster: mehrere Projekte einer Organisation, ein gemeinsames Budget

Auf diesem zweiten Pfad verbinden sich alle Projekte derselben Organisation über einen CNPG-Pooler (PgBouncer, transaction-Modus) vor einem gemeinsam genutzten Primärserver:

kostenlosmax_connections 50max_client_conn 100max_user_connections 20
Profimax_connections 100max_client_conn 200max_user_connections 60
Teammax_connections 200max_client_conn 400max_user_connections 150

Alle Projekte in einer Organisation sind über eine gemeinsame Anwendungsrolle miteinander verbunden. Daher begrenzt allein max_user_connections die Gesamtzahl der Serververbindungen, die diese Rolle im gesamten Cluster öffnen kann: Dies ist der eigentliche Cluster-globale Schutz, nicht max_client_conn, der nur Clientverbindungen zum Pooler selbst begrenzt.

Dieser Pooler bedient jedoch nur den SDK-Anwendungsverkehr. PostgREST bleibt seinerseits direkt mit dem primären Dienst (-rw) verbunden: Das Pooling im Transaktionsmodus würde seinen Schema-Neulademechanismus zerstören, der auf einen dedizierten LISTEN-Kanal namens pgrstlauscht. Seine eigenen Verbindungen (2 pro Replikat auf der gemeinsam genutzten Ebene, 10 pro Replikat auf der dedizierten Ebene) zählen daher direkt im max_connections-Budget des Primärservers, außerhalb jedes Poolers, genau die Art von „vergessener“ Verbindung, die Schritt 1 des folgenden Verfahrens umfassen muss.

Zahlen werden derzeit kalibriert, daher wird davon ausgegangen

Der Code dokumentiert diese Shared-Pooler-Budgets explizit als Startwerte, die unter realen Bedingungen durch Messung von pg_stat_activity unter Last zu kalibrieren sind, und nicht als feste Zahlen aus einem veröffentlichten Benchmark. Dies ist die gleiche Disziplin, die in unserer -Benchmark-Methodikbeschrieben wird: Erst messen, dann anpassen, nicht raten, dann hoffen. Diese Cluster laufen auf PostgreSQL 16, eine Auswahl, die in unserem Vergleich Postgres 16 vs. 17 vs. 18dokumentiert ist.

#
Methode

Das 5-stufige Verfahren zur Größenbestimmung von max_connections ohne Pooling

Dieses Verfahren ist nicht von einem bestimmten Tool abhängig: Es gilt für jeden verwalteten oder selbst gehosteten Postgres-Server.

  1. Zählen Sie Ihre tatsächlichen Clientverbindungen. Anzahl der Anwendungsprozesse multipliziert mit der Größe ihres internen Pools, plus Verwaltungstools, Replikation und Überwachung. Es ist diese Zahl, nicht die Formel, die die Untergrenze für max_connections festlegt.
  2. Berechnen Sie die ideale Parallelität Ihrer Hardware mit der Formel aus dem PostgreSQL-Wiki: (physische Kerne × 2) + effiziente Festplatten. Diese Zahl gibt an, wie viele dieser Verbindungen tatsächlich parallel arbeiten können, ohne dass der Durchsatz beeinträchtigt wird.
  3. Legen Sie „max_connections“ über dem tatsächlichen Bedarf für Schritt 1 fest, mit Spielraum für superuser_reserved_connections und für alle Admin-Tools, die ihre eigenen Verbindungen außerhalb der Anwendung öffnen.
  4. Übernehmen Sie die Änderung mit ALTER SYSTEM SET und starten Sie dann den Server neu. Dies ist ein Postmaster-Parameter: Ein einfaches Neuladen reicht nicht aus, wie oben beschrieben.
  5. Überwachen Sie pg_stat_activity im Laufe der Zeit. Wenn die Anzahl der inaktiven Verbindungen die Anzahl der aktiven Verbindungen bei weitem übersteigt, handelt es sich nicht um ein max_connections-Problem: Es ist das Signal, dass Sie einen Pooler vor dem Server benötigen, nicht eine höhere Zahl.

Die Überwachungsanfrage aus Schritt 5, direkt nutzbar:

psqlsql
SELECT state, count(*)
FROM pg_stat_activity
GROUP BY state
ORDER BY count(*) DESC;
#
Warnsignal

Wenn die Formel nicht mehr reicht: Die Anzeichen dafür, dass Sie einen Pooler brauchen

Drei Signale kehren systematisch zurück, wenn max_connections allein nicht mehr ausreicht, unabhängig von ihrem Wert.

  1. Der Fehler FATAL: sorry, too many clients already tritt während der Spitzenlast auf, während sich die meisten von pg_stat_activity angezeigten Verbindungen im Ruhezustand befinden.
  2. Die Anwendung läuft in einer serverlosen Umgebung oder mit kurzlebigen Workern (Edge-Funktionen, kurze Jobs), die Verbindungen viel schneller öffnen und schließen, als das Prozess-pro-Verbindung-Modell von Postgres dafür ausgelegt ist.
  3. Die obige Formel und das obige Verfahren wurden bereits angewendet, und der tatsächliche Bedarf an Clientverbindungen übersteigt weiterhin den verfügbaren Speicher, der zugewiesen werden kann, ohne work_mem oder shared_buffers zu gefährden.

In diesen drei Fällen ist die richtige Antwort fast immer ein Pooler zwischen der Anwendung und Postgres und kein höherer max_connections. Unser -Vergleich PgBouncer, Supavisor und PgCat beschreibt die drei Optionen im Detail, und unser -Leitfaden zum Transaktionsmodus erklärt den häufigsten Kompromiss, sobald der Pooler vorhanden ist. Informationen zu allen Postgres-Tunings, die über Verbindungen hinausgehen, finden Sie in unserer Produktions-Postgres-Tuning-Checkliste.

#
Häufig gestellte Fragen

FAQs

Was ist die Standard-max_connections von PostgreSQL?+
100, wobei standardmäßig 3 Verbindungen für den Superuser reserviert sind (superuser_reserved_connections). Diese Standardeinstellung eignet sich für viele Anwendungen, die einen Pooler durchlaufen, wird jedoch ohne Pooling schnell unzureichend, sobald eine Flotte von Anwendungsprozessen jeweils ihren eigenen Verbindungsstapel öffnet.
Können wir max_connections ändern, ohne PostgreSQL neu zu starten?+
Nein. max_connections ist ein Postmaster-Kontextparameter: Postgres liest ihn einmal beim Start, um die Größe seines gemeinsam genutzten Speichers zu bestimmen. ALTER SYSTEM SET schreibt den neuen Wert in postgresql.auto.conf, wird aber nur bei einem vollständigen Serverneustart angewendet. ein Nachladen oder ein SIGHUP reichen nicht aus.
Wie viel Speicher verbraucht eine inaktive PostgreSQL-Verbindung?+
Es gibt keine einheitliche offizielle Zahl: Sie hängt von work_mem, shared_buffers und den pro Sitzung geladenen Erweiterungen ab. Dokumentiert ist jedoch, dass work_mem pro Sortier- oder Hashing-Vorgang in einer Abfrage zugewiesen wird, nicht pro Verbindung: Eine einzelne komplexe Abfrage kann daher work_mem mehrmals auf einer einzelnen aktiven Verbindung verbrauchen.
Sollten wir immer einen Pooler wie PgBouncer einem höheren max_connections vorziehen?+
In den meisten Fällen ja, sobald die Anzahl der tatsächlichen Clientverbindungen die durch die PostgreSQL-Wiki-Formel berechnete ideale Parallelität deutlich übersteigt. Ein Transaktionsmodus-Pooler bündelt eine kleine Anzahl physischer Verbindungen zwischen einer viel größeren Anzahl logischer Verbindungen auf der Anwendungsseite. Sehen Sie sich unseren Vergleich von PgBouncer, Supavisor und PgCat an, um herauszufinden, welches.
Was genau misst die Formel (Kerne × 2) + effiziente Festplatten?+
Es schätzt die ideale aktive Parallelität: die Anzahl der Anfragen, die die CPU und die Festplatte eines bestimmten Servers parallel verarbeiten können, ohne den Durchsatz zu beeinträchtigen, und nicht die Gesamtzahl der in max_connections zu öffnenden Verbindungen. Dies ist ein Ausgangspunkt, der durch Messungen validiert werden muss und im offiziellen Wiki des PostgreSQL-Projekts dokumentiert ist, und kein fester Grenzwert.
Woher weiß ich, ob mein Postgres-Server fast sein Verbindungslimit erreicht hat?+
Fragen Sie pg_stat_activity ab und vergleichen Sie die Anzahl der Verbindungen im aktiven Zustand mit denen im Ruhezustand. Eine große Anzahl inaktiver Verbindungen in der Nähe der max_connections-Obergrenze, ohne dass eine aktive Anfrage dahinter steckt, weist fast immer darauf hin, dass eine Bündelung erforderlich ist, und nicht darauf, dass max_connections weiter erhöht werden muss.

BEREIT ZUM EINSATZ?

Ihr Backend in fünf Minuten.

Keine Kreditkarte erforderlich · 500 MB kostenlos · 50.000 MAU