
Hyvä gets most of the credit on Adobe Commerce performance, and it deserves a lot of it. The Alpine.js plus Tailwind stack is dramatically lighter than Luma. But almost every team that migrates to Hyvä and stops there hits a ceiling at about 600 to 800 milliseconds Time To First Byte. The bottleneck after the migration is no longer on the storefront. It is on the server. Pulling TTFB below 200ms takes server-side discipline that has nothing to do with the theme.
This is the work most clients skip because the post-migration win feels good enough. The Core Web Vitals score moves into green. The team takes a victory lap. Three months later, marketing starts asking why the site still feels slow on category pages with a lot of products. The answer is usually a TTFB problem that lives in PHP-FPM tuning, OPcache configuration, Varnish behavior, or database query patterns that Magento generates by default.
Bemeir has tuned a lot of Adobe Commerce stores from acceptable TTFB into the sub-200ms range. The patterns below are the ones that actually move the metric. None of them are exotic. All of them assume you already have a healthy Hyvä storefront and are now trying to push the server tier as hard as the frontend tier.
What TTFB actually measures
Time To First Byte is the elapsed time between the browser firing a request and receiving the first byte of the response. On Adobe Commerce, that interval is the sum of network propagation, edge routing, Varnish hit-or-miss handling, PHP-FPM startup and execution, database query time, and any blocking external calls the page makes before it can render.
When TTFB is high, the answer is almost never in one of those slices alone. It is in the interaction of several. A page that misses Varnish, lands on a PHP-FPM worker with cold OPcache, fires three uncached database queries against a poorly indexed table, and waits on a synchronous call to an external inventory service can easily produce a 1.5 second TTFB even on a Hyvä-themed store with a perfect frontend.
The discipline of TTFB tuning is sequencing. You instrument the path, identify which slice is dominating the time on the slow requests, and you fix that slice. Then you re-measure, and the next slice surfaces. The web.dev TTFB primer is a reasonable shared vocabulary if your team has not all seen it before.
Start with cache hit ratio
The fastest TTFB on Adobe Commerce is the one where the page never touches PHP. Varnish, when configured correctly, can serve a category or product page in 30 to 60ms with no Magento involvement at all. The win is enormous, and most stores leave it on the table.
The first metric to look at is your Varnish hit ratio for the page types that actually drive traffic. Category, product, and CMS pages should run at 85 percent or higher. If you are below 70 percent, you have a cache configuration problem before you have a tuning problem. Common causes are misconfigured ESI blocks for the cart and minicart, custom modules that disable full-page cache for pages that should be cached, query string parameters that produce unique cache keys without business reason, and customer-segment-aware caching that fragments the cache by group.
Once the cache configuration is right, push the Varnish TTL upward where the business allows. Many stores run with two-hour TTLs out of caution. If your inventory and pricing systems can tolerate longer windows, eight to 24 hours is achievable on category and CMS pages with a clean cache invalidation strategy. The Varnish official tuning guide walks through the relevant trade-offs.
Bemeir’s experience is that the Varnish work alone moves TTFB on the long tail of pages by 200 to 400 milliseconds for stores that were not previously tuned. That is half of the sub-200ms goal achieved before you touch PHP at all.
Tune PHP-FPM workers and OPcache
The next slice is PHP-FPM. Two settings dominate: the number of FPM workers and the OPcache memory budget.
On Adobe Commerce, the default FPM configuration is almost always wrong for production traffic. The standard pm.dynamic settings size the pool too small for peak hours, which means high-concurrency requests queue at the PHP layer and add 100 to 300 milliseconds to TTFB even when individual requests are fast. The correct sizing depends on per-request memory consumption and the CPU count of the host, but a useful starting point is pm.max_children equal to memory available divided by 256 megabytes per worker, rounded down. For an eight-core host with 32 gigabytes of memory and Magento running, that lands around 100 to 120 workers.
OPcache is the second knob. The default Magento OPcache memory budget of 256 megabytes is too small for any non-trivial store. Push it to 512 or 1024 megabytes and confirm with opcache_get_status that the cache is not evicting compiled scripts under load. Eviction is the single most common cause of mysterious TTFB regression after a deploy. The official PHP OPcache documentation is worth reading end to end once if your team has not done it.
The table below summarizes the FPM and OPcache settings we typically end up at for mid-market Adobe Commerce stores after tuning.
| Setting | Default | Tuned |
|---|---|---|
| pm.max_children | 50 | 100 to 150 (sized to memory) |
| pm.start_servers | 10 | 25 percent of max_children |
| pm.min_spare_servers | 5 | 20 percent of max_children |
| pm.max_spare_servers | 35 | 50 percent of max_children |
| opcache.memory_consumption | 256 MB | 512 to 1024 MB |
| opcache.max_accelerated_files | 10000 | 32531 (prime) |
| opcache.validate_timestamps | 1 | 0 in production |
Disabling validate_timestamps in production removes a stat call on every script include. The trade-off is that you must explicitly clear OPcache on each deploy, which the deployment pipeline should be doing anyway.
Database query patterns that surface after the cache is healthy
Once Varnish and PHP-FPM are working correctly, the next source of TTFB is the database. Magento generates a lot of queries, and most of them are fine. The ones that hurt are the ones that show up in the slow query log and the ones that ORM-induce on uncached page types.
The first move is to instrument the slow query log with a low threshold, around 200 milliseconds, and audit a representative day of traffic. The usual culprits are queries against catalog_product_index_price, sales_order_grid, and any custom EAV attribute that lacks an index. The fixes are not exotic: add the missing index, rewrite the offending query, or move the expensive computation to a scheduled job that updates a cached projection.
The second move is to audit any custom module that has its own database access pattern. Modules that bypass the repository pattern and write SQL directly are common offenders. They also tend to skip Magento’s built-in query caching, which means they hit the database on every request even on pages that would otherwise be fast.
The third move is to look at MySQL configuration itself. Adobe Commerce performance is sensitive to innodb_buffer_pool_size, which should be sized to 60 to 70 percent of available RAM on a dedicated database host. Stores that run undersized buffer pools see TTFB spikes during periods of catalog or order volume because the working set does not fit in memory. The MySQL tuning primer is the reference point, though most of our work ends up in Percona’s variant of these tunables.
Synchronous external calls are the silent killer
The single most common cause of mysterious TTFB regression we have seen in the last 18 months is a synchronous external call. A custom module makes a call to a stock check API, a personalization service, or a pricing engine, and the call adds 200 to 500 milliseconds to every page load that triggers it.
The fix is to move external calls off the request path. Either cache the response aggressively, or compute the value asynchronously and store it in a fast local cache like Redis. For inventory specifically, the Adobe Commerce Inventory Management documentation explains the supported patterns for local stock caching. For personalization, the right pattern is usually edge-side decisioning rather than origin-side blocking calls.
Bemeir’s clients almost always have at least one synchronous external call in a custom module that nobody remembers writing. Finding it is a profiling exercise. Removing it is usually a one-day job with outsized impact on TTFB.
Putting it together
Sub-200ms TTFB on Adobe Commerce is achievable, even at scale, but it requires sequencing. Varnish hit ratio first. PHP-FPM and OPcache second. Database query hygiene third. Synchronous external calls fourth. Skip any of these and the next layer will not give you the headline gain you are looking for.
A reasonable tuning project against an Adobe Commerce store that has just finished a Hyvä migration takes two to four weeks of focused engineering effort. Spread over a couple of sprints, the work is not disruptive. The result, in stores we have shipped, is a TTFB that lands consistently between 120 and 180 milliseconds for cache hits and 350 to 500 milliseconds for cache misses on category and product pages.
If you are also evaluating performance across other platforms, the same sequencing discipline applies. Bemeir’s teams across Shopify Plus, Shopware, and BigCommerce use a similar layered approach, with the specifics of the cache layer and the database tier adjusted per platform. The unifying idea is to make TTFB an explicit metric the team owns, instrument every layer that contributes to it, and tune them in the order that surfaces the most leverage first.
The team that owns the Hyvä migration on your Adobe Commerce store should not consider the project finished when the storefront looks fast. The server tier is the second half of the work, and it is where the durable performance gains live. Most stores will see another 30 to 50 percent of TTFB reduction beyond the Hyvä win itself if they put two clean sprints into the patterns above.





