Surviving Shopify Oxygen’s Quotas: Memory, CPU, and Bundle Size Guardrails
Introduction
Oxygen is Shopify’s global edge hosting platform for Hydrogen storefronts. It delivers speed and scale — but with strict quotas. Developers who ignore them risk silent failures, inflated costs, or customer-facing outages.
This post unpacks Oxygen’s bundle size, subrequest, memory, and CPU guardrails — why they exist, what breaks when you hit them, and how to design storefronts that stay inside the lines.
Why Shopify Enforces Quotas
- 🛡 Protect the multi-tenant edge → one storefront can’t hog resources.
- ⚡ Force performance discipline → quotas encourage lean, cache-friendly apps.
- 🌍 Ensure global consistency → limits apply evenly across PoPs (points of presence).
Common Quotas
1. Bundle Size (<10 MB)
- Failure Mode: Build deploys fail or Oxygen rejects bundle.
- Cause: Too many dependencies, unoptimized images, bloated JS.
- Fix: Code splitting, tree-shaking, image/CDN offload.
2. Subrequest Budget (~40 per route)
- Failure Mode: “Exceeded subrequest budget” error.
- Cause: Over-fetching APIs, multiple GraphQL calls per component.
- Fix: Consolidate queries, cache at loader level, prefetch data.
3. Memory (~128 MB per request)
- Failure Mode: Function crashes mid-request.
- Cause: Large in-memory JSON, oversized product catalog fetches.
- Fix: Stream results, paginate queries, store large payloads externally.
4. CPU Execution (~30s cap)
- Failure Mode: Timeout → page never resolves.
- Cause: Heavy computation in loaders, synchronous loops.
- Fix: Push processing to background jobs, precompute at build.
Debugging Quota Failures
- Check Oxygen logs → errors appear in deploy dashboard.
- Use Datadog/Splunk/Sentry → add custom metrics for subrequests/memory.
- Run Lighthouse CI + k6 → simulate heavy load and catch quota edge cases.
Mitigation Strategies
Cache-First Design
- Tokenless queries cached at the edge.
- Use CacheShort or CacheLong for Storefront API calls.
Split Functions by Responsibility
- Don’t lump everything into one loader.
- Example: cart mutations separate from PDP loaders.
Bundle Hygiene
- Run webpack-bundle-analyzer before deploy.
- Replace heavy dependencies with lighter alternatives.
Lazy Load & Offload
- Lazy load admin-only features.
- Offload big images/videos to CDN or Shopify Files API.
Case Example: Fashion Brand
- Initial Hydrogen build failed → 15 MB bundle, 75 subrequests.
- Fixes:
- Split code by route.
- Consolidated queries with GraphQL fragments.
- Cached tokenless product queries.
- Result: 6 MB bundle, 28 subrequests → stable Oxygen deploys.
Best Practices
- ✅ Budget subrequests in CI/CD.
- ✅ Run bundle size analyzer pre-deploy.
- ✅ Use pagination for all large queries.
- ✅ Document Oxygen limits for future devs.
- ✅ Treat quotas as design constraints, not bugs.
Conclusion
Oxygen’s quotas may feel restrictive, but they exist to keep storefronts fast and reliable. By respecting bundle size, subrequest, memory, and CPU limits, developers build Hydrogen stores that scale globally without breaking.
Quotas aren’t barriers — they’re guardrails for performance.