Edge Quotas & Resource Exhaustion in Shopify Oxygen

Introduction

Shopify Oxygen is powerful — but it isn’t infinite. Every storefront runs inside an edge container with strict quotas on CPU, memory, and network requests. These limits are designed to keep Oxygen fast and fair across thousands of stores.

But when developers push too hard — with heavy 3D libraries, unoptimized GraphQL calls, or runaway server-side logic — they run into resource exhaustion. The result? Unexpected slowdowns, 500 errors, or even blocked deployments.

This article breaks down what edge quotas are, why they matter, and how to stay well within the limits.

What Are Edge Quotas?

On Oxygen, every request lives inside a runtime sandbox with resource caps:

  • CPU cycles → prevent long-running synchronous work.
  • Memory usage → keep containers lightweight.
  • I/O subrequests → capped at ~60 (see Queue 6, #2).
  • Bundle size → capped at ~4 MB (see Queue 6, #1).
  • Execution timeouts → hard cutoffs for runaway processes.

These quotas are invisible to customers but very real for developers.

Signs You’re Hitting Limits

  • 🚨 Cold-start delays (CPU/memory spike on first load).
  • 🚨 TTFB creep (100 ms → 400 ms+).
  • 🚨 Checkout routes failing with vague 500s.
  • 🚨 Deployment rejections (bundle/subrequest caps exceeded).

Real-World Scenarios

  1. Heavy 3D libraries: Importing all of Three.js + GSAP into the bundle → blows memory + bundle cap.
  2. CMS fetch storm: Each route calls Sanity, Contentful, and Storefront API → 60+ subrequests, timeout triggered.
  3. Overfetching GraphQL: Querying all metafields instead of just one → runaway CPU + memory.
  4. AI integrations: Trying to call OpenAI or Vertex AI directly in-server → long response times → Oxygen timeouts.

Staying Within Quotas

Optimize Imports

  • ✅ Use dynamic imports for GSAP/Three.js.
  • ✅ Replace lodash with lodash-es (tree-shakeable).
  • ✅ Don’t bundle test/dev utilities into prod.

Control API Calls

  • ✅ Batch GraphQL queries.
  • ✅ Cache with stale-while-revalidate.
  • ✅ Pre-generate static data where possible.

Profile & Monitor

  • ✅ Use --subrequest-profiler in dev.
  • ✅ Run Lighthouse with server timings enabled.
  • ✅ Stream logs to Datadog/Splunk for memory/CPU alerts.

DevOps Guardrails

GitHub Actions Check for Route Health

- name: Route smoke test run: | curl -w "TTFB: %{time_starttransfer}\n" -o /dev/null -s https://your-oxygen-preview.myshopify.com/

k6 Load Test (Detect Memory/CPU Spikes)

import http from 'k6/http'; import { check } from 'k6'; export const options = { vus: 10, duration: '30s' }; export default function () { const res = http.get(`${__ENV.TARGET_URL}/products/example`); check(res, { 'TTFB < 300ms': r => r.timings.waiting < 300 }); }

Conclusion

Shopify Oxygen quotas are not constraints to fear — they’re guardrails that keep your store fast at scale. Developers who respect these limits build storefronts that deploy cleanly, serve customers globally, and never get caught off-guard by runtime exhaustion.

In the Oxygen era, success means engineering within quotas, not against them.