Skip to main content

Documentation Index

Fetch the complete documentation index at: https://planetscale.com/docs/llms.txt

Use this file to discover all available pages before exploring further.

The Neon serverless driver (@neondatabase/serverless) runs Postgres queries from JavaScript and TypeScript over HTTP or WebSockets instead of TCP. PlanetScale supports this driver on platforms where standard TCP drivers and connection pooling are not viable. For full API details, see Neon’s serverless driver documentation and the GitHub repository.
Driver v1.0.0 and later require Node.js 19 or higher.

When to use this driver

Use the Neon serverless driver when your deployment platform cannot maintain TCP connections or a connection pool between requests.
PlatformRecommended approach
Netlify FunctionsNeon serverless driver (this page)
Deno DeployNeon serverless driver (this page)
Cloudflare Workers (without Hyperdrive)Neon serverless driver (this page)
Vercelpg with @vercel/functions and PgBouncer on port 6432
Cloudflare Workers + Hyperdrivepg with Hyperdrive
AWS Lambda, Railway, Render, VPS, Dockerpg with PgBouncer on port 6432

Vercel

Vercel Fluid compute reuses warm function instances, making TCP connection pooling safe. For Vercel deployments, connect with pg through PgBouncer on port 6432 and pool connections with attachDatabasePool from @vercel/functions. The Neon serverless driver remains an option on Vercel when you cannot use connection pooling (for example, classic serverless without Fluid). See Neon’s Vercel connection guide for a comparison of TCP, HTTP, and WebSocket latency on that platform.

Cloudflare Workers

For Cloudflare Workers, Hyperdrive with pg is the recommended approach. It provides connection pooling and lower latency for warm connections. Use the Neon serverless driver only when Hyperdrive is not available for your setup.

Deno Deploy

Install the driver from JSR for Deno projects:
deno add jsr:@neon/serverless
See Neon’s Deno Deploy guide for deployment details.

HTTP vs WebSocket modes

The Neon serverless driver supports two connection modes:
  • HTTP mode — Uses the neon function to execute queries over HTTP. Faster for single queries and non-interactive transactions. No connection state is maintained between requests.
  • WebSocket mode — Uses the Pool object to establish a WebSocket connection. Required for session support, interactive transactions, or node-postgres compatibility.
PlanetScale supports both modes. Choose based on your use case:
Use caseRecommended mode
Single queriesHTTP
Non-interactive transactions (batch of queries)HTTP
Interactive transactionsWebSocket
Session-based featuresWebSocket
node-postgres compatibilityWebSocket

Setting up credentials

Both modes use the same credentials setup.
1
Install the driver via npm:
npm install @neondatabase/serverless
2
You’ll need to create a Postgres role to use with the driver. Once you have these credentials, place them in environment variables:
DATABASE_HOST=XXXX.pg.psdb.cloud
DATABASE_PORT=5432
DATABASE_NAME=XXXX
DATABASE_USERNAME=XXXX
DATABASE_PASSWORD=pscale_pw_XXXX
These can all be added to a unified Postgres connection URL for use by the driver:
DATABASE_URL="postgresql://$DATABASE_USERNAME:$DATABASE_PASSWORD@$DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME"

Using HTTP mode

HTTP mode is the simplest way to execute queries. You must configure the fetchEndpoint to use PlanetScale’s SQL endpoint.
import { neon, neonConfig } from "@neondatabase/serverless";

// This MUST be set for PlanetScale Postgres connections
neonConfig.fetchEndpoint = (host) => `https://${host}/sql`;

const sql = neon(process.env.DATABASE_URL!);

const posts = await sql`SELECT * FROM posts WHERE id = ${postId}`;
The neon function returns a tagged template literal that automatically handles parameterized queries, protecting against SQL injection. For manually parameterized queries, use sql.query():
const posts = await sql.query("SELECT * FROM posts WHERE id = $1", [postId]);
See Neon’s HTTP mode documentation for arrayMode, fullResults, fetchOptions, and other configuration options.

Non-interactive transactions

HTTP mode supports non-interactive transactions where you send a batch of queries to be executed together. Use the transaction function:
import { neon, neonConfig } from "@neondatabase/serverless";

// This MUST be set for PlanetScale Postgres connections
neonConfig.fetchEndpoint = (host) => `https://${host}/sql`;

const sql = neon(process.env.DATABASE_URL!);

const [posts, tags] = await sql.transaction(
  [
    sql`SELECT * FROM posts ORDER BY posted_at DESC LIMIT ${limit}`,
    sql`SELECT * FROM tags`,
  ],
  { isolationLevel: "ReadCommitted", readOnly: true }
);

Using WebSocket mode

WebSocket mode provides a full Pool interface compatible with the pg library. See Neon’s WebSocket documentation for the full API reference. This mode requires additional configuration for PlanetScale connections.
In serverless and edge environments, WebSocket connections cannot outlive a single request. Create, use, and close Pool or Client objects within the same request handler. Do not create pools outside a handler or reuse them across handlers.
1
When connecting, you must set the following configuration options:
neonConfig.pipelineConnect = false;
neonConfig.wsProxy = (host, port) => `${host}/v2?address=${host}:${port}`;
2
Here’s a complete example:
import ws from "ws";
import { Pool, neonConfig } from "@neondatabase/serverless";

neonConfig.webSocketConstructor = ws;
// These MUST be set for PlanetScale Postgres connections
neonConfig.pipelineConnect = false;
neonConfig.wsProxy = (host, port) => `${host}/v2?address=${host}:${port}`;

const pool = new Pool({ connectionString: process.env.DATABASE_URL });

const posts = await pool.query("SELECT * FROM posts WHERE id = $1", [postId]);

pool.end();
In browser or edge environments that have a native WebSocket global, you don’t need to import ws or set neonConfig.webSocketConstructor.

Security

PlanetScale requires SCRAM-SHA-256 for all authentication to Postgres servers. We maintain this strict requirement for security purposes. For WebSocket connections, you must set neonConfig.pipelineConnect = false;. This adds a bit of additional latency, but is necessary to connect using SCRAM-SHA-256. When this is "password" (the default value) it requires using cleartext password authentication, reducing connection security. HTTP mode connections handle authentication automatically and don’t require this configuration.