mirror of
https://github.com/supabase/supabase.git
synced 2026-10-09 03:15:06 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Docs update. Restructure, mostly moved lines, plus inbound anchor fixes. ## What is the current behavior? The page states the same routing decision four times and never states an answer: - Intro bullets - A matrix table - A "How to choose the right connection method?" section - A Mermaid flowchart An agent asked "I'm deploying to Vercel serverless functions, set up the database connection" has to synthesize an answer from four partial, inconsistent restatements. Context, procedure, and reference material are interleaved throughout, so background reading interrupts the action path. The page is also too long at 2,883 words, and grouping alone doesn't fix that. Explainer and reference material need their own page, and the troubleshooting group belongs in troubleshooting entries. 16 of the 19 inbound anchor links to this page are already broken on `master`, before any restructure: `#direct-connections`, `#shared-pooler`, `#connection-pooler`, `#how-connection-pooling-works`, `#quick-summary`, `#connection-pool`, and `#connecting-with-drizzle`. Groundwork for [DOCS-1312](https://linear.app/supabase/issue/DOCS-1312). The issue stays open until the paired eval is re-run. ## What is the new behavior? Group the guide into a decision, a procedure, context, reference, and troubleshooting, per CONTRIBUTING § Guides on mixed information types. Review with `git diff --color-moved=zebra`. - Lead with "Which connection method do you use?", a decision table keyed on where your code runs. Section navigation sits directly below the intro. - Collect every connection string under "Get your connection string", with the shared Connect dialog steps stated once as a procedure. - Move the endpoint, port, pool size, and connection limit material into "Connection reference". These were FAQ questions. - Split the page. The guide keeps the decision, the connection strings, and the quickstarts, at 1,180 words and three paths. A new child page, Connection pooling and limits, carries how pooling works, pool size, connection limits, and monitoring. - Move the endpoint and IP version table up beside the connection strings it explains. - Replace the troubleshooting group with two new troubleshooting entries, `tenant-or-user-not-found` and `fatal-password-authentication-failed`, plus links to the existing entries. The existing connection-refused entry is stronger than what was here: it names the IP ban and gives the unban procedure. - Cut the pool size worked example. It said a pool size of 30 is a shared ceiling across session and transaction mode, while the Supavisor FAQ and the terminology entry both say pool size is per user, database, and mode combination. That text came from `master`, so the contradiction is pre-existing. Link the FAQ as the authority rather than picking a side. - Drop the duplicate `pg_stat_ssl` query, which already exists in `connection-management.mdx` and `monitor-supavisor-postgres-connections.mdx`, both with column tables this page lacked. - Add the subsection to the navigation, which also adopts `connecting-to-postgres/serverless-drivers`. That page existed on disk and was referenced nowhere in the navigation constants. - Delete the decision flowchart. It was the fourth restatement of the decision table, and its logic was broken: `Persistent Backend` had two unconditional edges into decision nodes that each had one unlabeled output, so neither node decided anything. - Fix every broken inbound anchor, and pin stable anchors on the headings they target. This now includes six files in `apps/www` that no earlier pass in this stack checked, most of which were already broken on `master`. - Repoint the Studio Connect sheet's Drizzle link at the Drizzle guide. It pointed at a heading this page hasn't had for some time. - Serverless drivers: state the guide's intent, give the three runtimes parallel structure, and link the transaction mode prepared statements constraint. That page never mentioned the constraint that most affects serverless connections. ## Additional context PR 2 of 2. Base is #49868, rebased on its review feedback commit. Three of the 13 files are in `apps/studio`, so this runs the Studio unit tests, build, and lint ratchet. They are link string changes only. The ESLint warning count is unchanged at 1 on the touched files, so the ratchet holds. ## Manual testing 1. Open [Connect to your database](https://docs-git-docs-connecting-to-postgres-structure-supabase.vercel.app/docs/guides/database/connecting-to-postgres) on the deploy preview. 2. Check the table of contents. The top level reads: Which connection method do you use?, Get your connection string, Quickstarts, Related. The intro lists three paths. 3. Open [Reports](https://docs-git-docs-connecting-to-postgres-structure-supabase.vercel.app/docs/guides/monitoring-and-debugging/reports) and follow "Implement connection pooling" under Disk IO. It lands on the decision table. 4. Open [Serverless drivers](https://docs-git-docs-connecting-to-postgres-structure-supabase.vercel.app/docs/guides/database/connecting-to-postgres/serverless-drivers). The intro links the transaction mode prepared statements constraint. 5. Check the sidebar. Connecting to your database expands to Connection pooling and limits and Serverless drivers. 6. Open [Connection pooling and limits](https://docs-git-docs-connecting-to-postgres-structure-supabase.vercel.app/docs/guides/database/connecting-to-postgres/pooling-and-limits). Pool size states the setting and links the Supavisor FAQ, with no worked example. 7. Open [Tenant or user not found](https://docs-git-docs-connecting-to-postgres-structure-supabase.vercel.app/docs/guides/troubleshooting/tenant-or-user-not-found). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added a dedicated guide covering connection pooling, limits, configuration, and monitoring. * Added troubleshooting guides for password authentication failures and shared pooler tenant or user errors. * Expanded connection guidance with method selection, endpoints, IP versions, and serverless driver configuration. * **Documentation** * Reorganized database connection documentation and navigation. * Updated related links throughout the documentation to current connection and pooling guidance. * Improved guidance for pooler modes, connection strings, and supported deployment environments. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
109 lines
7.6 KiB
Plaintext
109 lines
7.6 KiB
Plaintext
---
|
|
title: 'Connection pooling and limits'
|
|
description: 'How connection pooling works, and the limits that apply to your connections'
|
|
subtitle: 'How Supabase pools database connections, and the limits that apply to them.'
|
|
---
|
|
|
|
Learn how to choose between connection modes, size a pool, and work out why you're running out of connections. To get connected, see [Connect to your database](/docs/guides/database/connecting-to-postgres).
|
|
|
|
## How connection pooling works [#how-connection-pooling-works]
|
|
|
|
Connection pooling improves database performance by reusing existing connections between queries. This reduces the overhead of establishing connections and improves scalability.
|
|
|
|
A Postgres connection is a long-lived session. Once established, it stays open until the client disconnects, or until the server or the network closes it. A server might make a single 10 ms query but hold its database connection for seconds or longer.
|
|
|
|
A pooler sits between clients and the database and shares a small set of database connections across many clients, so a connection isn't tied up while a client sits idle.
|
|
|
|
<Image
|
|
alt="A direct connection reserves one database connection per client. A connection pooler shares a smaller set of database connections across many clients."
|
|
src={{
|
|
dark: '/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works.png',
|
|
light:
|
|
'/docs/img/guides/database/connecting-to-postgres/how-connection-pooling-works--light.png',
|
|
}}
|
|
width={1851}
|
|
height={907}
|
|
caption="Connecting to the database directly compared with using a connection pooler"
|
|
/>
|
|
|
|
### Application-side and server-side poolers [#application-side-poolers]
|
|
|
|
There are two kinds, and they work together.
|
|
|
|
**Application-side poolers** are built into connection libraries and API servers, such as Prisma, SQLAlchemy, and Postgres.js. They keep a few connections open and reuse them. On a persistent backend, such as a long-running container or VM, an application-side pooler is enough on its own.
|
|
|
|
**Server-side poolers**, such as Supavisor in transaction mode, run in front of the database and serve many clients. Use one when connections come from serverless or edge functions, or from anything that scales horizontally. These environments open many short-lived connections, which is the case an application-side pooler can't cover.
|
|
|
|
For more on when each is needed and how to size them, see the [Supavisor FAQ](/docs/guides/troubleshooting/supavisor-faq-YyP5tI).
|
|
|
|
### Shared and dedicated poolers [#shared-pooler]
|
|
|
|
Supabase offers two poolers. The shared pooler, [Supavisor](https://github.com/supabase/supavisor), is multi-tenant, available on every project, and IPv4-only. The dedicated pooler, [PgBouncer](https://www.pgbouncer.org/), is available on paid plans and runs alongside your Postgres instance. Like the direct connection, it is on IPv6, or on IPv4 if the project has the [IPv4 add-on](/docs/guides/platform/ipv4-address).
|
|
|
|
The dedicated pooler runs on the same machine as your database, so it connects with lower latency than the shared pooler, which runs on a separate server. It also uses more of your project's compute resources. If your network supports IPv6, or you have the IPv4 add-on, use the dedicated pooler instead of the shared pooler. Direct connections have no pooler overhead, but they require IPv6 unless you have the IPv4 add-on.
|
|
|
|
In most cases, choose either PgBouncer or Supavisor for pooled or transaction-based traffic. Direct connections remain the best choice for long-lived sessions, and shared pooler session mode is the alternative when those sessions need IPv4. Run both poolers at once only when you need to raise the total number of concurrent client connections, and expect a higher risk of hitting your database's maximum connection limit on smaller compute sizes.
|
|
|
|
## Connection limits
|
|
|
|
### Pool size [#pooler-pool-size]
|
|
|
|
Pool size sets how many connections a pooler is allowed to open to Postgres. You can adjust it in [Database settings](/dashboard/project/_/database/settings) in the Supabase Dashboard.
|
|
|
|
Supavisor and PgBouncer read the same setting but apply it independently, so raising it raises the ceiling for both.
|
|
|
|
For what the setting counts, and how it interacts with the user, database, and mode combinations connecting to your project, see [the Supavisor FAQ](/docs/guides/troubleshooting/supavisor-faq-YyP5tI).
|
|
|
|
### Client connections and backend connections [#client-connections-and-backend-connections]
|
|
|
|
There are two limits to understand when working with poolers.
|
|
|
|
| Limit | What it counts | What sets it |
|
|
| ------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
| Client connections | How many clients can connect to a pooler at the same time | Your [compute size's max pooler clients limit](/docs/guides/platform/compute-and-disk#postgres-replication-slots-wal-senders-and-connections) |
|
|
| Backend connections | How many active connections a pooler opens to Postgres | The pool size for that pooler |
|
|
|
|
Both limits apply independently to Supavisor and PgBouncer. One pooler reaching its client limit doesn't affect the other. When a pooler reaches this limit, it stops accepting new client connections until existing ones close.
|
|
|
|
```txt
|
|
Direct connections +
|
|
Supavisor backend connections +
|
|
PgBouncer backend connections
|
|
< Postgres max connections for your compute instance
|
|
```
|
|
|
|
Stay below the maximum rather than at it. Supabase services hold their own connections, including Auth, Storage, PostgREST, and the health checker, and those come out of the same total. [Managing connections](/docs/guides/database/connection-management) covers how much headroom to leave.
|
|
|
|
For the connection counts that come with each compute size, see [compute and disk](/docs/guides/platform/compute-and-disk#postgres-replication-slots-wal-senders-and-connections). For the terminology, see [Supavisor and connection terminology explained](/docs/guides/troubleshooting/supavisor-and-connection-terminology-explained-9pr_ZO).
|
|
|
|
### Monitor connection usage [#monitor-connection-usage]
|
|
|
|
Track connection usage in the [Observability](/dashboard/project/_/observability/database) section of the Supabase Dashboard. There are three reports:
|
|
|
|
- **Database Connections:** total active connections by role, including direct and pooled connections.
|
|
- **Dedicated Pooler Client Connections:** active client connections to PgBouncer.
|
|
- **Shared Pooler (Supavisor) Client Connections:** active client connections to Supavisor.
|
|
|
|
These reports are not real-time. They show the connection count from the last refresh. For up-to-the-second data, query `pg_stat_activity` in the SQL Editor:
|
|
|
|
```sql
|
|
-- Count connections by application and user name
|
|
select
|
|
count(usename),
|
|
count(application_name),
|
|
application_name,
|
|
usename
|
|
from
|
|
pg_stat_ssl
|
|
join pg_stat_activity on pg_stat_ssl.pid = pg_stat_activity.pid
|
|
group by usename, application_name;
|
|
```
|
|
|
|
To list every connection with its state and query, and to read which Supabase service each role belongs to, see [Managing connections](/docs/guides/database/connection-management#observing-live-connections).
|
|
|
|
## Related
|
|
|
|
- [Connect to your database](/docs/guides/database/connecting-to-postgres)
|
|
- [Managing connections](/docs/guides/database/connection-management)
|
|
- [Supavisor FAQ](/docs/guides/troubleshooting/supavisor-faq-YyP5tI)
|