Our Magento speed optimization service implements everything in this guide for you. Magento (Adobe Commerce) powers over 250,000 online stores worldwide, from mid-market retailers to global enterprises processing billions in annual GMV. It's the most architecturally complex e-commerce platform available, a layered stack of PHP application code, MySQL/MariaDB database, Redis object and session caching, Varnish HTTP cache, Elasticsearch/OpenSearch, and optional CDN, and that complexity is both its greatest strength and its biggest performance liability.
The average Magento store takes 4-7 seconds to load on mobile. Yet a properly optimized Magento store can outperform every other platform: sub-100ms TTFB on cached pages via Varnish, 200ms uncached TTFB with tuned Redis and OPcache, and 90+ Lighthouse scores with the Hyvä theme. The gap between a slow Magento store and a fast one is enormous, and almost entirely a matter of configuration, not platform limitation.
The business impact is equally dramatic. Amazon found that every 100ms of latency costs 1% of revenue. For a Magento store doing $500K/month, cutting load time from 5 seconds to 2 seconds could mean $50K-$100K in additional monthly revenue from the same traffic, before factoring in the SEO boost from passing Core Web Vitals.
This guide consolidates everything we've learned from optimizing hundreds of Magento stores into a single, comprehensive resource. You'll learn how to configure Varnish FPC with proper VCL rules and ESI hole-punching, tune Redis for object caching and session storage, audit and eliminate extension bloat, optimize MySQL queries and Elasticsearch indexes, migrate to the Hyvä theme for an 80%+ JavaScript reduction, build a high-performance image pipeline, and pass all three Core Web Vitals for better Google rankings. Whether you're on Magento Open Source, Adobe Commerce, or Adobe Commerce Cloud, every section includes actionable steps you can implement today.
TL;DR
Magento stores are slow because of misconfigured Varnish FPC (cache hit rates below 85%), extension bloat (each extension adds database queries, JavaScript, and event observers), untuned Redis/MySQL, and heavy front-end frameworks (RequireJS + KnockoutJS on Luma theme). Quick wins: 1) Verify Varnish FPC is working — check X-Cache headers and aim for 90%+ hit rates. 2) Audit extensions — disable one at a time, measure TTFB difference, remove unused ones (disabled extensions still load config). 3) Configure Redis with separate databases for cache (db0, allkeys-lru) and sessions (db1, noeviction), using Unix sockets. 4) Optimize MySQL — add missing indexes, clean orphaned data, tune innodb_buffer_pool_size to 70% of available RAM. 5) Migrate to Hyvä theme to replace RequireJS/KnockoutJS with Alpine.js (80%+ JS reduction). 6) Preload LCP images, inline critical CSS, defer non-critical JS. 7) Reserve CSS min-height for ESI blocks to prevent CLS. 8) Monitor CrUX field data — Google uses the 75th percentile of real-user data over 28 days for ranking, not lab scores.
Key Takeaways
- ✓Magento's layered architecture (Varnish → Redis → PHP-FPM → MySQL → Elasticsearch) means performance issues can originate at any layer — and each layer has dedicated optimization levers.
- ✓Varnish FPC misconfiguration is the #1 cause of slow Magento stores — properly configured, it reduces TTFB from 2–5 seconds to under 100ms.
- ✓Extension bloat compounds exponentially: each extension adds database queries, JavaScript, CSS, event observers, and plugins that intercept core logic.
- ✓The Hyvä theme replaces RequireJS and KnockoutJS with Alpine.js, reducing front-end JavaScript by 80%+ and eliminating most INP issues.
- ✓Redis must be configured with separate databases for cache vs. sessions, proper eviction policies, and Unix sockets for lowest latency.
- ✓Elasticsearch/OpenSearch tuning dramatically improves category and search page performance — the most visited page types on e-commerce sites.
- ✓A properly optimized Magento store can achieve sub-100ms TTFB (cached), 90+ Lighthouse scores, and outperform simpler platforms.
Magento's Performance Architecture: Understanding the Stack
Magento (Adobe Commerce) is the most architecturally complex e-commerce platform available. Understanding its layered architecture is essential before optimizing — because performance issues can originate at any layer, and fixing the wrong layer wastes time.
The request lifecycle flows through six distinct layers:
- CDN/Edge Layer: Fastly (Adobe Commerce Cloud) or your chosen CDN handles static assets, SSL termination, and potentially edge-side logic
- Varnish HTTP Cache: Serves cached HTML pages directly, bypassing PHP entirely for cache hits — this is where the biggest TTFB wins happen
- Web Server (Nginx/Apache): Routes requests to PHP-FPM, serves static files, handles SSL if not terminated at CDN
- PHP-FPM Application: Executes Magento's PHP code — routing, business logic, template rendering, event dispatch
- Data Layer: MySQL/MariaDB for persistent data, Redis for object cache and sessions, Elasticsearch/OpenSearch for search and catalog navigation
- Front-End Layer: Browser rendering of HTML/CSS/JavaScript — RequireJS + KnockoutJS (Luma) or Alpine.js + Tailwind (Hyvä)
The critical insight: optimizing layer 6 (front-end) while layer 2 (Varnish) is misconfigured is like polishing a car with a broken engine. Always optimize from the bottom up: infrastructure first, then application, then front-end.
For Adobe Commerce Cloud specifically, Fastly acts as both CDN and Varnish replacement — its VCL snippets control caching behavior, and its Image Optimizer handles responsive image delivery. Understanding whether you're on self-hosted (you manage Varnish) or Cloud (Fastly manages caching) determines which tools and configurations apply.
Varnish Full Page Cache: The Single Biggest Performance Lever
Varnish FPC is the most impactful optimization for any Magento store. When properly configured, it reduces TTFB from 2–5 seconds (PHP execution) to under 100ms (served from memory). No other single change comes close to this impact.
How Varnish Works with Magento
Varnish sits in front of your web server and caches complete HTML responses. When a visitor requests a page, Varnish checks if it has a cached copy. If yes (cache hit), it serves the HTML directly from RAM — PHP never executes. If no (cache miss), the request passes through to Magento, and Varnish stores the response for future requests.
VCL Configuration
Magento generates a base VCL file (bin/magento varnish:vcl:generate), but you'll need to customize it:
- Vary headers: Pages vary by currency, language, customer group, and store view. Incorrect Vary configuration causes either cache pollution (wrong content served) or cache fragmentation (too many variants, low hit rate)
- TTL settings: Static pages (CMS, about) → 86400s; category pages → 3600s; PDPs → 1800s; cart/checkout → 0 (never cache)
- Grace mode: Serve stale content for 300–600s while the backend regenerates — prevents thundering herd on cache expiry
- Health checks: Configure backend probes so Varnish serves stale content if PHP-FPM is overloaded rather than returning 503 errors
ESI (Edge Side Includes) Hole-Punching
Magento uses ESI to handle dynamic blocks within cached pages. The page HTML is cached, but blocks like cart count, customer greeting, and recently viewed products are fetched separately via ESI tags. Common issues:
- Too many ESI blocks reduce the benefit of FPC (each is a separate backend request)
- ESI blocks with slow rendering increase overall page TTFB
- Missing ESI configuration causes entire pages to be marked uncacheable
Debugging Cache Misses
Use varnishlog to trace why requests miss cache:
- Check for cookies preventing caching (especially third-party analytics cookies)
- Look for Vary header mismatches
- Identify URLs with query parameters that fragment cache
- Monitor X-Magento-Cache-Debug header (HIT/MISS) in browser DevTools
Cache Warming
After deployment (bin/magento cache:flush clears Varnish), run a cache warming script that crawls your sitemap URLs. This ensures no real visitor hits an uncached page. Use wget or a custom script with concurrency limits (don't overwhelm the backend):
wget --spider --recursive --no-parent --quiet --header="X-Magento-Cache-Warm: 1" https://yourstore.com/sitemap.xml
Redis Configuration: Object Cache, Sessions, and Tuning
Redis serves two critical roles in Magento: object caching (storing compiled configuration, layout XML, and block HTML) and session storage (keeping user sessions in-memory instead of files or database).
Separate Databases for Cache vs. Sessions
Never use the same Redis database for both — they have fundamentally different requirements:
- Cache (db0): Use allkeys-lru eviction. When memory fills, Redis evicts least-recently-used keys. This is safe because cached data can be regenerated.
- Sessions (db1): Use noeviction policy. Sessions must never be evicted during a user's checkout flow — evicting a session mid-purchase causes cart abandonment.
Memory Configuration
Set maxmemory based on your catalog size and traffic:
- Small stores (< 10K SKUs): 256MB cache, 128MB sessions
- Medium stores (10K–100K SKUs): 512MB cache, 256MB sessions
- Large stores (100K+ SKUs): 1GB+ cache, 512MB sessions
Monitor with redis-cli INFO memory — if used_memory_peak approaches maxmemory, increase allocation.
Connection Optimization
For same-server deployments, use Unix sockets instead of TCP:
'session' => ['save' => 'redis', 'redis' => ['host' => '/var/run/redis/redis.sock', 'port' => '0', 'database' => '1']]
Unix sockets eliminate TCP overhead (handshake, packet framing), saving 10–20% latency per operation. For remote Redis (ElastiCache, Redis Cloud), ensure the Redis instance is in the same availability zone as your web servers.
Monitoring Key Metrics
- hit_rate: cache_hits / (cache_hits + cache_misses) — target 95%+
- evicted_keys: Should be near zero for sessions, acceptable for cache if hit rate stays high
- connected_clients: Watch for connection leaks from misconfigured PHP-FPM workers
- instantaneous_ops_per_sec: Baseline for capacity planning
PHP-FPM and OPcache: Application Layer Performance
PHP-FPM (FastCGI Process Manager) manages the pool of PHP workers that execute Magento's application code. Misconfiguration here causes either wasted resources (too many idle workers) or request queuing (too few workers during traffic spikes).
Worker Count Formula
Each Magento PHP-FPM worker consumes 128–256MB of RAM. Calculate max_children:
(available_RAM_MB × 0.7) / average_worker_memory_MB = max_children
Example: 16GB server → (16384 × 0.7) / 200 = ~57 workers
Set pm = dynamic with:
- pm.start_servers = 25% of max_children
- pm.min_spare_servers = 10% of max_children
- pm.max_spare_servers = 75% of max_children
- pm.max_requests = 1000 (recycle workers to prevent memory leaks)
OPcache Configuration
OPcache caches compiled PHP bytecode, eliminating the need to parse and compile PHP files on every request. Magento has thousands of PHP files, making OPcache essential:
opcache.memory_consumption=256 opcache.max_accelerated_files=65536 opcache.validate_timestamps=0 (production only — clear manually on deploy) opcache.interned_strings_buffer=32 opcache.save_comments=1 (required by Magento's annotation-based DI)
Verify with opcache_get_status(): hit rate should be 99%+, and num_cached_files should match the total number of PHP files in your Magento installation.
PHP 8.1+ JIT Compilation
Enable the JIT compiler for additional 10–25% execution speed on computation-heavy operations (price rules, EAV loading, indexing):
opcache.jit_buffer_size=128M opcache.jit=1255 (tracing mode)
Monitor with opcache_get_status()['jit'] — look for increasing opt_level counts indicating hot code paths are being JIT-compiled.
Extension Audit: Identifying and Eliminating Bloat
Magento's extension marketplace is both its greatest strength and its biggest performance weakness. Each installed extension potentially adds:
- Database tables and queries: Some extensions add 10+ tables and run queries on every page load
- Event observers and plugins: Intercept core logic at potentially hundreds of interception points — each adding microseconds that compound into milliseconds
- Front-end assets: JavaScript, CSS, and templates loaded on every page regardless of whether the extension's functionality is needed on that page
- Admin panel overhead: Configuration loading, menu rendering, and system checks that slow admin operations
- Cron jobs: Background processes competing for server resources
The Profiling Process
- List all installed extensions: bin/magento module:status
- Baseline performance: measure TTFB on homepage, a category page, and a PDP
- Disable extensions one at a time: bin/magento module:disable Vendor_Module
- Re-measure TTFB after each disable
- Create a spreadsheet: extension name, TTFB impact, business value, verdict (keep/remove/replace)
Critical Insight: Disabled Extensions Still Load Config
Simply disabling an extension via the admin panel doesn't remove its performance overhead. The module's etc/ configuration XML is still loaded and parsed on every request. To fully eliminate an extension's impact, you must remove it via Composer: composer remove vendor/module-name
Plugin Chain Analysis
Use bin/magento dev:di:info to trace which extensions intercept which methods. Look for extensions that plugin into hot code paths:
- Catalog product load (called hundreds of times on category pages)
- Quote/cart operations (called on every page with mini-cart)
- Customer session initialization (called on every authenticated request)
Target: Under 30 Active Third-Party Extensions
Stores with 50+ extensions almost always have severe performance issues. For every extension, ask: Is this functionality available in Magento core? Can it be replaced with a lighter alternative? Is the business value worth the performance cost?
MySQL/MariaDB Optimization: Queries, Indexes, and Configuration
Magento's EAV (Entity-Attribute-Value) data model creates complex queries with multiple JOINs across attribute tables. This architecture provides flexibility (unlimited custom attributes) at the cost of query performance.
Slow Query Analysis
Enable the slow query log:
slow_query_log = 1 long_query_time = 1 slow_query_log_file = /var/log/mysql/slow.log
Analyze with mysqldumpslow or pt-query-digest (Percona Toolkit). Common slow query patterns in Magento:
- EAV attribute loading: Product loads joining 10+ attribute tables — fix with flat catalog indexes or targeted attribute selection
- Category product counts: Full table scans for layered navigation — fix with proper anchored category indexing
- Quote item collection: Cart queries joining multiple tables — fix by cleaning abandoned quotes (bin/magento cron:run --group=sales_clean_quotes)
- Search queries: Full-text searches falling back to MySQL instead of Elasticsearch — fix by ensuring Elasticsearch is properly configured as the search engine
Key InnoDB Settings
innodb_buffer_pool_size = 70% of available RAM (the most impactful MySQL setting) innodb_log_file_size = 256MB–1GB (larger = better write performance, slower recovery) innodb_flush_method = O_DIRECT (avoid double-buffering with OS page cache) table_open_cache = 4000 (Magento has hundreds of tables) max_connections = 150 (match PHP-FPM worker count + cron + admin)
Data Hygiene
Magento accumulates data that bloats tables and slows queries:
- Clean expired quotes: DELETE FROM quote WHERE updated_at < DATE_SUB(NOW(), INTERVAL 30 DAY) AND is_active = 1
- Remove orphaned catalog images: bin/magento catalog:images:remove-orphans
- Clean old log entries: bin/magento log:clean
- Rebuild flat catalog indexes: bin/magento indexer:reindex catalog_product_flat catalog_category_flat
Indexer Configuration
Set all indexers to 'Update by Schedule' (not 'Update on Save'). 'Update on Save' triggers reindexing on every product save, causing write amplification during bulk imports and admin operations. 'Update by Schedule' batches changes and processes them via cron, typically every minute.
Elasticsearch/OpenSearch: Catalog Search and Navigation
Elasticsearch (or OpenSearch in Adobe Commerce 2.4.6+) powers category pages, search results, and layered navigation — collectively the most visited page types on e-commerce sites. Proper tuning here impacts the majority of your traffic.
Index Configuration
- number_of_replicas: Set to 1 for read performance (queries can be served by either primary or replica shard)
- refresh_interval: Change from default 1s to 30s for better indexing throughput. Products don't need to be searchable within 1 second of saving.
- max_result_window: Set appropriate for your catalog size (default 10000 is fine for most stores)
- Translog durability: Set to 'async' with sync_interval of 5s for better write performance during reindexing
Analyzer Configuration
Magento's default analyzers work for basic search but can be improved:
- Autocomplete: Add edge_ngram tokenizer for instant search suggestions
- Synonyms: Configure synonym filters for common product term variations (e.g., 'couch' → 'sofa', 'TV' → 'television')
- Stop words: Customize stop word lists for your product domain
Query Performance
Monitor individual query latency with /_nodes/stats — queries should complete in under 50ms. If category pages are slow:
- Check that layered navigation attributes are mapped as keyword type (not analyzed text)
- Ensure aggregation queries use the terms aggregation (not scripts)
- Verify that product visibility and status filters use filter context (cached) not query context
Large Catalog Optimization (100K+ SKUs)
For very large catalogs:
- Increase Java heap size (ES_JAVA_OPTS) to 50% of server RAM, max 32GB
- Consider separate indexes for search vs. category navigation
- Use scroll API for bulk operations instead of deep pagination
- Monitor JVM garbage collection — long GC pauses cause search latency spikes
Front-End Optimization: Luma vs. Hyvä Theme Performance
Magento's front-end is where the most dramatic performance differences exist between stores. The choice between Luma (default) and Hyvä (modern alternative) is the single biggest front-end decision you'll make.
Luma Theme: The Legacy Stack
Luma ships with Magento and uses:
- RequireJS: AMD module loader that manages JavaScript dependencies. The problem: it loads modules synchronously, creating waterfall chains where each module must load before its dependents can initialize.
- KnockoutJS: MVVM framework used for dynamic UI (mini-cart, checkout, configurable product options). The problem: KnockoutJS templates are compiled in the browser, creating long tasks during page initialization.
- jQuery + jQuery UI: Used extensively throughout Luma, adding 90KB+ of JavaScript overhead.
- Less CSS: Compiled server-side, but the generated CSS includes substantial unused rules.
Total front-end JavaScript on a typical Luma PDP: 300–500KB (compressed), executing 1–3 seconds of main-thread work.
Hyvä Theme: The Modern Stack
Hyvä replaces the entire Luma front-end stack with:
- Alpine.js: 15KB reactive framework (vs. KnockoutJS's 60KB+). Components initialize instantly with minimal main-thread impact.
- Tailwind CSS: Utility-first CSS that generates only the classes you use — typical Hyvä CSS: 20–40KB vs. Luma's 200KB+.
- No RequireJS: Scripts use standard ES modules with dynamic import() for code splitting.
- No jQuery: Native JavaScript APIs replace jQuery utilities.
Total front-end JavaScript on a typical Hyvä PDP: 40–80KB (compressed), executing under 200ms of main-thread work.
Migration Considerations
Hyvä migration timeline: 2–8 weeks depending on customization complexity. Key factors:
- Custom Luma templates must be rewritten for Alpine.js
- Third-party extensions need Hyvä-compatible versions (the Hyvä compatibility module handles many automatically)
- Checkout customizations are the most complex to migrate
- The Hyvä ecosystem has grown rapidly — 90%+ of common extensions now have Hyvä versions
Optimizing Luma (If Migration Isn't Feasible)
If you must stay on Luma:
- Advanced JS bundling: bin/magento setup:static-content:deploy with --strategy=compact. Configure requirejs-config.js to bundle related modules.
- Critical CSS: Use tools like Penthouse to extract and inline above-fold CSS, deferring the rest.
- Lazy KnockoutJS init: Wrap KnockoutJS component initialization in IntersectionObserver callbacks — only initialize components when they scroll into view.
- Remove jQuery UI: Most Luma stores only use a fraction of jQuery UI widgets. Create a custom build that includes only what you need.
- Preload key modules: Use
<link rel="modulepreload">for critical RequireJS modules to eliminate waterfall chains.
Image Pipeline: WebP, AVIF, and Responsive Delivery
Images typically account for 60–80% of page weight on Magento product pages. An optimized image pipeline can cut total page weight by 50%+ without any visible quality loss.
Format Selection
- WebP: 25–35% smaller than JPEG at equivalent quality. Supported by 97%+ of browsers. This should be your default format.
- AVIF: 40–50% smaller than JPEG, but encoding is slower and browser support is 93%. Use as progressive enhancement with
<picture>element fallback. - JPEG: Fallback format for the 3% of browsers without WebP support.
- SVG: For logos, icons, and illustrations — infinitely scalable, typically 1–5KB.
Magento Image Configuration
Configure image resizing in view.xml:
<image id="category_page_grid" type="small_image"><width>240</width><height>300</height></image>
<image id="product_page_image_medium" type="image"><width>700</width><height>700</height></image>
Generate responsive srcsets:
<img srcset="product-240w.webp 240w, product-480w.webp 480w, product-700w.webp 700w" sizes="(max-width: 640px) 240px, (max-width: 1024px) 480px, 700px" src="product-700w.jpg" alt="Product Name" width="700" height="700" loading="lazy">
LCP Image Preloading
The hero image on each page type must be preloaded — it's almost always the LCP element:
<link rel="preload" as="image" type="image/webp" href="hero-banner.webp" fetchpriority="high">
Add this in the <head> of your layout XML for homepage, category, and landing page templates. Do NOT preload images on PDPs — the main product image is typically below fold on mobile.
Adobe Commerce Cloud: Fastly Image Optimizer
If on Adobe Commerce Cloud, enable Fastly IO for automatic format conversion, resizing, and quality optimization at the CDN edge — no Magento-side image processing needed. Configure in Stores → Configuration → Advanced → System → Full Page Cache → Fastly → Image Optimization.
Core Web Vitals: Passing All Three Metrics on Magento
Magento stores face unique Core Web Vitals challenges compared to other platforms. The combination of server-side complexity (TTFB), heavy front-end frameworks (INP), and dynamic content injection (CLS) creates a trifecta of CWV issues that requires a holistic approach.
LCP (Largest Contentful Paint) — Target: < 2.5s
LCP on Magento is primarily a TTFB problem. Fix the server stack first (Varnish, Redis, PHP-FPM), then optimize the client side:
- Verify Varnish FPC is serving cached responses (X-Cache: HIT header)
- Preload the LCP image (hero banner on homepage, first product image on category pages)
- Inline critical CSS — the CSS needed to render above-fold content should be in the
<head>, not a separate file - Defer non-critical JavaScript — RequireJS bundles that aren't needed for initial render should load after LCP
- Use fetchpriority="high" on the LCP image element
- Ensure CDN is serving images from edge locations close to your users
INP (Interaction to Next Paint) — Target: < 200ms
INP measures the responsiveness of interactions (clicks, taps, key presses). Magento's biggest INP challenges:
- RequireJS module initialization: On Luma, clicking an element that requires a not-yet-loaded module triggers a synchronous load chain. Fix: preload critical interaction modules or migrate to Hyvä.
- KnockoutJS template rendering: Configurable product options (size, color selectors) trigger KnockoutJS re-rendering that blocks the main thread. Fix: break updates into smaller batches with requestAnimationFrame.
- Add-to-cart handlers: The full add-to-cart flow (validation, AJAX request, mini-cart update, message display) is a single synchronous operation. Fix: respond immediately with UI feedback, process the rest asynchronously.
- Mega menu interactions: Nested navigation menus with hundreds of items. Fix: render submenus on hover/click, not on page load.
CLS (Cumulative Layout Shift) — Target: < 0.1
CLS on Magento is primarily caused by:
- ESI blocks: Varnish hole-punched blocks (cart count, customer greeting, recently viewed) render after the initial cached HTML, pushing content down. Fix: reserve space with CSS min-height on ESI container elements.
- Late-loading product images: Images without explicit dimensions cause layout shifts when they load. Fix: add width and height attributes to all
<img>tags in templates. - Web fonts: Font swap causes text to reflow. Fix: use font-display:swap with size-adjusted fallback fonts (@font-face with size-adjust, ascent-override, descent-override).
- Dynamic content injection: Reviews, related products, and upsell blocks loaded via AJAX. Fix: reserve skeleton placeholders with min-height.
Testing Strategy
Test the four critical page types separately — they have very different performance profiles:
- Homepage (usually passes easiest — mostly static content)
- Category/listing pages (hardest for INP — layered navigation interactions)
- Product detail pages (hardest for LCP — hero image + heavy JS initialization)
- Checkout (hardest overall — heavy JS application with complex interactions)
Use CrUX Dashboard to monitor field data by page type, not just origin-level metrics.
Passing all three CWV metrics is the practical bar for ranking — our Core Web Vitals optimization service focuses on exactly this.
Adobe Commerce Cloud: Platform-Specific Optimization
Adobe Commerce Cloud (formerly Magento Commerce Cloud) runs on a managed infrastructure with Fastly CDN, AWS services, and automated deployment pipelines. While you lose some configuration control compared to self-hosted, Cloud offers platform-specific optimizations:
Fastly Configuration
Fastly replaces Varnish on Cloud. Configure via Stores → Configuration → Advanced → System → Full Page Cache → Fastly:
- VCL snippets: Custom Varnish logic deployed via Fastly's API — no direct VCL file editing
- Shielding: Enable a shield POP to reduce origin requests. All edge POPs send cache misses to the shield first, which checks its cache before hitting origin.
- Soft purging: Use surrogate keys for targeted cache invalidation instead of full purges
- Image Optimizer (IO): Automatic WebP/AVIF conversion, responsive resizing, and quality optimization at the edge
Environment Sizing
Cloud environments are sized by CPU and RAM. For performance:
- Production: Minimum M4 (4 vCPU, 16GB RAM) for stores with 50K+ SKUs
- Use dedicated worker tier for cron jobs and indexing — don't compete with web traffic
- Scale horizontally (more web instances) for traffic spikes, not vertically
Deployment Optimization
Cloud deployments clear all caches. Optimize the post-deploy phase:
- Static content deployment: Use --strategy=compact --jobs=4 to parallelize
- Cache warming: Add post_deploy hook to warm critical URLs
- Zero-downtime deployment: Ensure health checks pass before routing traffic to new instances
New Relic Integration
Cloud includes New Relic APM. Use it to:
- Monitor transaction response times by page type
- Identify slow database queries with Query Analysis
- Track deployment performance impact with Deployment Markers
- Set up alerts for TTFB exceeding thresholds
If your WooCommerce store is hitting the wall on performance, our WooCommerce speed optimization service is built around exactly that problem.
Checkout Extensibility and Shopify Functions are Plus-only levers we deploy in our Shopify Plus performance tuning engagements.
Hero-image priority, font loading, and render-blocking removal are the big LCP levers — see our LCP optimization service.
INP failures usually trace to long JavaScript tasks — our INP optimization service profiles and fixes them.
CLS is usually fixable in days — our CLS optimization service handles font-loading, image sizing, and dynamic content shifts.
Hosting + caching + CDN is the TTFB stack — our TTFB optimization service tunes all three as one engagement.
Choosing the CDN is easy; configuring edge cache rules and image optimization is hard — our CDN setup and configuration handles both.
CrUX is what Google ranks on, not lab metrics — our CrUX field-data optimization service moves the numbers that matter.
Thresholds & Benchmarks
| Metric | Good | Needs Improvement | Poor |
|---|---|---|---|
| TTFB (cached via Varnish) | < 100ms | 100–500ms | > 500ms |
| TTFB (uncached) | < 400ms | 400–1200ms | > 1200ms |
| LCP (mobile) | < 2.5s | 2.5–4.0s | > 4.0s |
| INP | < 200ms | 200–500ms | > 500ms |
| CLS | < 0.1 | 0.1–0.25 | > 0.25 |
| Varnish cache hit rate | > 90% | 85–90% | < 85% |
| Redis memory utilization | < 70% | 70–90% | > 90% |
| Total page weight (mobile) | < 1.5MB | 1.5–3MB | > 3MB |
Frequently Asked Questions
Why is my Magento store so slow?
The most common causes are: 1) Varnish FPC not properly configured (check X-Cache headers — if you're getting MISSes, PHP is executing on every request), 2) Too many extensions (each adds database queries, JavaScript, and event observers), 3) Untuned Redis (cache evictions, low hit rates), 4) MySQL slow queries (EAV JOINs without proper indexes), and 5) Heavy Luma front-end (RequireJS + KnockoutJS). Fix in this order: Varnish → Redis → MySQL → Extensions → Front-end.
What is a good TTFB for Magento?
For cached pages (served by Varnish/Fastly): under 100ms. For uncached pages (PHP execution): under 400ms. If your cached TTFB exceeds 100ms, there's likely a CDN or network issue. If uncached TTFB exceeds 1 second, focus on Redis configuration, OPcache, and extension audit.
Should I migrate from Luma to Hyvä theme?
If front-end performance is a priority (and it should be for SEO), Hyvä is the single most impactful front-end change you can make. It reduces JavaScript by 80%+, eliminates RequireJS/KnockoutJS overhead, and typically improves INP from 500ms+ to under 200ms. Migration takes 2–8 weeks depending on customization. The ROI is almost always positive within 3–6 months through improved conversion rates and SEO rankings.
How do I check my Varnish cache hit rate?
Three methods: 1) Check browser DevTools for X-Cache (HIT/MISS) and X-Magento-Cache-Debug headers on each request, 2) Run varnishstat on the server and look at MAIN.cache_hit vs MAIN.cache_miss ratios, 3) Use monitoring tools (New Relic, Datadog) that track cache hit rates over time. Target: 90%+ hit rate. Below 85% indicates VCL misconfiguration.
How many extensions is too many for Magento?
There's no absolute number, but our data shows performance degrades noticeably above 30 active third-party extensions, and severely above 50. The impact isn't linear — some extensions add 0.5ms overhead, others add 500ms. Profile each extension individually. We've seen stores go from 5s TTFB to 0.8s by removing 20 low-value extensions.
Is Magento 2 faster than Magento 1?
Magento 2's architecture is more scalable (better caching, async operations, message queues), but out-of-the-box Magento 2 with Luma theme can actually be slower than a well-optimized Magento 1 store due to heavier front-end frameworks. With Hyvä theme and proper stack tuning, Magento 2 is significantly faster than Magento 1.
What's the difference between Redis object cache and Redis session storage?
Object cache stores Magento's compiled configuration, layout XML, block HTML, and other computed data — preventing PHP from regenerating it on every request. Session storage keeps user session data (login state, cart contents) in memory instead of files or database. They MUST use separate Redis databases with different eviction policies: allkeys-lru for cache (safe to evict), noeviction for sessions (evicting a session mid-checkout causes abandonment).
How do I optimize Magento checkout speed?
Checkout is Magento's heaviest page — a full JavaScript application with KnockoutJS templates, payment SDK loading, address validation, and shipping rate calculation. Optimize by: 1) Preloading payment SDKs on the cart page, 2) Lazy-loading non-critical checkout steps, 3) Caching shipping rate responses, 4) Minimizing the number of payment methods displayed, 5) Removing marketing scripts from checkout pages entirely, 6) On Luma: optimize RequireJS bundling specifically for checkout modules.
Does Magento support HTTP/3?
Magento itself doesn't handle HTTP/3 — it's a server/CDN feature. If you're on Adobe Commerce Cloud, Fastly supports HTTP/3 by default. For self-hosted, configure Nginx with QUIC support (nginx-quic module) or use a CDN like Cloudflare/Fastly that handles HTTP/3 at the edge. HTTP/3's biggest benefit for Magento is faster connection establishment on mobile, reducing TTFB by 50–100ms on first visit.
How do I fix Magento CLS issues from Varnish ESI blocks?
ESI (Edge Side Includes) blocks are fetched separately from the cached page HTML, causing content to shift when they render. Fix by adding CSS min-height to ESI container elements: .block-customer-login { min-height: 40px; } .block-cart { min-height: 50px; } Measure the rendered height of each ESI block and reserve that space. Also consider whether each ESI block is necessary — some can be loaded lazily via JavaScript instead of ESI.
Should I use Magento's built-in CDN or a third-party CDN?
For Adobe Commerce Cloud, use Fastly (it's included and tightly integrated). For self-hosted, use a third-party CDN (Cloudflare, Fastly, or AWS CloudFront) configured to cache static assets (images, CSS, JS) and optionally HTML pages. Don't rely on Magento's 'Use CDN for static assets' setting alone — it only changes URLs but doesn't configure caching behavior. A properly configured CDN should serve 95%+ of static asset requests from edge locations.
How does Magento's flat catalog affect performance?
Flat catalog creates denormalized tables that combine EAV attribute data into single rows — dramatically faster for catalog queries (1 query instead of 10+ JOINs). However, flat catalog maintenance has overhead: reindexing takes longer, and the flat tables must be rebuilt when attributes change. For stores with under 50K SKUs, flat catalog provides modest improvement. For 100K+ SKUs, the query performance gain is significant. In Magento 2.4+, Elasticsearch handles most catalog queries, reducing the need for flat catalog on the front-end — but it's still valuable for admin and API operations.
What PHP version should I use for Magento?
Use the latest PHP version supported by your Magento release. As of 2026: Adobe Commerce 2.4.7 supports PHP 8.3 (recommended) and 8.2. Each PHP minor version brings 5–15% performance improvements through JIT optimizations, reduced memory usage, and faster array/string operations. Never run Magento on PHP 7.x — it's end-of-life and significantly slower than PHP 8.x.
How do I prevent performance regression on Magento?
Implement a performance budget and monitoring pipeline: 1) Set Lighthouse score thresholds in CI/CD (fail builds below 80), 2) Monitor CrUX data weekly for field metric trends, 3) Require performance impact assessment for every new extension, 4) Run automated load tests before major deployments, 5) Set up New Relic/Datadog alerts for TTFB exceeding 500ms, 6) Review and clean unused extensions quarterly, 7) Audit page weight monthly — flag any page exceeding 2MB.
Magento vs Shopify Plus: which is faster?
Out-of-the-box: Shopify Plus is faster (managed infrastructure, lighter themes, lower TTFB floor). Optimized: both can achieve 90+ scores and sub-2s LCP. Magento's performance ceiling is higher — with Hyvä theme, Varnish, Redis, and proper tuning, it can outperform Shopify Plus. But reaching that ceiling requires significant expertise and infrastructure investment. Choose based on business requirements (B2B complexity, multi-store, customization needs), not speed alone — speed parity is achievable on both platforms. See our Ultimate Shopify Plus Speed Guide for comparison.
How do I optimize Magento for mobile speed?
Mobile optimization for Magento focuses on: 1) Reducing JavaScript payload — Hyvä theme cuts JS by 80%, making mobile execution dramatically faster, 2) Responsive images with proper srcset and sizes attributes, 3) Preloading the mobile LCP image (often different from desktop), 4) Critical CSS inlining — mobile above-fold CSS is much smaller than desktop, 5) Touch interaction optimization — ensure tap targets are 48px+ and handlers respond within 200ms, 6) Disabling hover-triggered features that add JS overhead without mobile benefit, 7) Testing on real devices, not just Chrome DevTools throttling.
What is the best hosting for Magento performance?
For managed hosting: Adobe Commerce Cloud (Fastly CDN included, auto-scaling), Nexcess (Magento-optimized stack), or AWS with managed services (ElastiCache for Redis, RDS for MySQL, OpenSearch Service). For self-managed: minimum spec is 8 vCPU, 32GB RAM, NVMe SSD, with separate servers for MySQL and Redis/Elasticsearch in production. The hosting provider matters less than the configuration — a well-tuned $200/month VPS can outperform a misconfigured $2000/month managed host.
How do I optimize Magento GraphQL API performance?
For headless/PWA architectures using GraphQL: 1) Enable GraphQL query caching in Varnish (requires custom VCL for POST caching), 2) Use persisted queries to reduce payload size and enable GET-based caching, 3) Implement DataLoader pattern to batch resolver database queries (N+1 query prevention), 4) Set appropriate query complexity limits to prevent denial-of-service via deeply nested queries, 5) Cache resolver results in Redis, 6) Use field-level caching for rarely-changing data (category trees, CMS content).
How often should I reindex Magento?
With 'Update by Schedule' mode (recommended), indexers run automatically every minute via cron — no manual action needed. Full reindex is only required after: major data imports, attribute changes, index corruption, or Magento version upgrades. Full reindex on a 100K SKU store takes 10–30 minutes depending on hardware. Schedule full reindexes during low-traffic periods. Monitor indexer status with bin/magento indexer:status — if an indexer is stuck in 'processing' for over an hour, it likely needs manual intervention.
Does HTTP/2 Server Push help Magento performance?
HTTP/2 Server Push has been deprecated by Chrome and most browsers as of 2023. Instead, use 103 Early Hints, which achieves similar preloading benefits: the server sends a 103 response with Link headers for critical resources while still processing the full HTML response. Configure in Nginx: add_header Link '</static/css/styles.css>; rel=preload; as=style' early; Fastly and Cloudflare both support 103 Early Hints at the CDN edge.
