Skip to main content

Query Ownership and Caching

Understand where query results live without creating a second state authority.

“Cache” can refer to several different owners in one Nuxt page. Distinguishing them prevents duplicate state.

Where state lives

StateOwnerLifetime
Convex query result and wire deduplicationCurrent Convex clientClient lifetime and identity generation
SSR resultNuxt payload/async dataRequest and hydrated payload
data, error, and lifecycle refsComposable instanceVue effect scope
Optimistic local viewConvex client local storeUntil server confirmation or rollback
UI-only stateComponent or app storeApplication-defined

There is no separate Better Convex Nuxt entity cache or query registry.

Identical queries

Two mounted components may request the same Convex query and arguments. Convex owns wire-level deduplication. Each composable still has its own Vue-visible refs, which keeps loading presentation and derived views local to their consumers.

For reusable application intent, write an ordinary composable that calls the query directly:

app/composables/useCurrentTeam.ts
import { api } from '#convex/api'

export function useCurrentTeam() {
  return useConvexQuery(api.teams.current, {}, { auth: 'required' })
}

This is code reuse, not a second cache owner.

Reactive argument identity

A query is identified by its function reference, normalized arguments, auth boundary, and current identity generation. Changing arguments requests a new result.

keepPreviousData: true may retain the previous result while new arguments load for the same identity. It never carries data across an identity boundary.

Convex data versus Pinia

Keep server-backed entities in Convex queries. Use Pinia or local refs for UI state such as:

  • open panels and dialogs;
  • unsaved local drafts;
  • wizard progress;
  • client preferences that are not server data.

Copying query entities into Pinia creates synchronization work: refresh, optimistic rollback, sign-out clearing, and live update reconciliation all gain a second implementation.

No cross-request cache promise

Each server request has its own Nuxt app and identity context. If a deployment adds HTTP or page caching, its privacy and invalidation rules belong to that deployment layer. Read performance before caching authenticated pages.