Serverless / edge driver
Use @kisenon/serverless — or the stock @neondatabase/serverless — against Kisenon over HTTP and WebSocket.
Edge and serverless runtimes — Cloudflare Workers, Vercel Edge, Deno — cannot open raw TCP sockets, so they can't speak the Postgres wire protocol directly. Kisenon endpoints answer this with an HTTP + WebSocket SQL gateway that is wire-compatible with the Neon serverless driver.
The pitch
Install @kisenon/serverless.
It is a drop-in swap for the Neon serverless driver, and it is what the examples
on this page import.
The stock @neondatabase/serverless
package also works against Kisenon, unmodified — same gateway, same wire format,
no neonConfig overrides to set. Pick either; there is one difference between
them and it is called out under HTTP queries below.
Either way, the only change from a stock Neon setup is the connection host —
point DATABASE_URL at your Kisenon endpoint:
postgres://<user>:<password>@<eid>.<region>.kisenon.com/<db>That is the same host as your regular Postgres connection string — there
is no separate serverless hostname. Grab it from the endpoint card in the
console, or with keon connection-string <branch> --project <project-id>.
Install
npm i @kisenon/serverlessHTTP queries with neon()
The neon() tagged-template client sends each query as a single HTTPS
POST to the endpoint's /sql route. It runs on Web-standard fetch,
so it is safe in edge runtimes with no Node net module. Ideal for
one-shot queries in a Worker or Edge Function:
import { neon } from "@kisenon/serverless";
export default {
async fetch(request, env) {
const sql = neon(env.DATABASE_URL);
const [row] = await sql`SELECT 1 AS n`;
return Response.json({ n: row.n });
},
};Parameterized queries interpolate through the tag, so
sql`SELECT * FROM users WHERE id = ${id}` is sent as a bound
parameter, not string-concatenated.
When the SQL text is a string you built rather than a template, use
sql.query(text, params):
const rows = await sql.query("SELECT * FROM users WHERE id = $1", [id]);This is the one place the two packages differ.
@neondatabase/serverless v1 also accepts the direct call
sql(text, params). @kisenon/serverless@0.1.0 does not — it binds the
tagged-template signature only, so a plain string is read character by
character and Postgres rejects it with 42601 syntax error. Use
sql.query() and both packages behave identically.
Sessions and transactions with Pool / Client
For multi-statement sessions, interactive transactions, or when you need a
long-lived connection, use Pool (or Client). These tunnel the Postgres
wire protocol over a WebSocket to the endpoint's /v2 route — the WS
path is selected automatically, you don't configure it:
import { Pool } from "@kisenon/serverless";
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const { rows } = await pool.query("SELECT 1");The full pg-style API works: pool.connect(), client.query('BEGIN'),
prepared statements, and so on, all over the one WebSocket.
How it works
Two transports terminate at the regional data plane:
- HTTP —
neon()POSTs tohttps://<eid>.<region>.kisenon.com/sqlwith aNeon-Connection-Stringheader; the gateway runs the query and returns the Neon response envelope (command,rowCount,fields,rows). There is also a front-door formhttps://api.<region>.kisenon.com/sql, where the endpoint is taken from the connection string in theNeon-Connection-Stringheader rather than the host label —apiis a reserved front-door label, not an endpoint id. - WebSocket —
Pool/Clientupgradewss://<eid>.<region>.kisenon.com/v2and the gateway transparently bridges the raw Postgres wire protocol (startup, auth, query, row data) across the socket. The stock driver's default pipelined-cleartext auth is handled by a shim, so its md5/SCRAM computes work unmodified.
Both land on the same endpoint your TCP postgres:// string reaches, so
they share your branch's data, roles, and TLS certificate.
The edge driver authenticates with both md5 and scram-sha-256 — compute roles default to md5 password encryption while newer roles use scram — and the gateway handles both transparently, so you never configure which one your role uses.
Limits and notes
- Direct or pooled. The driver works over both the direct host and the
pooled
<eid>-pooler.<region>.kisenon.comhost (transaction mode) — pooling is GA and default-on. For the serverless driver's short-lived connections the pooled host is a natural fit. See Connection strings for pooled-vs-direct. - Wake from zero. A suspended endpoint wakes on its first request. An
HTTP query to a cold endpoint may briefly return
503with{"code":"endpoint_waking"}and aRetry-Afterheader; the driver retries HTTP requests transparently where applicable, and a held WebSocket upgrade completes once the endpoint is warm. Expect the first request after idle to take a beat longer. - TLS is mandatory. The gateway serves a
*.<region>.kisenon.comcertificate from the public trust store — no custom CA needed. - Falling back to the stock driver.
@kisenon/serverless@0.1.0is exercised against the HTTP path —neon(),sql.query(),sql.transaction()and thefullResultsenvelope. If you hit trouble on the WebSocket path,@neondatabase/serverlessis a supported swap and needs no other change: same host, same connection string, same gateway.