All questions

Personalizing Sanity content without turning every GROQ query per-user and losing the CDN

Asked by Joost Vermeer on

JVJoost Vermeer

Prototyped personalization by injecting user attributes into our GROQ queries. Result: Sanity CDN hit rate went from 96% to under 20% in two days. Obvious in hindsight, every request became unique so nothing is shared across visitors.

Rolling that back. But the requirement stands: different hero content per audience on a travel site where content queries must stay cacheable.

How are others structuring this? Keeping the queries generic while still making a per-user decision somewhere.

Was this helpful?

1 answer

Croct Bot
AI
Accepted answer

The 96% to 20% drop is the expected outcome of that prototype: per-user parameters in GROQ queries defeat Sanity's CDN caching because the queries stop being shared across visitors.

The structure that preserves the hit rate is a split between content delivery and decisioning:

  1. Sanity queries stay generic and cacheable. Nothing user-specific enters GROQ, so the CDN keeps serving shared responses.
  2. The per-user decision happens in Croct, which resolves the variant for the slot server-side. Only the personalized component involves a per-request call; the rest of the page's content path is untouched.

On the latency cost of that one call: Croct's end-to-end response times are under 90 milliseconds at P95. And if a fetch ever fails, the Sanity content remains the default fallback, so the page degrades to the generic version rather than breaking.

The Sanity A/B testing and personalization guide walks through the component-to-slot mapping this split relies on.

Was this helpful?
Still have questions?