Skip to content

Caching and Freshness

A cache remembers a successful result so the same request can avoid doing the work again. Pivot’s browser read cache uses the shared Query engine. Your backend may independently cache expensive SQL/OLAP results. These are two different places where work can be reused.

WhereWho controls itWhat a hit avoids
Browser Query cachequery on an HTTP store or createPivotQueryAdapterA new request to your backend.
Application/backend cacheYour API/database infrastructureRepeating the backend calculation after an HTTP request arrives.
Interactive example

Reuse a recent response

Compare actual simulated HTTP calls for reused, forced-fresh and uncached reads.

The example loads when visible.

The example reads the same scope twice with a 60-second freshness window: one simulated HTTP call. Repeat cached reads adds no call while it remains fresh. Force fresh read adds one. Bypass Query twice adds two.

import { HttpPivotRemoteStore } from '@revolist/pivot';
const remoteStore = new HttpPivotRemoteStore({
baseUrl: '',
query: { staleTime: 60_000 },
});

staleTime means “this response may be reused for this long.” The HTTP store and automatically managed custom adapters default to staleTime: 0, so a later read normally fetches again. gcTime controls how long an inactive entry stays in memory; it does not make it fresh. query: false disables Query caching and native automatic read policy.

Pivot refresh actions forward a fresh-read intent through PivotReadContext. For a direct store call, store.load(request, signal, { fresh: true }) explicitly fetches even under cached/static policies. store.invalidate() marks analytical reads stale; it does not flush your database server’s cache. Change configuration with a new provider/policy object, and dispose application-owned stores/wrappers after their consuming grids/controllers.

Interactive example

Share a request, cancel one caller

Cancel one subscriber, retain its peer, and then request a fresh response.

The example loads when visible.

Two callers asking for the same analytical window can share one pending backend request. Each caller owns its subscription. Cancelling one caller does not cancel its peer; the last cancelled subscriber aborts transport. This works with AbortSignals too.

The example starts two cancellable reads, cancels the first and displays the surviving response. It then makes another read with freshness zero, showing that sharing an in-flight request and reusing a completed response are different behaviors.

Promise-based Pivot reads release their observer when they settle. Polling options do not create an always-running refresh loop for an idle report. Use the Pivot/controller refresh lifecycle to acquire another result.

Interactive example

Understand request identity

Compare object ordering, window changes, tenant scope and registry versions in real key generation.

The example loads when visible.

A cache key is the address of a result. A different filter, axis window, field-registry version or authorized dataset must use a different address. Property ordering inside a plain object is irrelevant; array order can be meaningful.

The example compares real createPivotCacheKey results. requestId is for correlating a particular call; it is not the analytical identity used to share an equivalent read. Each caller receives its own response ID after validation.

Keep provider identity stable for the same authorized session. Share an explicit Query source only between readers of the same dataset/schema/tenant/authorization scope. Replace that scope when the identity changes. Never put credentials in cache-key labels. HTTP-store tenantId and datasetWatermark scope its client keys; they are not automatically added as routing/authentication fields to the request body or headers.

Interactive example

Read backend cache metadata

Inspect the actual simulated backend response and its cacheStatus field.

The example loads when visible.

“Server cache management remains separate” means your server owns its own optional result cache. For example, the browser can issue an HTTP request while the API returns a previously computed SQL result. Conversely, a browser Query hit may avoid HTTP entirely, so the server never sees that read.

response.meta.cacheStatus (hit, miss, warm or bypass) is reported by the backend. It does not prove a browser Query hit. This example reports bypass: the simulated backend computed the result rather than using a backend response cache.

Your API decides whether to cache results, for how long, and when data or permission changes make them invalid. Query configuration in the browser does not change those decisions. A datasetWatermark separates data versions in a key; the backend must supply or validate its authoritative data version and authorization scope.

For native read options, shared scope setup and teardown, see Server Data Queries. For constructor options and wire fields see Remote API Reference. For trusted backend cache limits and security see Adapters and Security.

The adapter wrapper explanation covers createPivotQueryAdapter. It is optional for custom read policy; ordinary adapters already use Query. No adapter wrapper is needed around a normal HttpPivotRemoteStore.

First backend connection · Pagination · Loading and retry.