PgBeam Docs

Serverless Driver

Use @neondatabase/serverless to connect from edge runtimes and serverless functions through PgBeam with HTTP or WebSocket transports.

Connect from edge runtimes and serverless functions using the @neondatabase/serverless driver. PgBeam supports both the HTTP query endpoint and the WebSocket wire protocol — no code changes required if you're already using the Neon serverless driver.

Setup

Install the package

npm install @neondatabase/serverless
pnpm add @neondatabase/serverless
yarn add @neondatabase/serverless
bun add @neondatabase/serverless

For Node.js environments using WebSocket transport, also install ws:

npm install ws

HTTP transport — neon() tagged template

Best for one-shot queries from edge/serverless functions. Each call is a single HTTP request — no persistent connection required.

query.ts
import { neon } from "@neondatabase/serverless";

const sql = neon("postgresql://user:pass@abc.aws.pgbeam.app/mydb");
const rows = await sql`SELECT * FROM users WHERE active = true`;

WebSocket transport — Pool / Client

Best for interactive transactions or session-level features. Uses the PostgreSQL wire protocol over WebSocket.

db.ts
import { Pool } from "@neondatabase/serverless";

const pool = new Pool({
  connectionString: "postgresql://user:pass@abc.aws.pgbeam.app/mydb",
});
const { rows } = await pool.query("SELECT * FROM users");
db.ts
import { Pool, neonConfig } from "@neondatabase/serverless";
import ws from "ws";

neonConfig.webSocketConstructor = ws;

const pool = new Pool({
  connectionString: "postgresql://user:pass@abc.aws.pgbeam.app/mydb",
});
const { rows } = await pool.query("SELECT * FROM users");

Run a test query

const result = await sql`SELECT 1 AS ok`;
console.log(result); // [{ ok: 1 }]

If this returns results, the serverless driver is connected through PgBeam.

HTTP vs WebSocket

HTTP (neon())WebSocket (Pool / Client)
Best forOne-shot queries, edge functionsTransactions, session features
ConnectionStateless HTTP requestPersistent WebSocket
Cold startNoneWebSocket handshake + TLS
Transactionssql.transaction([...])BEGIN / COMMIT via client
PipeliningAutomatic (batched in one request)PostgreSQL wire protocol
Max payload~10 MB responseUnlimited streaming

Edge runtime compatibility

The serverless driver works in any runtime with fetch (for HTTP) or WebSocket (for WS):

RuntimeHTTPWebSocketNotes
Vercel Edge FunctionsYesYesBuilt-in WebSocket support
Cloudflare WorkersYesYesBuilt-in WebSocket support
Deno DeployYesYesBuilt-in WebSocket support
BunYesYesBuilt-in WebSocket support
Node.jsYesYesRequires ws package

Drizzle ORM integration

Use the serverless driver adapters with Drizzle for type-safe queries:

db.ts
import { neon } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-http";

const sql = neon("postgresql://user:pass@abc.aws.pgbeam.app/mydb");
const db = drizzle(sql);

const users = await db.select().from(usersTable);
db.ts
import { Pool } from "@neondatabase/serverless";
import { drizzle } from "drizzle-orm/neon-serverless";

const pool = new Pool({
  connectionString: "postgresql://user:pass@abc.aws.pgbeam.app/mydb",
});
const db = drizzle(pool);

const users = await db.select().from(usersTable);

Transactions

Use sql.transaction() to run multiple statements in a single HTTP request:

HTTP transactions
import { neon } from "@neondatabase/serverless";

const sql = neon("postgresql://user:pass@abc.aws.pgbeam.app/mydb");

const results = await sql.transaction([
  sql`UPDATE accounts SET balance = balance - 100 WHERE id = 1`,
  sql`UPDATE accounts SET balance = balance + 100 WHERE id = 2`,
]);

Use standard BEGIN / COMMIT with a dedicated client:

WebSocket transactions
import { Pool } from "@neondatabase/serverless";

const pool = new Pool({
  connectionString: "postgresql://user:pass@abc.aws.pgbeam.app/mydb",
});

const client = await pool.connect();
try {
  await client.query("BEGIN");
  await client.query("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
  await client.query("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
  await client.query("COMMIT");
} catch (e) {
  await client.query("ROLLBACK");
  throw e;
} finally {
  client.release();
}

Caching and replicas

SQL annotations work the same with the serverless driver:

Cache and replica annotations
import { neon } from "@neondatabase/serverless";

const sql = neon("postgresql://user:pass@abc.aws.pgbeam.app/mydb");

// Cache for 5 minutes
const categories = await sql`/* @pgbeam:cache maxAge=300 */ SELECT * FROM categories`;

// Route to read replica
const stats = await sql`/* @pgbeam:replica */ SELECT count(*) FROM orders`;

// Combine both
const products = await sql`/* @pgbeam:replica */ /* @pgbeam:cache maxAge=60 */ SELECT * FROM products`;

See Caching and Read Replicas for details.

Common issues

IssueCauseFix
WebSocket is not definedNode.js missing WS constructorInstall ws and set neonConfig.webSocketConstructor = ws
fetch failed on HTTP endpointNetwork/firewall blocking HTTPSVerify the proxy hostname resolves and port 443 is open
Slow cold starts with WebSocketTLS + WS handshake on each invocationUse HTTP transport for stateless queries
connection terminatedIdle timeout exceededUse connection pooling or reconnect on error

Further reading

On this page