The challenge
The client's headless Shopify Plus store was hemorrhaging revenue. Page loads hit 6.1 seconds on collection pages, the Node.js server crashed every 4-6 hours from memory leaks, and their Core Web Vitals were deep in the red — Google had demoted their search rankings.
Their in-house team had spent 6 months trying to diagnose the issues. They suspected Apollo Client but couldn't pinpoint the root cause. Meanwhile, analytics showed 34% of users abandoning sessions before the first page finished loading.
Our approach
We started with a deep performance audit: Node.js heap profiling, Chrome DevTools performance traces, network waterfall analysis, and Apollo Client cache inspection. Within 48 hours, we identified 7 critical issues — 3 memory leaks and 4 performance bottlenecks.
The memory leaks were all related to Apollo Client's cache behavior during server-side rendering. The cache was accumulating normalized entities across requests without cleanup. Each SSR request added to the heap until the process ran out of memory and crashed.
Key technical decisions:
- Per-request Apollo cache instances instead of a shared global cache during SSR
- Redis caching layer for Shopify Storefront API responses (5-minute TTL)
- Chose NOT to rewrite — surgical fixes were faster and less risky than a rebuild
- Cloudflare Workers for edge-side image optimization and HTML streaming
What we built
A stabilized, high-performance storefront with proper observability:
- Zero server crashes (was crashing every 4-6 hours)
- LCP from 6.1s to 0.8s across all collection and product pages
- GraphQL query batching reducing API calls by 70%
- Redis caching layer with intelligent invalidation on Shopify webhooks
- Datadog APM dashboards with memory, latency, and error rate alerting
- Lighthouse CI gates preventing performance regressions in PRs