Repository navigation
Description
Summary
The docs promise "Database reads are fast everywhere via D1's read replication" (docs/guide/index), but nothing in void enables or uses it: databases are provisioned without read_replication, and void/db never calls withSession(), so every query — including per-request auth lookups — always hits the D1 primary.
Discovered while investigating production 503s on a void-deployed app: the dispatch worker races worker.fetch() against a 10s deadline, and sequential D1 round trips to an APAC-primary database push the p99 tail past it.
Evidence
platform/packages/api/src/provisioning/cloudflare-api.ts—createD1Databaseposts only{name}; noread_replicationconfig.packages/void/src/cli/provision.ts:4465—wrangler d1 create <name> --binding ... --update-configwith no--read-replicationflag; nothing writesread_replicationintod1_databases[]config.packages/void/src/runtime/db.ts:60—dbproxy wrapsdrizzle(requireRuntimeBinding('DB'))on the raw binding.D1Database.withSession()/D1DatabaseSession.getBookmark()are never exposed.packages/void/src/runtime/better-auth.ts:9—resolveDatabasepassesenv.DBdirectly to better-auth, so auth's per-request session+user lookups can't use a replica session either.- Repo-wide,
read_replication/withSessionappear only in the docs claim; no code or tests reference them.
Impact
Every D1 query in every void app pays a round trip to the database's primary region. For APAC-primary databases serving global traffic that's ~800ms+ per hop; auth middleware alone does 2+ sequential hops per request.
Suggested approach
- Enable at provisioning:
read_replication: { mode: "auto" }oncreateD1Database(platform API path) andwrangler d1 create --read-replication enabled/ wrangler config emission (CLI path). - Session API in
void/db: expose a per-request D1 session, e.g.db.withSession("first-unconstrained")or a request-scoped drizzle instance viagetRuntimeRequestResource(env.tsalready has the plumbing). Drizzle's d1 driver only callsprepare/batch, whichD1DatabaseSessionsupports — needs a type widening sincedrizzle()is typed againstD1Database. - Auth path: route
resolveVoidAuthState/runVoidAuthMiddlewaresession lookups through a D1 session — biggest win, since every request's auth hops would hit the nearest replica with sequential consistency.
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity