Skip to content

CONCEPT Cited by 2 sources

Serverless TCP socket restriction

Serverless TCP socket restriction is the platform constraint that serverless / FaaS / edge compute runtimes forbid user code from opening raw TCP sockets, permitting outbound network I/O only over fetch()-style HTTPS. The constraint is structural, not configurable: it exists because the runtime isolates tenants behind a V8-isolate or WASM sandbox without a general-purpose syscall interface, and because allowing arbitrary outbound TCP would undermine the runtime's multi-tenancy and regional-egress cost model.

Canonical statement

From PlanetScale (2022-08-18): "these environments require external connections to be made over HTTP and not other networking protocols. Connections with other MySQL drivers speak the MySQL binary protocol over a raw TCP socket… Our new driver uses secure HTTP, which allows you to use PlanetScale in these constrained environments." (Source: sources/2026-04-21-planetscale-introducing-the-planetscale-serverless-driver-for-javascript.)

Restated in Jan 2023 with stronger framing: "In serverless compute contexts, your code is fundamentally not able to open up a TCP socket and speak the MySQL binary protocol to us. The platforms require communication through HTTP(S)." (Source: sources/2026-04-21-planetscale-faster-mysql-with-http3.)

Runtimes affected

  • Cloudflare Workers — V8-isolate runtime; historically fetch()-only egress. (Cloudflare later added a connect() TCP primitive, but at the time of the 2022 PlanetScale launch Workers was HTTP-egress-only.)
  • Vercel Edge Functions — V8-isolate runtime running on the Vercel edge network.
  • Netlify Edge Functions — Deno-based edge runtime.
  • AWS Lambda-class FaaS — classical Lambda permits raw TCP from user code, but many serverless-framework integrations (e.g. Next.js Edge runtime on Lambda) use the Edge runtime's HTTP-only subset.
  • In-browser JavaScript — not a FaaS but structurally identical: raw TCP is not exposed to page JS; only fetch() / XMLHttpRequest / WebSocket are available.

Consequences for database clients

A MySQL / Postgres / Redis / Kafka client that wraps the native wire protocol cannot run in these runtimes. The natural architectural responses are:

  1. Ship an HTTP-API version of the database protocolpatterns/http-api-alongside-binary-protocol — and a client that speaks it. Example: PlanetScale HTTP API + PlanetScale serverless driver for JavaScript.
  2. Route the TCP connection through a proxy service that itself runs outside the restricted runtime — example: Cloudflare Hyperdrive for Postgres / MySQL. The Worker still speaks an abstracted binding; the actual TCP connection is held by Hyperdrive.
  3. Connect via an HTTP-REST façade — common for NoSQL: DynamoDB's HTTP API, Firestore's REST API, Upstash Redis's REST API all work directly from serverless runtimes because they're HTTP-native by design.

Why it's a constraint, not a bug

The restriction is load-bearing for the serverless cost model:

  • Multi-tenancy: allowing raw TCP connections from untrusted tenant code widens the attack surface (ability to probe the provider's internal network, abuse egress for DoS, exfiltrate across tenant boundaries).
  • Egress accounting: HTTP requests are easy to meter per route / origin; raw TCP streams are harder to slice for billing.
  • Cold-start cost: per-invocation TCP connection setup is expensive; the HTTP-over-shared-connection model lets the runtime amortise network I/O across invocations.
  • Connection-count pressure on backends: many short-lived serverless invocations each opening MySQL connections would exhaust database connection pools (concepts/connection-pool-exhaustion); HTTP/2 multiplexing amortises that cost.

Contrast with traditional server runtimes

In a long-lived server runtime (bare-metal, Kubernetes pod, Fargate task) the database client opens a connection pool at boot and reuses sockets across requests. Per-request connection cost is effectively zero. The serverless per-invocation programming model breaks this — every invocation is a cold client — which is why concepts/connection-multiplexing-over-http matters more there than in the long-lived server case.

Seen in

Last updated · 378 distilled / 1,213 read