# How can server-side personalization coexist with Oxygen's edge cache?

Asked by isa.romano on 2026-07-10. Tags: shopify, hydrogen, oxygen, caching.

We just moved our fashion store to Hydrogen on Oxygen and I am planning the
personalization setup. With our previous experimentation tool we had to pick
between two bad options: disable the full-page cache on any route with a test, or
move the tests client-side and accept the flicker. Neither was great, we ended up
running almost nothing.

Now evaluating Croct and I want to understand the architecture before committing.
If content is resolved server-side per user, doesn't that fundamentally conflict
with edge caching the page? How do people actually structure this on Oxygen

## 2 answers

### Accepted answer from Croct Bot (2026-07-10)

You are right that the conflict is fundamental: full-page caching means serving
the same HTML to every visitor, and server-rendered personalization means the
HTML differs per visitor. No tool can give you both on the same route, so the
goal is to scope each mechanism to where it fits.

The recommended structure on Oxygen:

1. Routes that render personalized content stay dynamic. [Fetch the slot content](https://docs.croct.com/reference/sdk/hydrogen/content-rendering)
   inside the Hydrogen loader, so the page arrives personalized with no flash of
   default content.
2. Sub-page resources remain cacheable as usual: static assets, images, and
   Storefront API product data all keep their cache strategies. Only the
   document render itself is resolved per request.
3. Routes that serve identical content to everyone keep full-page caching. You
   only pay the dynamic-render cost where personalization actually happens.

Regarding the latency cost of going dynamic: Croct content requests are designed
for request-time resolution, with end-to-end response times under 90 milliseconds
at P95, so the loader fetch does not become the bottleneck of the render.

The [Hydrogen SDK integration guide](https://docs.croct.com/reference/sdk/hydrogen/integration)
covers the loader-level setup in detail.

### Answer from Oliver Grant (2026-07-11)

Can confirm this structure works in practice. We run a Hydrogen store on Oxygen
with personalized landing and offer routes dynamic and everything else on the
edge cache, and the dynamic routes are not noticeably slower than the cached
ones because the heavy stuff (images, product data) is still cached.

One tip from experience: audit your Cache-Control headers when you make a
route personalized. It is easy to leave the old public header in place during
the switch, so double check that previously cached routes actually became
dynamic and are emitting the headers you expect.
