Hosting Hydrogen: Oxygen or self-hosted on Workers

Short answer

Oxygen is the default home for a Hydrogen storefront: it is available at no extra charge on paid Shopify plans and manages environments, variables, caching and Shopify’s CDN. Shopify also documents self-hosting, with Cloudflare Workers among the named runtimes, but you replace Oxygen’s packages, provide a Web Cache API cache and sessions, and own the edge caching. Choose Oxygen unless you need infrastructure it doesn’t give you, or a public URL your plan can’t provide.

  • Oxygen is available at no extra charge on paid Shopify plans and isn’t available on Agentic plans.
  • Development stores and trial plans can deploy to Oxygen but have no public environments; Starter to Advanced plans get one public environment and Shopify Plus 25.
  • Shopify’s self-hosting guide names Vercel, Netlify, Fly.io and Cloudflare Workers as other runtimes for Hydrogen; it requires the Headless channel for API tokens.
  • The Workers Free plan allows 10 ms of CPU time per HTTP request; the Paid plan allows 30 seconds by default, configurable up to 5 minutes.
  • Workers Cache returns cached responses without running the Worker, keyed by request path, entrypoint, ctx.props and, by default, the Worker version.

A Hydrogen storefront is a server-rendered application, so it needs somewhere to run. Shopify offers Oxygen, built for Hydrogen. Shopify also documents running Hydrogen on other JavaScript runtimes, and Cloudflare Workers is one of them. We run this website on Workers, so this is a comparison from both the documentation and our own deployment.

What Oxygen gives you

  • Cost and plans. Oxygen is available at no extra charge on paid Shopify plans: Starter, Basic, Grow, Advanced, Plus and Pause and build. It isn’t available on Agentic plans. Development stores and trial plans can use it too, but only privately; Plus Partner Sandbox stores get one public environment.
  • Environments. Each environment links to a Git branch and can hold up to 110 environment variables. Environments are private by default and need a store login. Public environments: one on Starter, Basic, Grow, Advanced and Pause and build, 25 on Shopify Plus, and none on development stores or trial plans.
  • Operations. Shopify describes Oxygen as handling deployment environments, environment variable management, caching and the integration with Shopify’s CDN. Those are the four things you rebuild or replace when you leave it.
  • Private previews by default. Because environments need a store login unless made public, unfinished work isn’t exposed to visitors or crawlers by accident.

What changes when you self-host

Shopify’s self-hosting guide names Vercel, Netlify, Fly.io and Cloudflare Workers. The requirement on the Shopify side is the Headless channel, which provides Storefront API and Customer Account API access. The work on your side:

  1. Remove the Oxygen-specific packages and adapt vite.config.ts, react-router.config.ts and the server entry. Hydrogen’s own Vite plugin stays.
  2. Provide a cache that implements the standard Web Cache API, so Hydrogen’s Storefront API caching keeps working.
  3. Implement sessions for your runtime, and check how it supports background work such as waitUntil.
  4. Set the Shopify-Storefront-Buyer-IP header on server-side Storefront API requests. Without it Shopify can’t tell buyers apart, which can get requests throttled.
  5. Build your own preview and production split, including a noindex rule for anything that isn’t production, since previews are no longer private behind a store login.

Cloudflare Workers specifics

LimitWorkers FreeWorkers Paid
Requests100,000 a dayNo daily limit
CPU time per HTTP request10 ms30 seconds by default, up to 5 minutes
Subrequests per invocation5010,000 (up to 10 million)
Worker size, uncompressed64 MiB64 MiB
Memory per isolate128 MB128 MB

Ten milliseconds of CPU is a tight budget for server-rendering a React page. The lever that changes this is Workers Cache: Cloudflare checks the cache before invoking the Worker, and a hit is returned without running your code, so it uses no CPU. The cache honours standard Cache-Control directives, including stale-while-revalidate, and bypasses responses that set cookies and requests that carry an Authorization header. Its key is the request path, entrypoint, ctx.props and, by default, the Worker version, not the hostname.

What each option costs to run

On a paid Shopify plan, Oxygen adds no hosting bill. On Workers you pay Cloudflare’s rates, and Workers Cache changes the shape of that bill: with it enabled, every request is billed at the standard Workers request rate, with no extra charge for caching, and CPU time is billed only when the Worker actually runs. A storefront whose pages are mostly cache hits spends little CPU; one that renders every request spends it on every visit. The larger cost on either host is engineering time, and self-hosting adds some: sessions, caching headers, preview environments and upgrade testing are yours.

Storefront API caching when self-hosted

Hydrogen’s data caching and the edge cache for whole pages are two separate layers, and self-hosting touches both:

  • Sub-request cache. Hydrogen caches Storefront API responses through the cache object you give it. On Workers that is the runtime’s Web Cache API (caches.open(…)), which is what this site passes to Hydrogen’s context.
  • Page cache. Whether a rendered page is cached is decided by the headers you set on the response and by the host. On Workers that means Workers Cache and your Cache-Control rules.
  • Personal data. Responses that set cookies must stay out of any shared cache. Workers Cache bypasses responses with Set-Cookie and requests with an Authorization header, but your own rules should say so explicitly as well.

What we run, and why

This website is a Hydrogen 2026.4 app served from Cloudflare Workers; Oxygen is not part of its production pipeline. The build already produces a Worker bundle and static assets, so moving it needed configuration, not a rewrite. The cache policy lives in the server entry:

  • Public HTML is cached at the edge for an hour and can be served stale for a day while one background request refreshes it. Browsers always revalidate.
  • Anything that sets a cookie, redirects, fails with a server error or isn’t a read is never cached, so session data can’t leak into the shared cache. Not-found pages are cached for only a minute.
  • Because the cache key includes the Worker version, each deploy starts with an empty cache and never serves HTML from an older build.
  • Preview deployments are a separate Worker with a noindex header, replacing what Oxygen would have done for us.

Snow / Motion, the founder’s Hydrogen showcase, uses both hosts. It deploys to Oxygen from GitHub Actions, but it runs on a development store, which has no public Oxygen environment, so its public copy is served from Workers.

What to test before you commit

  1. Deploy the same build to both hosts, if your plan allows, and compare response times for the pages that matter from the regions where your customers are.
  2. On Workers, check CPU time per request for uncached pages in the Workers logs. If it approaches the Free plan’s 10 ms, plan for the Paid plan or for aggressive caching.
  3. Confirm that a logged-in or cart-holding visitor never receives a cached page meant for someone else.
  4. Run a Hydrogen upgrade on the self-hosted build before launch, to find out early how much the self-hosting changes cost you each time.

How to choose

SituationBetter fit
A paid-plan store that wants the fewest moving partsOxygen
Several public environments needed (staging, market previews)Oxygen on Plus, or self-hosted
The storefront must sit alongside other Workers, bindings or infrastructure you already runSelf-hosted on Workers
No developer to own caching, sessions and upgrades on a custom hostOxygen
A public URL from a development store (demos, prototypes)Self-hosted

Default to Oxygen. Self-hosting is a reasonable choice, but it moves the caching, preview and upgrade-testing work onto your team. If you are still deciding whether headless is right at all, start with Hydrogen vs Liquid.

Questions

Is Oxygen free?
Shopify states that Oxygen is available at no extra charge on paid Shopify plans. It isn’t available on Agentic plans.
Can a development store have a public Hydrogen site on Oxygen?
No. Development stores and trial plans can deploy to Oxygen, but they have no public environments, so every deployment URL needs a store login.
Can Hydrogen run on Cloudflare Workers?
Yes. Shopify’s self-hosting guide lists Cloudflare Workers alongside Vercel, Netlify and Fly.io. You need the Headless channel for API tokens, a Web Cache API cache and a session implementation.
Why does the Storefront API throttle my self-hosted storefront?
Server-side requests should carry the Shopify-Storefront-Buyer-IP header with the buyer’s IP address. Without it, Shopify can’t tell buyers apart, which can result in throttled requests.

Sources

  1. Hydrogen and Oxygen fundamentalsShopify developer documentation, checked 26 September 2026
  2. Oxygen environmentsShopify developer documentation, checked 26 September 2026
  3. Self-hosting HydrogenShopify developer documentation, checked 26 September 2026
  4. Storefront API reference (authentication and rate limits)Shopify developer documentation, checked 26 September 2026
  5. Workers limitsCloudflare developer documentation, checked 26 September 2026
  6. Workers CacheCloudflare developer documentation, checked 26 September 2026