Convex Patterns
Realtime and SSR
Understand how useConvexQuery moves from server fetch to client subscription, and why paginated queries stay client-only.
The shared runtime treats reads in two different ways:
useConvexQuerycan fetch on the server and then attach realtime updates on the clientuseConvexPaginatedQuerystays client-only
How useConvexQuery behaves
When server rendering is enabled, useConvexQuery(...).suspense() fetches once through ConvexHttpClient during SSR.
const { data, suspense } = useConvexQuery(api.tasks.list, { userId: 'demo' })
await suspense()
After hydration, the client attaches a realtime subscription and keeps data updated without polling.
When to disable SSR
Use { server: false } or set convex.server = false when:
- the query depends on browser-only auth state
- the page is private and SEO does not matter
- you want to avoid server-side Convex requests entirely
Why paginated queries are different
useConvexPaginatedQuery does not run an SSR prefetch pass. It starts on the client and manages realtime pagination there.
Decision rule
- Use
useConvexQueryfor SSR-friendly reads and initial page content - Use
useConvexPaginatedQueryfor interactive feeds and load-more flows
Next steps
- Read Queries for the task-focused query guide
- Read Pagination for the client-side paginated flow