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:

  • useConvexQuery can fetch on the server and then attach realtime updates on the client
  • useConvexPaginatedQuery stays 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 useConvexQuery for SSR-friendly reads and initial page content
  • Use useConvexPaginatedQuery for interactive feeds and load-more flows

Next steps

  • Read Queries for the task-focused query guide
  • Read Pagination for the client-side paginated flow
Copyright © 2026