You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
void/db can't start on the D1 primary or carry a bookmark across requests #755
Follow-up to #337, which asked for read replication and per-request sessions.
During a request, db from void/db always starts with withSession('first-unconstrained'), and each request gets a new session. That covers read-your-writes within one request, but not across requests: a write followed by a read in the next request can reach a replica that hasn't caught up.
The D1 guide says to handle this like so:
If another read must start with the latest primary data, use env.DB.withSession('first-primary') from cloudflare:workers.
That's the raw D1 API, and there's no supported way to run Drizzle queries on it:
createDb() calls withSession('first-unconstrained') itself, so it can't be given a different constraint.
createPrimaryDb() exists in src/runtime/db.ts, but it's private and only used outside a request.
Using drizzle() directly needs drizzle-orm as a dependency, and void/db is meant to replace that.
So a read that must be fresh has to become raw SQL with hand-written row types.
This affects common flows:
A form saves and redirects, and the next page's loader shows the old data.
A user pays and is sent to a page gated on that payment, and a replica says they haven't paid.
A webhook looks up a row created by an earlier request and doesn't find it.
Proposal
A way to get a Drizzle db that starts on the primary and keeps the app's schema, such as createDb(env.DB, { session: 'first-primary' }) or an exported primaryDb.
An opt-in bookmark that carries across requests: Void saves getBookmark() in a cookie when a request ends and starts the next request's session from it, so a user always sees their own writes.
Either one would solve the gated-page case. The first suits individual reads and also covers webhooks, which have no cookie. The second fixes the redirect-after-write case across a whole app.
Prior art
Rails' DatabaseSelector and Laravel's sticky option both send a user's reads to the primary after they write.
Activity
Allow Drizzle D1 clients to start sessions on primary, refs #755.