Summary
When a route search param (date) changes, rendering stalls while useLiveQuery re-evaluates. In Chrome Performance (production build), most self time is inside tanstack-db’s internal query engine (shown as “graph run” / d2ts join). Filters are simple equalities on fields like date and dispatchId. From maintainer guidance, indexes are applied automatically, but the profile suggests the planner isn’t using an index path here.
What I measured (prod build)
Hook Name Total ms Qty
useDispatchAssignedIds 352.8449 39x
useSelectedInstallerSameDayAssignments 6.4560 89x
useCombinedInstallerIds 4.3544 26x
useSelectedVehicleDispatch 3.6657 26x
useVehicleAssignedIds 3.6552 49x
useDispatchSidebarData 0.6889 2x
Chrome Performance (Self Time) consistently shows big chunks in graph run / d2ts join during the update triggered by changing date.
The Slowest Query
const idVdSubquery = new Query()
.from({ ind: installerDispatchCollection })
.fullJoin({ vd: vehicleDispatchCollection }, ({ ind, vd }) => eq(ind.vehicleDispatchId, vd.id))
.select(({ ind, vd }) => ({ installerDispatch: ind, vehicleDispatch: vd }))
export const useDispatchAssignedIds = (dateString: string, dispatchId?: string) => {
console.time('useDispatchAssignedIds')
const { data } = useLiveQuery(
q =>
q
.from({ idVd: idVdSubquery })
.where(({ idVd }) =>
and(
not(isUndefined(idVd.vehicleDispatch?.dispatchId)),
eq(idVd.vehicleDispatch?.dispatchId, dispatchId),
eq(idVd.vehicleDispatch?.date, dateString)
)
)
.orderBy(({ idVd }) => idVd.installerDispatch?.id, 'asc')
.select(({ idVd }) => ({
installerDispatchId: idVd.installerDispatch?.id,
vehicleDispatchId: idVd.vehicleDispatch?.id,
vehicleId: idVd.vehicleDispatch?.vehicleId,
})),
[dateString, dispatchId]
)
console.timeEnd('useDispatchAssignedIds')
return data
}
Expected
- Equality filters on common fields (
date, dispatchId) should use auto-indexes, keeping graph work small and updates snappy.
- UI should not visibly stall on
date changes when data is local.
Actual
- Rendering hangs while graph work completes; most time is spent inside the engine (not React paint).
- Behavior suggests an index is not being used for these equality filters.
Hypothesis
- Planner/optimizer is missing an indexable path for certain query graph shapes (e.g., equality on
date followed by joins), forcing expensive scans/joins. (per discussion on Discord)
Artifacts
- Chrome Performance screenshots (Self Time view):
What would help
- Confirmation that these equality filters should hit an index in live queries.
- If this is a planner miss, a fix or a temporary pattern to guarantee index usage (e.g., specific join order or “anchor” collection guidance).
- A way to verify index usage (devtools, explain-like diagnostics, or logging flag), so we can self-check query shapes.
Why this matters
Switching from a few “big” queries + JS transforms to many useLiveQuerys reduced total compute time, but the UI still blocks on date changes. If the planner used the expected indexes here, the page should feel instant.
Collections (row counts)
customers_customer 538
dispatch_dispatch 3,539
dispatch_installerdispatch 6,125
dispatch_vehicle 13
dispatch_vehicledate 1,929
dispatch_vehicledispatch 3,118
people_customuser 34
projects_contract 1,591
projects_job 894
projects_projectsite 1,016
projects_trip 13
projects_workorder 2,785
Environment
{
"@electric-sql/client": "^1.1.0",
"@electric-sql/react": "^1.0.15",
...
"@tanstack/electric-db-collection": "^0.1.38",
"@tanstack/query-core": "^5.90.5",
"@tanstack/query-db-collection": "^0.2.36",
"@tanstack/react-db": "^0.1.36",
"@tanstack/react-router": "^1.133.35",
...
"zod": "^4.1.12"
"react": "^19.2.0",
"react-dom": "^19.2.0",
"vite": "^7.1.12",
...
"babel-plugin-react-compiler": "^1.0.0",
}
- Vite production build
- React Compiler enabled (still has some manual
useMemo/useCallback)
- OS/Browser: Chrome (Performance panel traces)
Summary
When a route search param (
date) changes, rendering stalls whileuseLiveQueryre-evaluates. In Chrome Performance (production build), most self time is inside tanstack-db’s internal query engine (shown as “graph run” /d2ts join). Filters are simple equalities on fields likedateanddispatchId. From maintainer guidance, indexes are applied automatically, but the profile suggests the planner isn’t using an index path here.What I measured (prod build)
Chrome Performance (Self Time) consistently shows big chunks in graph run / d2ts join during the update triggered by changing
date.The Slowest Query
Expected
date,dispatchId) should use auto-indexes, keeping graph work small and updates snappy.datechanges when data is local.Actual
Hypothesis
datefollowed by joins), forcing expensive scans/joins. (per discussion on Discord)Artifacts
console.timelogs per hook: all-hook-calls.txtWhat would help
Why this matters
Switching from a few “big” queries + JS transforms to many
useLiveQuerys reduced total compute time, but the UI still blocks ondatechanges. If the planner used the expected indexes here, the page should feel instant.Collections (row counts)
Environment
{ "@electric-sql/client": "^1.1.0", "@electric-sql/react": "^1.0.15", ... "@tanstack/electric-db-collection": "^0.1.38", "@tanstack/query-core": "^5.90.5", "@tanstack/query-db-collection": "^0.2.36", "@tanstack/react-db": "^0.1.36", "@tanstack/react-router": "^1.133.35", ... "zod": "^4.1.12" "react": "^19.2.0", "react-dom": "^19.2.0", "vite": "^7.1.12", ... "babel-plugin-react-compiler": "^1.0.0", }useMemo/useCallback)