mirror of
https://github.com/supabase/supabase.git
synced 2026-10-07 18:35:07 +03:00
Closes FDBKIN-31335 Closes FDBKIN-13040 Closes FDBKIN-8653 Closes FDBKIN-19912 Closes DOCS-740 ## 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. While we are revising this document, this PR gathers docs feedback via AI magic and applies that feedback. ## What is the current behavior? These findings stand on feedback intake rather than on the baseline. Worth doing, and the eval won't show a score change for any of them. - **Nothing explains the pooler host.** #49868 switched the strings to `[POOLER-HOST]`, but the page never says why you can't compose the host, and agents that recite `aws-0` get `Tenant or user not found`. agent-skills#92. - **The page gives the instruction to turn prepared statements off, but not the flag.** It also links the GitHub discussion rather than the troubleshooting entry that mirrors it. FDBKIN-8248, FDBKIN-7883. - **SSL goes undiscussed.** Four of six eval runs set `ssl: 'require'` unprompted. - **The pooled username format only appears inside example strings**, never as a rule. DOCS-740, FDBKIN-19912. - **Third-party tools have no answer.** Session mode is the right one, and the decision table had no row for a BI client or database GUI at all. FDBKIN-8653. - **Only one of transaction mode's three limitations is documented.** FDBKIN-13040 names prepared statements, cursors, and session-level settings. The page covered prepared statements. ## What is the new behavior? - Tell the reader to copy the host, port, and username rather than typing the placeholders, and explain the pooler cluster index next to the reference table. The placeholders themselves changed in #49868. - State the username rule: direct connections and the dedicated pooler use `postgres`, shared pooler connections use `postgres.<project-ref>`. - Add a per-driver prepared statements table for Postgres.js, Drizzle, Prisma, asyncpg, and JDBC, and link [Disabling prepared statements](https://supabase.com/docs/guides/troubleshooting/disabling-prepared-statements-qL8lEL) for the rest. Add JDBC's `prepareThreshold=0` to that entry too, so the two pages agree. - Document SSL: `require` rather than the `prefer` default, which falls back to plaintext. - Link the `CONNECT_TIMEOUT` entry for stale sockets in frozen serverless runtimes. - Add a decision table row for a third-party tool, and point at Quickstarts for named tools. - Cover all three transaction mode limitations. Cursors work inside a single transaction only, and session-level state is lost between transactions: `set` and `reset`, session-level advisory locks, `listen` and `notify`, and temporary tables. Renamed the section from "Prepared statements", since it now covers the cause rather than one symptom. - Promote Configure your client to an H2 and fold the SSL certificate section into it. The table of contents only renders H2 and H3, so the client settings were invisible as H4s. ## Manual testing 1. Open [Connect to your database](https://docs-git-docs-connecting-to-postgres-technical-supabase.vercel.app/docs/guides/database/connecting-to-postgres) on the deploy preview. 2. Read the Get your connection string lead-in. It tells you to copy the host, port, and username rather than typing the placeholders. 3. Check the table of contents. Configure your client is an H2 with Application-side pool size, Prepared statements, SSL, and Stale connections under it. 4. Follow the prepared statements link. It lands on the in-docs troubleshooting entry, not GitHub. 5. Open the [endpoint reference](https://docs-git-docs-connecting-to-postgres-technical-supabase.vercel.app/docs/guides/database/connecting-to-postgres#endpoints-and-ip-versions). The table shows `aws-[INDEX]-[REGION]`, and the prose below explains the index and the username rule. 6. Read the decision table. It has a row for a third-party BI client or database GUI, pointing at session mode. 7. Read [Transaction mode limitations](https://docs-git-docs-connecting-to-postgres-technical-supabase.vercel.app/docs/guides/database/connecting-to-postgres#transaction-mode-limitations). It covers prepared statements, cursors, and session-level state. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Documentation - Expanded the Postgres connection guide with clearer client configuration guidance, including pool sizing, SSL, stale connections, and transaction mode limitations. - Added recommendations for BI tools and database GUIs using the shared pooler. - Clarified connection strings, pooler hosts, usernames, ports, and IP version behavior. - Updated serverless driver guidance for transaction mode configuration. - Added JDBC troubleshooting instructions for disabling prepared statements with `prepareThreshold=0`. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
148 lines
6.0 KiB
Plaintext
148 lines
6.0 KiB
Plaintext
---
|
|
id: 'serverless-drivers'
|
|
title: 'Serverless drivers'
|
|
description: 'Connect to your Postgres database from a serverless environment'
|
|
subtitle: 'Choose a driver for connecting to your Postgres database from a serverless environment.'
|
|
---
|
|
|
|
Learn how to connect to your Postgres database from a serverless environment. The driver you use depends on which runtime your code runs in.
|
|
|
|
[supabase-js](/docs/reference/javascript/introduction) is an isomorphic JavaScript client that uses the [auto-generated REST API](/docs/guides/api), so it works in any environment that supports HTTPS connections. This API has a built-in [connection pooler](/docs/guides/database/connecting-to-postgres/pooling-and-limits#how-connection-pooling-works) and can serve thousands of simultaneous requests, which suits serverless workloads.
|
|
|
|
If you connect with a Postgres client instead, use the [shared pooler in transaction mode](/docs/guides/database/connecting-to-postgres#pooler-transaction-mode), then [configure your client](/docs/guides/database/connecting-to-postgres#configure-your-client) for pool size, prepared statements, and SSL. Those three settings are what most serverless connection problems come down to.
|
|
|
|
## Vercel Edge Functions
|
|
|
|
Vercel's [Edge runtime](https://vercel.com/docs/functions/runtimes/edge-runtime) runs on the [V8 engine](https://v8.dev/) and exposes a limited set of Web Standard APIs.
|
|
|
|
Start from a deploy template, or configure the connection yourself.
|
|
|
|
### Quickstart
|
|
|
|
Choose one of these Vercel Deploy Templates. They use the [Vercel Deploy Integration](https://vercel.com/integrations/supabase) to configure your connection strings as environment variables on your Vercel project.
|
|
|
|
<div>
|
|
<div className="grid grid-cols-12 gap-6 not-prose">
|
|
<Link
|
|
href="https://supabase.link/nextjs-with-supabase-starter"
|
|
className="col-span-12 md:col-span-6 xl:col-span-4"
|
|
passHref
|
|
>
|
|
<GlassPanel title="supabase-js" hasLightIcon={true} showIconBg={true}>
|
|
A Next.js App Router template configured with cookie-based auth using Supabase, TypeScript
|
|
and Tailwind CSS.
|
|
</GlassPanel>
|
|
</Link>
|
|
<Link
|
|
href="https://supabase.link/nextjs-supabase-kysely"
|
|
className="col-span-12 md:col-span-6 xl:col-span-4"
|
|
passHref
|
|
>
|
|
<GlassPanel title="Kysely" hasLightIcon={true} showIconBg={true}>
|
|
Basic Next.js template that uses Supabase as the database and Kysely as the query builder.
|
|
</GlassPanel>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
### Manual configuration
|
|
|
|
1. In the Supabase Dashboard, click [Connect](/dashboard/project/_?showConnect=true&method=transaction) and copy the URI from the **Transaction pooler** section.
|
|
2. Replace the password placeholder with your database password.
|
|
3. Add the suffix `?workaround=supabase-pooler.vercel` to the URI.
|
|
4. Save the result as the `POSTGRES_URL` environment variable.
|
|
|
|
```txt .env.local
|
|
POSTGRES_URL="postgresql://postgres.[PROJECT-REF]:[YOUR-PASSWORD]@[POOLER-HOST]:6543/postgres?workaround=supabase-pooler.vercel"
|
|
```
|
|
|
|
<Tabs scrollable defaultActiveId="drizzle" type="underlined" size="small">
|
|
|
|
<TabPanel id="drizzle" label="Drizzle">
|
|
|
|
```ts lib/drizzle.ts
|
|
import { sql } from '@vercel/postgres'
|
|
import { InferInsertModel, InferSelectModel } from 'drizzle-orm'
|
|
import { pgTable, serial, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core'
|
|
import { drizzle } from 'drizzle-orm/vercel-postgres'
|
|
|
|
export const UsersTable = pgTable(
|
|
'users',
|
|
{
|
|
id: serial('id').primaryKey(),
|
|
name: text('name').notNull(),
|
|
email: text('email').notNull(),
|
|
image: text('image').notNull(),
|
|
createdAt: timestamp('createdAt').defaultNow().notNull(),
|
|
},
|
|
(users) => {
|
|
return {
|
|
uniqueIdx: uniqueIndex('unique_idx').on(users.email),
|
|
}
|
|
}
|
|
)
|
|
|
|
export type User = InferSelectModel<typeof UsersTable>
|
|
export type NewUser = InferInsertModel<typeof UsersTable>
|
|
|
|
// Connect to Vercel Postgres
|
|
export const db = drizzle(sql)
|
|
```
|
|
|
|
</TabPanel>
|
|
<TabPanel id="kysely" label="Kysely">
|
|
|
|
```ts lib/kysely.ts
|
|
import { createKysely } from '@vercel/postgres-kysely'
|
|
import { ColumnType, Generated } from 'kysely'
|
|
|
|
interface UserTable {
|
|
// Columns that are generated by the database should be marked
|
|
// using the `Generated` type. This way they are automatically
|
|
// made optional in inserts and updates.
|
|
id: Generated<number>
|
|
name: string
|
|
email: string
|
|
image: string
|
|
|
|
// You can specify a different type for each operation (select, insert and
|
|
// update) using the `ColumnType<SelectType, InsertType, UpdateType>`
|
|
// wrapper. Here we define a column `createdAt` that is selected as
|
|
// a `Date`, can optionally be provided as a `string` in inserts and
|
|
// can never be updated:
|
|
createdAt: ColumnType<Date, string | undefined, never>
|
|
}
|
|
|
|
// Keys of this interface are table names.
|
|
export interface Database {
|
|
users: UserTable
|
|
}
|
|
|
|
export const db = createKysely<Database>()
|
|
export { sql } from 'kysely'
|
|
```
|
|
|
|
</TabPanel>
|
|
</Tabs>
|
|
|
|
## Cloudflare Workers
|
|
|
|
Cloudflare's Workers runtime also uses the [V8 engine](https://v8.dev/), but it provides polyfills for a subset of Node.js APIs and the [TCP Sockets API](https://developers.cloudflare.com/workers/runtime-apis/tcp-sockets/). That gives you three options:
|
|
|
|
### Drivers [#cloudflare-workers-drivers]
|
|
|
|
- [supabase-js](https://developers.cloudflare.com/workers/databases/native-integrations/supabase/)
|
|
- [Postgres.js](https://github.com/porsager/postgres?tab=readme-ov-file#cloudflare-workers-support)
|
|
- [node-postgres](https://developers.cloudflare.com/workers/tutorials/postgres/)
|
|
|
|
## Supabase Edge Functions
|
|
|
|
Supabase Edge Functions use the [Deno runtime](https://deno.com/), which has native support for TCP connections. You can choose any of these clients:
|
|
|
|
### Drivers [#supabase-edge-functions-drivers]
|
|
|
|
- [supabase-js](/docs/guides/functions/connect-to-postgres#using-supabase-js)
|
|
- [Deno Postgres driver](/docs/guides/functions/connect-to-postgres#using-a-postgres-client)
|
|
- [Postgres.js](https://github.com/porsager/postgres)
|
|
- [Drizzle](/docs/guides/functions/connect-to-postgres#using-drizzle)
|