Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Cold-start persist storm blocks hydrates for seconds on the shared SQLite driver (browser/OPFS)

Chiusa
#1,752 0 commenti 1 reazione 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
playwright, sqlite, typescript

Direzione di ricerca

Inizia dal core della persistenza, da applyCommittedTx, e traccia come interagisce con loadSubset, getStreamPosition e loadCollectionMetadata; usa il percorso Playwright descritto per una scheda a freddo e la strumentazione del driver per riprodurre la profondità della coda e i ritardi di hydrate. Il lavoro è completato quando le transazioni grandi già committate evitano i round trip per riga, le letture non vengono bloccate inutilmente da scritture non correlate e le modifiche alle righe insieme agli offset dello stream mantengono il comportamento di commit atomico.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Related to the persistence hardening RFC #1659.

Setup: 13 Electric collections in one browser tab, all wrapped in persistedCollectionOptions over @tanstack/browser-db-sqlite-persistence 0.2.12 / @tanstack/db-sqlite-persistence-core 0.2.12 (WA-SQLite/OPFS), one database for the whole app. @tanstack/db 0.7.2, @tanstack/electric-db-collection 0.3.18. Measured 2026-08-19 in Chrome via a Playwright journey with adapter-level and driver-level instrumentation.

What we measured on a cold tab (first 30 s):

  • 16 applyCommittedTx calls, 66,126–80,141 mutations, 24.8 s of serialized adapter time, max single op 7,431 ms.
  • Per-collection snapshot persists: collection A 9,481 mutations → 2,094 ms; collections B/C/D ~14,000 mutations each → 1,647–1,773 ms each.
  • Driver FIFO: max queue depth 24, max queue wait 7,199–7,354 ms, max single exec 2,094 ms.

Four things compound into a user-visible 7 s delay applying a live change:

  1. No statement batching in applyCommittedTx. Roughly three worker round trips per row (existing-row SELECT, upsert, tombstone delete). 14k mutations take ~1.7–2.1 s where a batched multi-row write would be an order of magnitude cheaper. This is the root cost; everything below is a consequence.
  2. Hydrate windows are not a narrow race. One collection opened 11 loadSubset calls per page life, most returning 0–1 rows, and was inside a hydrate window for 52–54% of the tab's first 14 s. Any live transaction arriving in that half is buffered (queuedBecauseHydrating).
  3. A buffered live transaction awaits its own persist. The hydrate it was buffered behind performed a 1-row loadSubset that waited 7,052 / 7,218 / 7,262 ms in the driver FIFO behind the storm; bufferedMs for the transaction was 6,815 / 6,994 / 7,032 ms. Applying it once flushed took 1–2 ms. 100% of the 7 s was post-network-arrival, inside the persistence layer.
  4. The subset upstream-forward waits for the disk hydrate. loadSubset resolves from disk before the upstream request is issued (measured 7,433 ms before forward). In our journey the value arrived on a live stream so this added nothing, but for a change arriving via a subset snapshot it would be the entire delay by itself.

Secondary: getStreamPosition/loadCollectionMetadata for collections created after the storm begins block for the storm's full length, delaying the source sync() start by +8.9 s for two collections.

What we did downstream, and what we could not fix from there. We put a write-behind queue in our persistence adapter: applyCommittedTx resolves on enqueue, nothing starts while a read is pending, and snapshot-sized transactions wait for requestIdleCallback. That took measured propagation from 6.8–7.0 s to 0–1.7 s. The residual is irreducible outside the library: applyCommittedTx is one transaction — rows and stream offset must commit together — so a read arriving mid-write waits out the whole ~2 s op.

Suggestions: batch statements inside applyCommittedTx; chunk large committed transactions into driver-level batches that still commit atomically, yielding between them; and let hydrates be served without queueing behind unrelated collections' writes (per-collection queues, or a read lane).

Lingua principale
TypeScript
Stelle
3.9k
Fork
272
Merge medio
1g 1h
PR unite (30g)
210

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di TanStack/db

Tutte le issue di TanStack/db

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.