Performance Budgets in Shopify Oxygen: Staying Within Limits

Introduction

Shopify Oxygen is powerful, but it isn’t limitless. Edge workers have hard performance ceilings — bundle size, memory, CPU, subrequest budgets — and ignoring them leads to failed deploys or degraded user experience.

The fix? Treat these constraints as performance budgets and enforce them early in Hydrogen projects.

Oxygen Runtime Realities

  • 📦 Bundle size → keep <5MB compressed.
  • 🧠 Memory quota → ~128MB per worker.
  • ⏱️ CPU time → capped (~30s per request).
  • 🔀 Subrequest budget → ~40 per route.

👉 Think of Oxygen like a race car: it’s fast, but only if you keep it lean.

TTFB Budgets

  • Global targets: aim for <300–400ms TTFB.
  • p95/p99 monitoring: measure worst-case, not just average.
  • Cold start overhead: add 100–300ms if bundles are heavy.

SSR & Streaming Strategies

Defer Secondary Data

export async function loader({context}) { return defer({ product: context.storefront.query(PRODUCT_QUERY), reviews: fetchReviews(), // streamed later }); }

👉 Critical data SSR’d, reviews streamed → faster TTFB.

Split Workers

  • Use separate workers for PDPs vs dashboards.
  • Avoid “everything in one worker” bloat.

Cache Aggressively

  • Cache catalog + collections long.
  • Cache PDPs short with background refresh.

Guardrails for Teams

  1. Forbidden APIs
    • No Node-only modules (fs, crypto).
    • Use edge-safe replacements.
  2. Bundle Analyzer in CI/CD
    • Fail build >5MB compressed.
    • Alert on heavy libs.
  3. Subrequest Budget Check
    • Enforce <40 queries per route.
    • Batch GraphQL queries when possible.
  4. Observability
    • Use Shopify profiler logs.
    • Monitor with Lighthouse CI + RUM.

Case Example: Lifestyle Brand

  • Original PDP worker = 9MB bundle, 70+ subrequests.
  • Oxygen deploys failed intermittently.
  • Fixes:
    • Tree-shook UI library.
    • Batched Storefront API queries.
    • Cached PLPs.
  • Final: 3.5MB worker, 32 subrequests, TTFB ~220ms.

Conclusion

Oxygen performance budgets aren’t restrictions — they’re design parameters. By enforcing bundle, memory, CPU, and subrequest limits, Hydrogen stores stay lean, fast, and scalable.

Build within the budget, and Oxygen will fly.