Orange Book
External databases

Connect Neon from Workers: Hyperdrive first, serverless driver as fallback

Neon officially recommends pooled connections through Hyperdrive; lightweight cases can use @neondatabase/serverless over HTTP or WebSocket.

Edited and verified by Orange Book Editorial Team ·

INTEGRATIONSINTERMEDIATE30 minutesVerified 2026-08-27

Bottom line first

The officially recommended path is Hyperdrive: edge-side pooling amortizes Neon compute cold starts and TLS handshakes. For low query volume with no appetite for maintaining a Hyperdrive configuration, use @neondatabase/serverless over HTTP or WebSocket.

Choosing between the two paths

PathBest forKey limits
Hyperdrive + Postgres driverHigh-frequency queries, latency-sensitive workloads, existing Postgres toolingNeeds a dedicated role and a non-pooled connection string; no LISTEN/NOTIFY-style features
@neondatabase/serverlessInfrequent reads and writes, prototypes, minimal configurationEvery request pays its own handshake; the first query after scale-to-zero takes hundreds of milliseconds

On the Neon free plan, compute scales to zero after about 5 minutes idle, and waking it takes a few hundred milliseconds. Hyperdrive's pool hides most of that; the HTTP driver path pays it on every cold start.

Create a dedicated role for the Worker in the Neon dashboard (do not reuse the owner account), then in the connection details uncheck connection pooling — Hyperdrive does its own pooling, and pointing it at Neon's pooled endpoint stacks two pools. The connection string looks like postgres://<role>:<password>@<host>/<db>?sslmode=require.

npx wrangler hyperdrive create neon-pg --connection-string="postgres://<role>:<password>@<host>/<db>?sslmode=require"
wrangler.jsonc
{
  "name": "notes-api",
  "compatibility_date": "2026-08-25",
  "compatibility_flags": ["nodejs_compat"],
  "hyperdrive": [
    { "binding": "HYPERDRIVE", "id": "<id returned by the create command>" }
  ]
}
src/index.ts
import { Client } from 'pg';

interface Env {
  HYPERDRIVE: Hyperdrive;
}

export default {
  async fetch(request, env: Env): Promise<Response> {
    const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
    try {
      await client.connect();
      const result = await client.query('SELECT id, title FROM notes LIMIT 10');
      return Response.json({ notes: result.rows });
    } catch (error) {
      return Response.json({ error: String(error) }, { status: 502 });
    } finally {
      await client.end().catch(() => {});
    }
  },
};

Path two: @neondatabase/serverless

npm i @neondatabase/serverless
npx wrangler secret put DATABASE_URL

DATABASE_URL is the full connection string from the Neon dashboard. The package runs single queries over HTTP by default and can also hold a session over WebSocket.

src/index.ts
import { neon } from '@neondatabase/serverless';

interface Env {
  DATABASE_URL: string;
}

export default {
  async fetch(request, env: Env): Promise<Response> {
    const sql = neon(env.DATABASE_URL);
    try {
      const rows = await sql`SELECT id, title FROM notes LIMIT 10`;
      return Response.json({ notes: rows });
    } catch (error) {
      return Response.json({ error: String(error) }, { status: 502 });
    }
  },
};

Verification and troubleshooting

curl -s https://<worker>.workers.dev/notes
SymptomCheck firstRecovery
First query takes hundreds of milliseconds, then normalWhether compute just woke from scale-to-zeroAccept the latency, or migrate to the Hyperdrive path
Authentication failure on the Hyperdrive pathWhether you used the owner account or a pooled connection stringRebuild Hyperdrive with the dedicated role and non-pooled string
password authentication failedWhether the password in the string contains characters needing escapesRecopy the connection string; URL-encode if needed
SQL errors about unsupported featuresWhether the code uses LISTEN/NOTIFY or advisory locksRewrite as polling or a queue-based design

Remote boundary and rollback

Creating a Hyperdrive configuration, writing the DATABASE_URL secret, and creating a Neon role all change remote state; this tutorial does not run those actions. Rollback: remove the hyperdrive binding from wrangler.jsonc and redeploy, delete the configuration with wrangler hyperdrive delete <id>, then rotate the role password or drop the dedicated role on the Neon side, and finally delete any unused secrets in Cloudflare. The database data itself is unaffected by a code rollback.

Next: connect Turso from Workers. For monitoring after launch, see Observability.

Primary sources

Did this page help you complete your goal?

Beta feedback is generated in this browser and is never uploaded automatically.

On this page