Connect TiDB from Workers: @tidbcloud/serverless over HTTP
Workers cannot open raw TCP connections; use @tidbcloud/serverless to reach TiDB Cloud Starter/Essential over HTTP.
Edited and verified by Orange Book Editorial Team ·
Bottom line first
TiDB is a distributed database compatible with the MySQL protocol, but Workers cannot open raw TCP connections. The official path is @tidbcloud/serverless, which wraps queries into HTTP requests. Hyperdrive's official support list does not include TiDB; compatibility is unverified and not a recommended path.
Scope and limits
- Only TiDB Cloud Starter / Essential clusters are supported; self-hosted TiDB or Dedicated clusters are outside this driver's scope.
- Every query goes over HTTPS with no pooling benefit; for high-frequency short queries, measure whether the latency is acceptable.
- Hyperdrive supports MySQL 5.7–8.x and protocol-compatible databases, but the official list does not name TiDB. Even if it works at the protocol level, do not run an unverified combination in production.
Prepare the cluster and credentials
After creating a Starter cluster in the TiDB Cloud console, take the standard MySQL connection string from the connection panel, shaped like mysql://user:pass@host/db, and store it as one secret:
npx wrangler secret put DATABASE_URLThe string contains a password, so it must go through wrangler secret — never into vars or the repository. If it leaks, reset the password in the TiDB Cloud console and update the secret.
Worker code
npm install @tidbcloud/serverlessimport { connect } from '@tidbcloud/serverless';
interface Env {
DATABASE_URL: string;
}
export default {
async fetch(request, env: Env): Promise<Response> {
const conn = connect({ url: env.DATABASE_URL });
try {
const rows = await conn.execute('SELECT id, title FROM notes LIMIT 10');
return Response.json({ notes: rows });
} catch (error) {
return Response.json({ error: String(error) }, { status: 502 });
}
},
};Each connect call creates a stateless HTTP client — nothing to reuse across requests and no connection to close. This path needs no Wrangler binding.
Verification and troubleshooting
curl -s https://<worker>.workers.dev/notes| Symptom | Check first | Recovery |
|---|---|---|
401 / authentication failure | Whether the user and password in DATABASE_URL match the console | Reset the password in the console, then update with wrangler secret put |
| Connection timeouts | Whether the cluster is Starter/Essential | Dedicated clusters need a different access method (out of scope here) |
| TLS-related errors | Whether the string came from the console connection panel with TLS parameters intact | Recopy the full connection string without trimming parameters |
| High latency under frequent queries | Whether the workload actually needs pooling | Evaluate Postgres plus Hyperdrive instead; see the integrations overview |
Remote boundary and rollback
Creating the TiDB Cloud cluster, writing the DATABASE_URL secret, and deploying the Worker all change remote state; this tutorial does not run those actions. Rollback: remove the related routes in code and redeploy — Workers holds no connections, so there is nothing to drain. Then delete the DATABASE_URL secret in Cloudflare and reset the database password in the TiDB Cloud console. Rolling the whole approach back to D1 means exporting the data first and importing into D1 — note that TiDB speaks MySQL dialect while D1 speaks SQLite, so the schema needs a table-by-table rewrite and verification, not a plain data copy.
Next: selection recap in the external database integrations overview; monitoring after launch in Observability.
Primary sources
Did this page help you complete your goal?
Beta feedback is generated in this browser and is never uploaded automatically.
Connect Turso from Workers: @libsql/client/web is the only path
Turso is libSQL (a SQLite fork) and cannot use Hyperdrive; in Workers you must import from @libsql/client/web.
Project four, multi-tenant SaaS foundation
Complete a minimum SaaS loop with a shared Worker, D1 tenant boundaries, quotas, and optional customer domains.