diff --git a/content/100-getting-started/02-prisma-orm/100-quickstart/100-prisma-postgres.mdx b/content/100-getting-started/02-prisma-orm/100-quickstart/100-prisma-postgres.mdx index b24bc0c59e..dfa8ecc893 100644 --- a/content/100-getting-started/02-prisma-orm/100-quickstart/100-prisma-postgres.mdx +++ b/content/100-getting-started/02-prisma-orm/100-quickstart/100-prisma-postgres.mdx @@ -206,6 +206,12 @@ const prisma = new PrismaClient({ adapter }) export { prisma } ``` +:::tip + +If you need to query your database via HTTP from an edge runtime (Cloudflare Workers, Vercel Edge Functions, etc.), use the [Prisma Postgres serverless driver](/postgres/database/serverless-driver#use-with-prisma-orm). + +::: + ## 8. Write your first query Create a `script.ts` file to test your setup: @@ -274,3 +280,4 @@ You should see the created user and all users printed to the console! - [Prisma Postgres documentation](/postgres) - [Prisma Config reference](/orm/reference/prisma-config-reference) - [Database connection management](/orm/prisma-client/setup-and-configuration/databases-connections) +- [Cache your queries](/postgres/database/caching#setting-up-caching-in-prisma-postgres) diff --git a/content/100-getting-started/02-prisma-orm/200-add-to-existing-project/100-prisma-postgres.mdx b/content/100-getting-started/02-prisma-orm/200-add-to-existing-project/100-prisma-postgres.mdx index f415afdace..46d33f5ba3 100644 --- a/content/100-getting-started/02-prisma-orm/200-add-to-existing-project/100-prisma-postgres.mdx +++ b/content/100-getting-started/02-prisma-orm/200-add-to-existing-project/100-prisma-postgres.mdx @@ -172,6 +172,12 @@ const prisma = new PrismaClient({ adapter }) export { prisma } ``` +:::tip + +If you need to query your database via HTTP from an edge runtime (Cloudflare Workers, Vercel Edge Functions, etc.), use the [Prisma Postgres serverless driver](/postgres/database/serverless-driver#use-with-prisma-orm). + +::: + ## 8. Query your database Now you can use Prisma Client to query your database. Create a `script.ts` file: @@ -256,3 +262,4 @@ This command will: - [Prisma Config reference](/orm/reference/prisma-config-reference) - [Database introspection](/orm/prisma-schema/introspection) - [Prisma Migrate](/orm/prisma-migrate) +- [Cache your queries](/postgres/database/caching#setting-up-caching-in-prisma-postgres) diff --git a/content/100-getting-started/03-prisma-postgres/100-from-the-cli.mdx b/content/100-getting-started/03-prisma-postgres/100-from-the-cli.mdx index adecf0e0e9..bfedbb98c6 100644 --- a/content/100-getting-started/03-prisma-postgres/100-from-the-cli.mdx +++ b/content/100-getting-started/03-prisma-postgres/100-from-the-cli.mdx @@ -294,6 +294,12 @@ const prisma = new PrismaClient({ adapter }) export { prisma } ``` +:::tip + +If you need to query your database via HTTP from an edge runtime (Cloudflare Workers, Vercel Edge Functions, etc.), use the [Prisma Postgres serverless driver](/postgres/database/serverless-driver#use-with-prisma-orm). + +::: + ### 4.2. Write your first query Paste the following boilerplate into `index.ts`: @@ -565,7 +571,7 @@ This time, you're seeing two `User` objects being printed. Both of them have a ` ## Next steps -You just got your feet wet with a basic Prisma Postgres setup. If you want to explore more complex queries, such as adding caching functionality, check out the official [Quickstart](/getting-started/prisma-orm/quickstart/prisma-postgres). +You just got your feet wet with a basic Prisma Postgres setup. If you want to explore more complex queries, such as [adding caching functionality](/postgres/database/caching#setting-up-caching-in-prisma-postgres), check out the official [Quickstart](/getting-started/prisma-orm/quickstart/prisma-postgres). ### View and edit data in Prisma Studio diff --git a/content/100-getting-started/03-prisma-postgres/100-quickstart/50-prisma-orm.mdx b/content/100-getting-started/03-prisma-postgres/100-quickstart/50-prisma-orm.mdx index d7bc02afd6..6e370e4f93 100644 --- a/content/100-getting-started/03-prisma-postgres/100-quickstart/50-prisma-orm.mdx +++ b/content/100-getting-started/03-prisma-postgres/100-quickstart/50-prisma-orm.mdx @@ -183,6 +183,12 @@ const prisma = new PrismaClient({ adapter }) export { prisma } ``` +:::tip + +If you need to query your database via HTTP from an edge runtime (Cloudflare Workers, Vercel Edge Functions, etc.), use the [Prisma Postgres serverless driver](/postgres/database/serverless-driver#use-with-prisma-orm). + +::: + ## 8. Write your first query Create a `script.ts` file to test your setup: @@ -251,3 +257,4 @@ You should see the created user and all users printed to the console! - [Prisma Postgres documentation](/postgres) - [Prisma Config reference](/orm/reference/prisma-config-reference) - [Database connection management](/orm/prisma-client/setup-and-configuration/databases-connections) +- [Cache your queries](/postgres/database/caching#setting-up-caching-in-prisma-postgres) \ No newline at end of file diff --git a/content/200-orm/050-overview/500-databases/200-database-drivers.mdx b/content/200-orm/050-overview/500-databases/200-database-drivers.mdx index c89546e390..1d046b733e 100644 --- a/content/200-orm/050-overview/500-databases/200-database-drivers.mdx +++ b/content/200-orm/050-overview/500-databases/200-database-drivers.mdx @@ -52,6 +52,8 @@ You can connect to your database using a Node.js-based driver from Prisma Client - PostgreSQL - [`pg`](/orm/overview/databases/postgresql#using-the-node-postgres-driver) +- Prisma Postgres + - [`@prisma/adapter-ppg`](/postgres/database/serverless-driver#use-with-prisma-orm) - MySQL/MariaDB - [`mariadb`](/orm/overview/databases/mysql#using-the-mariadb-driver) - SQLite @@ -65,6 +67,7 @@ You can connect to your database using a Node.js-based driver from Prisma Client Database providers, such as Neon and PlanetScale, allow you to connect to your database using other protocols besides TCP, such as HTTP and WebSockets. These database drivers are optimized for connecting to your database in serverless and edge environments. Prisma ORM maintains the following serverless driver adapters: +- [Prisma Postgres](/postgres/database/serverless-driver#use-with-prisma-orm) - [Neon](/orm/overview/databases/neon#how-to-use-neons-serverless-driver-with-prisma-orm) (and Vercel Postgres) - [PlanetScale](/orm/overview/databases/planetscale#how-to-use-the-planetscale-serverless-driver-with-prisma-orm-preview) - [Cloudflare D1](/orm/overview/databases/cloudflare-d1) @@ -79,6 +82,7 @@ You can also build your own driver adapter for the database you're using. The fo Refer to the following pages to learn more about how to use the specific driver adapters with the specific database providers: - [PostgreSQL](/orm/overview/databases/postgresql#using-the-node-postgres-driver) +- [Prisma Postgres](/postgres/database/serverless-driver#use-with-prisma-orm) - [MySQL/MariaDB](/orm/overview/databases/mysql#using-the-mariadb-driver) - [MS SQL Server](/orm/overview/databases/sql-server#using-the-node-mssql-driver) - [Neon](/orm/overview/databases/neon#how-to-use-neons-serverless-driver-with-prisma-orm) @@ -146,6 +150,19 @@ const prisma = new PrismaClient({ adapter }) See the docs for the driver adapter you're using for concrete setup instructions. +:::tip[Tuning pool sizes, timeouts, or other connection parameters] + +See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) for the Prisma ORM v7 driver adapter defaults and how they map from Prisma ORM v6 URL parameters. + +::: + +:::tip[Prisma timeouts] + +Prisma ORM also has its own configurable timeouts that are separate from the database driver timeouts. If you see a timeout error and are unsure whether it comes from the driver or from Prisma Client, see the [Prisma Client timeouts and transaction options documentation](/orm/prisma-client/queries/transactions#transaction-options). + +::: + + ### Driver adapters and custom output paths In Prisma ORM 7, the recommended approach is to use a custom output path for Prisma Client. The default output path is `../generated/prisma`. diff --git a/content/200-orm/050-overview/500-databases/300-postgresql.mdx b/content/200-orm/050-overview/500-databases/300-postgresql.mdx index 98fb4750d2..680d128690 100644 --- a/content/200-orm/050-overview/500-databases/300-postgresql.mdx +++ b/content/200-orm/050-overview/500-databases/300-postgresql.mdx @@ -137,7 +137,7 @@ The following arguments can be used: | Argument name | Required | Default | Description | | :--------------------- | :------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `schema` | **Yes** | `public` | Name of the [schema](https://www.postgresql.org/docs/12/ddl-schemas.html) you want to use, e.g. `myschema` | -| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) | +| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) (Prisma ORM v6 and before) | | `connect_timeout` | No | `5` | Maximum number of seconds to wait for a new connection to be opened, `0` means no timeout | | `pool_timeout` | No | `10` | Maximum number of seconds to wait for a new connection from the pool, `0` means no timeout | | `sslmode` | No | `prefer` | Configures whether to use TLS. Possible values: `prefer`, `disable`, `require` | @@ -160,6 +160,10 @@ As an example, if you want to connect to a schema called `myschema`, set the con postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=myschema&connection_limit=5&socket_timeout=3 ``` +:::tip[Prisma ORM v7 connection pooling] +In Prisma ORM v7, [driver adapters](/orm/overview/databases/database-drivers) are the default for relational databases. Connection pooling is handled by the Node.js driver you provide (like `pg`), not by Prisma's connection URL parameters. See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) for v7 defaults and configuration. +::: + ### Configuring an SSL connection You can add various parameters to the connection URL if your database server uses SSL. Here's an overview of the possible parameters: diff --git a/content/200-orm/050-overview/500-databases/400-mysql.mdx b/content/200-orm/050-overview/500-databases/400-mysql.mdx index 60b61c9bcb..381f3531cf 100644 --- a/content/200-orm/050-overview/500-databases/400-mysql.mdx +++ b/content/200-orm/050-overview/500-databases/400-mysql.mdx @@ -114,7 +114,7 @@ The following arguments can be used: | Argument name | Required | Default | Description | | :----------------- | :------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) | +| `connection_limit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) (Prisma ORM v6 and before) | | `connect_timeout` | No | `5` | Maximum number of seconds to wait for a new connection to be opened, `0` means no timeout | | `pool_timeout` | No | `10` | Maximum number of seconds to wait for a new connection from the pool, `0` means no timeout | | `sslcert` | No | | Path to the server certificate. Certificate paths are [resolved relative to the `./prisma folder`](/orm/prisma-schema/overview/data-sources#securing-database-connections) | @@ -130,6 +130,10 @@ As an example, if you want to set the connection pool size to `5` and configure mysql://USER:PASSWORD@HOST:PORT/DATABASE?connection_limit=5&socket_timeout=3 ``` +:::tip[Prisma ORM v7 connection pooling] +In Prisma ORM v7, [driver adapters](/orm/overview/databases/database-drivers) are the default for relational databases. Connection pooling is handled by the Node.js driver you provide (like `mariadb`), not by Prisma's connection URL parameters. See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) for v7 defaults and configuration. +::: + ### Configuring an SSL connection You can add various parameters to the connection URL if your database server uses SSL. Here's an overview of the possible parameters: diff --git a/content/200-orm/050-overview/500-databases/800-sql-server/index.mdx b/content/200-orm/050-overview/500-databases/800-sql-server/index.mdx index aac61feff2..6f0002ec07 100644 --- a/content/200-orm/050-overview/500-databases/800-sql-server/index.mdx +++ b/content/200-orm/050-overview/500-databases/800-sql-server/index.mdx @@ -120,7 +120,7 @@ sqlserver://HOST[:PORT];database=DATABASE;user={MyServer/MyUser};password={ThisI | | No - see Comments | | Password for SQL Server login _or_ Windows (Active Directory) username if `integratedSecurity` is set to `true` (Windows only). | | `encrypt` | No | `true` | Configures whether to use TLS all the time, or only for the login procedure, possible values: `true` (use always), `false` (only for login credentials). | | `integratedSecurity` | No | | Enables [Windows authentication (integrated security)](https://learn.microsoft.com/en-us/previous-versions/dotnet/framework/data/adonet/sql/authentication-in-sql-server), possible values: `true`, `false`, `yes`, `no`. If set to `true` or `yes` and `username` and `password` are present, login is performed through Windows Active Directory. If login details are not given via separate arguments, the current logged in Windows user is used to login to the server. | -| `connectionLimit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) | +| `connectionLimit` | No | `num_cpus * 2 + 1` | Maximum size of the [connection pool](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) (Prisma ORM v6 and before) | | `connectTimeout` | No | `5` | Maximum number of seconds to wait for a new connection | | `schema` | No | `dbo` | Added as a prefix to all the queries if schema name is not the default. | | | No | | Number of seconds to wait for login to succeed. | @@ -131,6 +131,10 @@ sqlserver://HOST[:PORT];database=DATABASE;user={MyServer/MyUser};password={ThisI | `trustServerCertificate` | No | `false` | Configures whether to trust the server certificate. | | `trustServerCertificateCA` | No | | A path to a certificate authority file to be used instead of the system certificates to authorize the server certificate. Must be either in `pem`, `crt` or `der` format. Cannot be used together with `trustServerCertificate` parameter. | +:::tip[Prisma ORM v7 connection pooling] +In Prisma ORM v7, [driver adapters](/orm/overview/databases/database-drivers) are the default for relational databases. Connection pooling is handled by the Node.js driver you provide (like `mssql`), not by Prisma's connection URL parameters. See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) for v7 defaults and configuration. +::: + ### Using [integrated security](https://learn.microsoft.com/en-us/previous-versions/dotnet/framework/data/adonet/sql/authentication-in-sql-server) (Windows only) The following example uses the currently logged in Windows user to log in to Microsoft SQL Server: diff --git a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/115-connection-pool.mdx b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/115-connection-pool.mdx index 24ca0d50ee..69adb8ee64 100644 --- a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/115-connection-pool.mdx +++ b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/115-connection-pool.mdx @@ -21,30 +21,84 @@ Relational database connectors use Prisma ORM's own connection pool, and the Mon -:::note -As of [v6.16.0](https://pris.ly/release/6.16.0), Prisma ORM can be used without Rust engines in production applications. Learn more [here](/orm/prisma-client/setup-and-configuration/no-rust-engine). +## Relational databases -**When enabled, your Prisma Client will be generated without a Rust-based query engine binary**: +Starting with Prisma ORM v7, relational datasources instantiate Prisma Client with [driver adapters](/orm/overview/databases/database-drivers) by default. Driver adapters rely on the Node.js driver you supply, so connection pooling defaults (and configuration) now come from the driver itself. -```prisma -generator client { - provider = "prisma-client" - output = "../src/generated/prisma" - engineType = "client" // no Rust engine -} -``` +Use the tables below to translate Prisma ORM v6 connection URL parameters to the Prisma ORM v7 driver adapter fields alongside their defaults. + + +### Prisma ORM v7 driver adapter defaults -Note that [driver adapters](/orm/overview/databases/database-drivers#driver-adapters) are required if you want to use Prisma ORM without Rust engines. In this scenario, the connection pool is maintained by the native JS database driver you're using. +The following tables document the default connection pool settings for each driver adapter. -You can [read about the performance and DX improvements](https://www.prisma.io/blog/prisma-orm-without-rust-latest-performance-benchmarks) of this change on our blog. +:::tip[Prisma timeouts] + +Prisma ORM also has its own configurable timeouts that are separate from the database driver timeouts. If you see a timeout error and are unsure whether it comes from the driver or from Prisma Client, see the [Prisma Client timeouts and transaction options documentation](/orm/prisma-client/queries/transactions#transaction-options). ::: +#### PostgreSQL (using the `pg` driver adapter) -## Relational databases +Here are the default connection pool settings for the `pg` driver adapter: + +| Behavior | v6 URL parameter | v6 default | v7 `pg` config field | v7 default | +| --- | --- | --- | --- | --- | +| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `max` | `10` | +| Acquire timeout | `pool_timeout` | `10s` | `connectionTimeoutMillis` | `0` (no timeout) | +| Connection timeout | `connect_timeout` | `5s` | `connectionTimeoutMillis` | `0` (no timeout) | +| Idle timeout | `max_idle_connection_lifetime` | `300s` | `idleTimeoutMillis` | `10s` | +| Connection lifetime | `max_connection_lifetime` | `0` (no timeout) | `maxLifetimeSeconds` | `0` (no timeout) | + +:::tip +See the [node-postgres pool documentation](https://node-postgres.com/apis/pool) for details on every available option. +::: + +#### MySQL or MariaDB (using the `mariadb` driver) + +Here are the default connection pool settings for the `mariadb` driver adapter: + +| Behavior | v6 URL parameter | v6 default | v7 `mariadb` config field | v7 default | +| --- | --- | --- | --- | --- | +| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `connectionLimit` | `10` | +| Acquire timeout | `pool_timeout` | `10s` | `acquireTimeout` | `10s` | +| Connection timeout | `connect_timeout` | `5s` | `connectTimeout` | `1s` | +| Idle timeout | `max_idle_connection_lifetime` | `300s` | `idleTimeout` | `1800s` | + +:::tip +Refer to the [MariaDB Connector/Node.js pool options](https://mariadb.com/docs/connectors/mariadb-connector-nodejs/connector-nodejs-promise-api#pool-options) for configuration and tuning guidance. +::: + +#### SQL Server (using the `mssql` driver) + +Here are the default connection pool settings for the `mssql` driver adapter: + +| Behavior | v6 URL parameter | v6 default | v7 `mssql` config field | v7 default | +| --- | --- | --- | --- | --- | +| Pool size | `connection_limit` | `num_cpus::get_physical() * 2 + 1` | `pool.max` | `10` | +| Connection timeout | `connect_timeout` | `5s` | `connectionTimeout` | `15s` | +| Idle timeout | `max_idle_connection_lifetime` | `300s` | `pool.idleTimeoutMillis` | `30s` | + +:::tip +See the [`node-mssql` pool docs](https://tediousjs.github.io/node-mssql/#general-same-for-all-drivers) for details on these fields. +::: + +## MongoDB + +The MongoDB connector does not use the Prisma ORM connection pool. The connection pool is managed internally by the MongoDB driver and [configured via connection string parameters](https://www.mongodb.com/docs/manual/reference/connection-string-options/#connection-pool-options). + +## External connection poolers + +You cannot increase the `connection_limit` beyond what the underlying database can support. This is a particular challenge in serverless environments, where each function manages an instance of `PrismaClient` - and its own connection pool. + +Consider introducing [an external connection pooler like PgBouncer](/orm/prisma-client/setup-and-configuration/databases-connections#pgbouncer) to prevent your application or functions from exhausting the database connection limit. + +## Manual database connection handling -The relational database connectors use Prisma ORM's connection pool. The connection pool has a **connection limit** and a **pool timeout**, which are controlled by connection URL parameters. +When using Prisma ORM, the database connections are handled on an [engine](https://github.com/prisma/prisma-engines)-level. This means they're not exposed to the developer and it's not possible to manually access them. + +## Prisma ORM v6 and before ### How the connection pool works @@ -229,16 +283,3 @@ datasource db { You can choose to [disable the connection pool timeout if queries **must** remain in the queue](/orm/prisma-client/setup-and-configuration/databases-connections#disabling-the-pool-timeout) - for example, if you are importing a large number of records in parallel and are confident that the queue will not use up all available RAM before the job is complete. -## MongoDB - -The MongoDB connector does not use the Prisma ORM connection pool. The connection pool is managed internally by the MongoDB driver and [configured via connection string parameters](https://www.mongodb.com/docs/manual/reference/connection-string-options/#connection-pool-options). - -## External connection poolers - -You cannot increase the `connection_limit` beyond what the underlying database can support. This is a particular challenge in serverless environments, where each function manages an instance of `PrismaClient` - and its own connection pool. - -Consider introducing [an external connection pooler like PgBouncer](/orm/prisma-client/setup-and-configuration/databases-connections#pgbouncer) to prevent your application or functions from exhausting the database connection limit. - -## Manual database connection handling - -When using Prisma ORM, the database connections are handled on an [engine](https://github.com/prisma/prisma-engines)-level. This means they're not exposed to the developer and it's not possible to manually access them. diff --git a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx index 3dba249f14..628169db4a 100644 --- a/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx +++ b/content/200-orm/200-prisma-client/000-setup-and-configuration/050-databases-connections/index.mdx @@ -267,19 +267,20 @@ If you consistently experience connection pool timeouts after configuring the re :::note -As of [v6.16.0](https://pris.ly/release/6.16.0), Prisma ORM can be used without Rust engines in production applications. Learn more [here](/orm/prisma-client/setup-and-configuration/no-rust-engine). +As of Prisma ORM v7, [driver adapters](/orm/overview/databases/database-drivers) are the default for relational databases, providing better performance and developer experience. Learn more [here](/orm/prisma-client/setup-and-configuration/no-rust-engine). -**When enabled, your Prisma Client will be generated without a Rust-based query engine binary**: +**In Prisma ORM v7, the default generator configuration uses driver adapters**: ```prisma generator client { - provider = "prisma-client" - output = "../src/generated/prisma" - engineType = "client" // no Rust engine + provider = "prisma-client" + output = "../generated/prisma" } ``` -Note that [driver adapters](/orm/overview/databases/database-drivers#driver-adapters) are required if you want to use Prisma ORM without Rust engines. In this scenario, the connection pool size is set via the native JS driver you are using. +With driver adapters, connection pool configuration is handled by the Node.js driver you provide (like `pg`, `mariadb`, or `mssql`). See the [connection pool guide](/orm/prisma-client/setup-and-configuration/databases-connections/connection-pool) for v7 defaults and configuration details. + +Prisma ORM also has its own configurable timeouts that are separate from the database driver timeouts. If you run into a timeout error and are unsure whether it comes from the specific driver or from Prisma Client, see the [Prisma Client timeouts and transaction options documentation](/orm/prisma-client/queries/transactions#transaction-options). You can [read about the performance and DX improvements](https://www.prisma.io/blog/prisma-orm-without-rust-latest-performance-benchmarks) of this change on our blog. diff --git a/content/250-postgres/300-database/350-caching.mdx b/content/250-postgres/300-database/350-caching.mdx index 10586c6bce..4992b04888 100644 --- a/content/250-postgres/300-database/350-caching.mdx +++ b/content/250-postgres/300-database/350-caching.mdx @@ -11,6 +11,81 @@ Prisma Postgres supports built-in query caching to reduce database load and impr This feature is powered by an internal caching layer enabled through [Prisma Accelerate](/accelerate), but you do not need to interact with Accelerate directly unless you're using your own database. +## Setting up caching in Prisma Postgres + +To enable query caching in your Prisma Postgres project, you need to configure Accelerate caching and set up the client extension. Follow these steps: + +### 1. Enable caching in the Platform Console + +1. Go to the [Platform Console](https://console.prisma.io) and navigate to your project dashboard +2. In the "Connect to your database" section, click **Connect** +3. Toggle **Enable Accelerate caching** to activate the caching layer +4. Copy the generated connection string + +Your connection string will look like this: + +```env +DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=ey...." +``` + +Replace the connection string in your `.env` file with this new Accelerate-enabled URL. + +### 2. Install the Accelerate extension + +Install the required client extension in your project: + +```bash +npm install @prisma/extension-accelerate +``` + +### 3. Configure Prisma Client with caching + +Update your Prisma Client setup to use the Accelerate extension: + + + + + +```ts +import { PrismaClient } from '../generated/prisma/client' +import { withAccelerate } from '@prisma/extension-accelerate' + +const prisma = new PrismaClient({ + accelerateUrl: process.env.DATABASE_URL, +}).$extends(withAccelerate()) +``` + + + + + +```ts +import { PrismaClient } from '@prisma/client/edge' +import { withAccelerate } from '@prisma/extension-accelerate' + +const prisma = new PrismaClient({ + accelerateUrl: process.env.DATABASE_URL, +}).$extends(withAccelerate()) +``` + + + + + +### 4. Start caching your queries + +Once configured, you can add caching to any read query using the `cacheStrategy` option: + +```ts +await prisma.user.findMany({ + cacheStrategy: { + ttl: 60, // Cache for 60 seconds + }, +}) +``` + +Your caching setup is now complete! Continue reading to learn about different cache strategies and how to optimize them for your use case. + ## Cache strategies For all read queries in Prisma Client, you can define the `cacheStrategy` parameter that configures cache behavior. The cache strategy allows you to define two main characteristics of the cache: diff --git a/content/250-postgres/300-database/750-serverless-driver.mdx b/content/250-postgres/300-database/750-serverless-driver.mdx index 0fcba998fa..7911abfdd7 100644 --- a/content/250-postgres/300-database/750-serverless-driver.mdx +++ b/content/250-postgres/300-database/750-serverless-driver.mdx @@ -1,13 +1,13 @@ --- title: "Serverless driver" metaTitle: "Serverless driver" -metaDescription: "The serverless driver enables direct access to Prisma Postgres via HTTP." +metaDescription: "A lightweight PostgreSQL driver for Prisma Postgres optimized for serverless and edge environments with HTTP/WebSocket support, result streaming, and minimal memory footprint." tocDepth: 3 toc: true sidebar_class_name: early-access-badge --- -The serverless driver for Prisma Postgres is a lightweight and minimal client library that can talk to Prisma Postgres using raw SQL. You can use it via the [`@prisma/ppg`](https://github.com/prisma/ppg-client/tree/main) npm package. +The Prisma Postgres serverless driver ([`@prisma/ppg`](https://www.npmjs.com/package/@prisma/ppg)) is a lightweight client for connecting to Prisma Postgres using raw SQL. It uses HTTP and WebSocket protocols instead of traditional TCP connections, enabling database access in constrained environments where native PostgreSQL drivers cannot run. :::warning @@ -15,152 +15,295 @@ The Prisma Postgres serverless driver is currently in [Early Access](/orm/more/r ::: +## Key features + +The serverless driver uses HTTP and WebSocket protocols instead of TCP, enabling database access in environments where traditional PostgreSQL drivers cannot run: + +- Compatible with Cloudflare Workers, Vercel Edge Functions, Deno Deploy, AWS Lambda, Bun, and browsers +- Stream results row-by-row to handle large datasets with constant memory usage +- Pipeline multiple queries over a single connection, reducing latency by up to 3x +- SQL template literals with automatic parameterization and full TypeScript support +- Built-in transactions, batch operations, and extensible type system + +Use this driver for edge/serverless environments without full Node.js support, or when working with large result sets that benefit from streaming. + +For standard Node.js environments, use the [`node-postgres` driver](/orm/overview/databases/postgresql#using-the-node-postgres-driver) for lower latency with direct TCP connections. + +## Prerequisite: Get your connection string + +The serverless driver requires a Prisma Postgres Direct TCP connection URL: + +``` +postgres://identifier:key@db.prisma.io:5432/postgres?sslmode=require +``` + +Find this in the API Keys section of your [Prisma Postgres dashboard](https://console.prisma.io). The connection string is used only to extract authentication credentials. No direct TCP connection is made from the client. + +If you don't have a Prisma Postgres database, create one using the [`create-db` CLI](/postgres/introduction/npx-create-db) tool: + +```terminal +npx prisma create-db +``` + ## Installation -Install the serverless driver via npm: +Install the appropriate package based on your use case: + + + + ```terminal -npm install @prisma/ppg +npm install @prisma/ppg ``` + + + + +```terminal +npm install @prisma/ppg @prisma/adapter-ppg +``` + + + + + + ## Usage -The recommended API for most users is the `ppg` function, which returns a high-level SQL client implemented as a template literal tag function: +### Query with SQL template literals + +Use the `prismaPostgres()` high-level API with SQL template literals and automatic parameterization: ```ts -import { ppg } from "@prisma/ppg"; - -type Post = { - id: number; - title: string; - content: string | null; - published: boolean; - authorId: number | null; -} +import { prismaPostgres, defaultClientConfig } from "@prisma/ppg" + +const ppg = prismaPostgres( + defaultClientConfig(process.env.PRISMA_DIRECT_TCP_URL!) +) -const sql = ppg("prisma+postgres://accelerate.prisma-data.net/?api_key=..."); +type User = { id: number; name: string; email: string } -const authorId = 1; -const posts = await sql`SELECT * FROM "Post" WHERE "authorId" = ${authorId}`; +// SQL template literals with automatic parameterization +const users = await ppg.sql` + SELECT * FROM users WHERE email = ${'user@example.com'} +`.collect() + +console.log(users[0].name) ``` -## API reference +### Use with Prisma ORM -### `ppg` +Use the `PrismaPostgresAdapter` to connect Prisma Client via the serverless driver: -The `ppg` function returns a high-level SQL client implemented as a template literal tag function: +```ts +import { PrismaClient } from '../generated/prisma/client' +import { PrismaPostgresAdapter } from '@prisma/adapter-ppg' + +const prisma = new PrismaClient({ + adapter: new PrismaPostgresAdapter({ + connectionString: process.env.PRISMA_DIRECT_TCP_URL, + }), +}) + +const users = await prisma.user.findMany() +``` + +### Stream results + +Results are returned as `CollectableIterator`. Stream rows one at a time for constant memory usage, or collect all rows into an array: ```ts -function ppg(connectionString: string, deserialize?: Deserialize): Sql; - -interface Sql { - (strings: TemplateStringsArray, ...values: unknown[]): Promise; - /** - * Executes a raw query defined as a string with placeholders and the list - * of parameters. - * - * ```ts - * const [user] = await sql.query("SELECT * FROM users WHERE id = $1", [id]); - * ``` - */ - query(query: string, ...params: unknown[]): Promise; +type User = { id: number; name: string; email: string } + +// Stream rows one at a time (constant memory usage) +for await (const user of ppg.sql`SELECT * FROM users`) { + console.log(user.name) } -type Deserialize = (value: unknown, oid: unknown) => unknown; + +// Or collect all rows into an array +const allUsers = await ppg.sql`SELECT * FROM users`.collect() ``` -The returned `Sql` object: +### Pipeline queries -- Accepts a SQL statement as a template literal. If this contains any interpolated values, these are automatically converted to SQL parameters in order to prevent SQL injection attacks (see below for an example). -- Returns the data as an array of objects mirroring the structure of your Prisma models. -- Provides a `query` function which: - - Takes a raw string and a list of params separately, allowing you to control the SQL parameters yourself or concatenate the query unsafely if needed. - - Returns column types and raw data without converting the rows into an array of objects. +Send multiple queries over a single WebSocket connection without waiting for responses. Queries are sent immediately and results arrive in FIFO order: -#### Arguments +```ts +import { client, defaultClientConfig } from "@prisma/ppg" -The `ppg` function accepts the following arguments: +const cl = client(defaultClientConfig(process.env.PRISMA_DIRECT_TCP_URL!)) +const session = await cl.newSession() -| Name | Type | Required | Description | -| :----------------- | :------------ | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `connectionString` | `string` | **Yes** | The connection string for your Prisma Postgres instance. | -| `deserialize` | `Deserialize` | No | Custom deserializer function which takes a column type OID and a raw value and returns a mapped value. It's type is defined as `type Deserialize = (value: unknown, oid: unknown) => unknown` | +// Send all queries immediately (pipelined) +const [usersResult, ordersResult, productsResult] = await Promise.all([ + session.query("SELECT * FROM users"), + session.query("SELECT * FROM orders"), + session.query("SELECT * FROM products") +]) -#### Usage +session.close() +``` + +With 100ms network latency, 3 sequential queries take 300ms (3 x RTT), but pipelined queries take only 100ms (1 x RTT). + +### Parameter streaming + +Parameters over 1KB are automatically streamed without buffering in memory: ```ts -import { ppg } from "@prisma/ppg"; - -type Post = { - id: number; - title: string; - content: string | null; - published: boolean; - authorId: number | null; -} +// Large text content (e.g., 10MB document) +const largeDocument = generateLargeText() -type User = { - id: number; - email: string -} +// Automatically streamed - constant memory usage +await ppg.sql.exec` + INSERT INTO documents (content) VALUES (${largeDocument}) +` +``` -const sql = ppg("prisma+postgres://accelerate.prisma-data.net/?api_key=..."); +### Transactions and batch operations -const posts: Post[] = await sql`SELECT * FROM "Post"` +Transactions automatically handle BEGIN, COMMIT, and ROLLBACK: -const userId = 42; -const user: User[] = await sql`SELECT * FROM "User" WHERE "id" = ${userId}` +```ts +const result = await ppg.transaction(async (tx) => { + await tx.sql.exec`INSERT INTO users (name) VALUES ('Alice')` + const users = await tx.sql`SELECT * FROM users WHERE name = 'Alice'`.collect() + return users[0].name +}) ``` +Batch operations execute multiple statements in a single round-trip within an automatic transaction: + +```ts +const [users, affected] = await ppg.batch<[User[], number]>( + { query: "SELECT * FROM users WHERE id < $1", parameters: [5] }, + { exec: "INSERT INTO users (name) VALUES ($1)", parameters: ["Charlie"] } +) +``` -### `Client` +## Type handling -The `Client` class provides more low-level control and should be used with more care: +When using `defaultClientConfig()`, common PostgreSQL types are automatically parsed (`boolean`, `int2`, `int4`, `int8`, `float4`, `float8`, `text`, `varchar`, `json`, `jsonb`, `date`, `timestamp`, `timestamptz`): ```ts -class Client implements Queryable { - constructor(options: ClientOptions); +import { prismaPostgres, defaultClientConfig } from "@prisma/ppg" - /** - * Executes a query against the Prisma Postgres database. - */ - query(query: string, parameters: unknown[]): Promise; -} +const ppg = prismaPostgres(defaultClientConfig(process.env.PRISMA_DIRECT_TCP_URL!)) + +// JSON/JSONB automatically parsed +const rows = await ppg.sql<{ data: { key: string } }>` + SELECT '{"key": "value"}'::jsonb as data +`.collect() +console.log(rows[0].data.key) // "value" + +// BigInt parsed to JavaScript BigInt +const bigints = await ppg.sql<{ big: bigint }>`SELECT 9007199254740991::int8 as big`.collect() + +// Dates parsed to Date objects +const dates = await ppg.sql<{ created: Date }>`SELECT NOW() as created`.collect() ``` -The `query` function it exposes: +### Custom parsers and serializers + +Extend or override the type system with custom parsers (by PostgreSQL OID) and serializers (by type guard): + +```ts +import { client, defaultClientConfig } from "@prisma/ppg" +import type { ValueParser } from "@prisma/ppg" + +// Custom parser for UUID type +const uuidParser: ValueParser = { + oid: 2950, + parse: (value) => value ? value.toUpperCase() : null +} -- Takes a raw string and a list of params separately, allowing you to control the SQL parameters yourself or concatenate the query unsafely if needed. -- Returns column types and raw data without converting the rows into an array of objects. +const config = defaultClientConfig(process.env.PRISMA_DIRECT_TCP_URL!) +const cl = client({ + ...config, + parsers: [...config.parsers, uuidParser] // Append to defaults +}) +``` -#### Usage +For custom serializers, place them before defaults so they take precedence: ```ts -import { Client } from "@prisma/ppg"; +import type { ValueSerializer } from "@prisma/ppg" + +class Point { constructor(public x: number, public y: number) {} } -const client = new Client({ - connectionString: "prisma+postgres://accelerate.prisma-data.net/?api_key=...", -}); +const pointSerializer: ValueSerializer = { + supports: (value: unknown): value is Point => value instanceof Point, + serialize: (value: Point) => `(${value.x},${value.y})` +} -const posts = await client.query('SELECT * FROM "Post" WHERE "authorId" = $1', [1]); +const config = defaultClientConfig(process.env.PRISMA_DIRECT_TCP_URL!) +const cl = client({ + ...config, + serializers: [pointSerializer, ...config.serializers] // Your serializer first +}) + +await cl.query("INSERT INTO locations (point) VALUES ($1)", new Point(10, 20)) ``` -This query returns an object of this structure: +See the [npm package documentation](https://www.npmjs.com/package/@prisma/ppg) for more details. + +## Platform compatibility + +The driver works in any environment with `fetch` and `WebSocket` APIs: + +| Platform | HTTP Transport | WebSocket Transport | +|----------|----------------|---------------------| +| Cloudflare Workers | ✅ | ✅ | +| Vercel Edge Functions | ✅ | ✅ | +| AWS Lambda | ✅ | ✅ | +| Deno Deploy | ✅ | ✅ | +| Bun | ✅ | ✅ | +| Node.js 18+ | ✅ | ✅ | +| Browsers | ✅ | ✅ (with CORS) | + +## Transport modes + +- **HTTP transport (stateless):** Each query is an independent HTTP request. Best for simple queries and edge functions. +- **WebSocket transport (stateful):** Persistent connection for multiplexed queries. Best for transactions, pipelining, and multiple queries. Create a session with `client().newSession()`. + +## API overview + +### `prismaPostgres(config)` + +High-level API with SQL template literals, transactions, and batch operations. Recommended for most use cases. + +### `client(config)` + +Low-level API with explicit parameter passing and session management. Use when you need fine-grained control. + +See the [npm package](https://www.npmjs.com/package/@prisma/ppg) for complete API documentation. + +## Error handling + +Structured error types are provided: `DatabaseError`, `HttpResponseError`, `WebSocketError`, `ValidationError`. ```ts -{ - columns: [ - { name: 'id', oid: 23 }, - { name: 'title', oid: 25 }, - { name: 'content', oid: 25 }, - { name: 'published', oid: 16 }, - { name: 'authorId', oid: 23 } - ], - rows: [ [ 1, 'Hello World', 'This is the content of the post', true, 1 ] ] +import { DatabaseError } from "@prisma/ppg" + +try { + await ppg.sql`SELECT * FROM invalid_table`.collect() +} catch (error) { + if (error instanceof DatabaseError) { + console.log(error.code) + } } ``` ## Limitations -- No transaction support. -- No [local Prisma Postgres](/postgres/database/local-development) support. +- Requires a Prisma Postgres instance and does not work with [local development](/postgres/database/local-development) databases +- Currently in Early Access and not yet recommended for production + +## Learn more + +- [`@prisma/ppg` npm package](https://www.npmjs.com/package/@prisma/ppg) +- [prisma/ppg-client GitHub repository](https://github.com/prisma/ppg-client) +- [Prisma Postgres documentation](/postgres/introduction)