This site is not affiliated with or endorsed by Cloudflare, Inc. It simply showcases experiments built using Cloudflare services.
Cloudflare Experiments

Hyperdrive SQL Demo

Query PostgreSQL through Cloudflare Hyperdrive connection pooling from a Worker

Connect to an existing PostgreSQL database through Cloudflare Hyperdrive and run safe read-only queries from the edge using Postgres.js.

Features

  • Hyperdrive binding with Postgres.js (nodejs_compat)
  • GET /status redacted connection metadata (host/db/user)
  • GET /ping database identity + latency
  • POST /query single read-only SELECT (max 50 rows)
  • Rejects write statements and multi-statement SQL

API Reference

GET /status

Returns redacted Hyperdrive target metadata without exposing the password.

Example Request

curl "https://your-worker.workers.dev/status"

Success Response

bound boolean

Whether the Hyperdrive binding is present

host string

Database host (and port when present)

database string

Database name

user string

Database user

{
  "bound": true,
  "host": "db.example.com:5432",
  "database": "app",
  "user": "alice"
}

GET /ping

Runs SELECT current_database(), current_user, version() through Hyperdrive.

Example Request

curl "https://your-worker.workers.dev/ping"

Success Response

ok boolean

Always true on success

database string

Current database name

user string

Current database user

serverVersion string

Postgres version() string

latencyMs number

Round-trip query latency in milliseconds

{
  "ok": true,
  "database": "app",
  "user": "alice",
  "serverVersion": "PostgreSQL 16.2 on x86_64-pc-linux-gnu",
  "latencyMs": 18
}

POST /query

Runs a single read-only SELECT and returns up to 50 rows.

Prop

Type

Example Request

curl -X POST "https://your-worker.workers.dev/query" \
  -H "content-type: application/json" \
  -d '{"sql":"SELECT 1 AS ok"}'

Success Response

sql string

Validated SQL that was executed

rowCount number

Number of rows returned (capped at 50)

rows array

Result rows as JSON objects

latencyMs number

Query latency in milliseconds

{
  "sql": "SELECT 1 AS ok",
  "rowCount": 1,
  "rows": [{ "ok": 1 }],
  "latencyMs": 12
}

Error Response

{
  "error": "Invalid SQL: only a single read-only SELECT statement is allowed",
  "code": "INVALID_SQL"
}

Error Codes

  • 400 - Invalid or missing JSON body (INVALID_BODY)
  • 400 - SQL rejected by allowlist (INVALID_SQL)
  • 502 - Hyperdrive binding missing (MISSING_BINDING)
  • 502 - Database error (DB_ERROR)

Use Cases

  • Accelerate queries from Workers to regional Postgres
  • Prove Hyperdrive pooling/caching against an existing database
  • Build read-only edge SQL playgrounds
  • Teach nodejs_compat + Postgres.js patterns on Workers

Limitations

  • Requires a real Hyperdrive config and reachable Postgres database
  • Only single SELECT statements are allowed
  • Results are capped at 50 rows
  • Local development needs localConnectionString pointing at a reachable DB

Deployment

Create Hyperdrive

npx wrangler hyperdrive create hyperdrive-sql-demo \
  --connection-string="postgres://USER:PASSWORD@HOST:5432/DATABASE"

Click the deploy button

Deploy to Cloudflare Workers

Paste the Hyperdrive id into wrangler.json under hyperdrive[0].id.

Test your deployment

curl "https://your-worker.workers.dev/ping"

Local Development

cd apps/experiments/hyperdrive-sql-demo
npm install
npm run dev

Set hyperdrive[0].localConnectionString in wrangler.json to a local or remote Postgres URL, then:

curl "http://localhost:8787/status"
curl "http://localhost:8787/ping"
curl -X POST "http://localhost:8787/query" \
  -H "content-type: application/json" \
  -d '{"sql":"SELECT 1 AS ok"}'

Configuration

Binding / settingPurpose
HYPERDRIVEHyperdrive binding (connectionString)
compatibility_flags: ["nodejs_compat"]Required for Postgres.js
postgres ^3.4.5Postgres client dependency

Cloudflare Features Used

Next Steps

On this page