Magento 2 Checkout Performance: Fixing the Slowest Page You Own
Checkout is the only page on your store where every millisecond has a directly attributable revenue number. A shopper who abandons a slow category page might come back. A shopper who abandons at the payment step with a full cart usually doesn't.
It's also the page Magento optimizes least. Checkout can't be full-page cached — it's entirely customer-specific by definition — so every one of the tricks that makes your catalog fast is unavailable here. What you get instead is a heavy JavaScript application booting from scratch, then making a series of sequential AJAX calls before the shopper can do anything.
This is the last post in a series covering site-wide performance, category pages, and product pages.
The Knockout problem, stated plainly
Magento's default Luma checkout is a Knockout.js single-page application. Loading it means: download the RequireJS dependency graph, resolve and execute dozens of modules, initialize the Knockout view models, then fetch the quote, the shipping methods, the payment methods, and the customer's address book — several of these sequentially rather than in parallel.
On a mid-range mobile device over a real network, that boot sequence commonly takes multiple seconds before the shipping form is usable. It's not one slow thing you can fix; it's the architecture.
You have three broad options, and it's worth being clear-eyed about the trade-offs rather than pretending optimization solves everything.
Optimize the Luma checkout in place. Realistic, and the right call for many stores. You can meaningfully reduce the boot cost — but you won't get to a fast checkout, you'll get to a tolerable one.
Replace it with a purpose-built checkout. Hyvä Checkout, or one of the several one-page checkout extensions, replaces the Knockout stack with something far lighter. This is the biggest available win and it's a licensing plus integration project, particularly if you have custom payment or shipping logic.
Rebuild it headless. Full control, correct answer for some businesses, a serious commitment for most. Don't take this path for performance reasons alone.
What to fix inside the Luma checkout
If you're staying on the default checkout, these are the levers that actually matter.
Cut the initial request chain
Open the Network panel on your checkout and look at the waterfall. You're looking for requests that happen in sequence when they could happen in parallel, and requests that happen at all when they don't need to.
The common finds:
- The estimate-shipping-methods call firing before the shopper has entered an address. Many themes trigger it on load using a default country, then again once the real address is entered. The first call is pure waste, and it's often the slowest request on the page.
- Payment methods loaded before the shipping step is complete. The shopper cannot see them yet. Defer.
- Multiple separate calls to
/rest/V1/carts/mine/...that could be batched.
Audit your shipping rate calculation
This is the most common single cause of a genuinely slow checkout, and it's usually not Magento's fault.
Every active shipping carrier is queried when rates are estimated. Real-time carriers (UPS, FedEx, DHL, and most rate-shopping extensions) make an outbound API call. If you have four live carriers and each takes 600ms, and they're queried sequentially, your shopper waits 2.4 seconds staring at a spinner — and if one carrier's API is having a bad day, the whole checkout stalls.
What to do:
- Set aggressive timeouts on every carrier. A 30-second default timeout means one degraded API can hang your entire checkout. Five seconds is usually generous.
- Cache rates where the carrier permits it. Rates for the same postcode and cart weight don't change minute to minute.
- Disable carriers you don't actually use. Test carriers left enabled from a migration are common.
- Monitor carrier response times as a first-class metric. This is exactly the kind of thing that degrades silently and gets blamed on "the site being slow."
Check your quote tables
quote, quote_item, and quote_address grow without bound by default. Every abandoned cart, every bot session, every guest who added an item and left. On a busy store these tables reach millions of rows, and checkout queries against them slow down accordingly.
Magento has cleanup for this, but it's frequently misconfigured or disabled. Check the quote lifetime setting, verify the cleanup cron is running, and if the tables are already enormous, plan a batched archival — deleting millions of rows in one statement will lock the table and take the store down, which is a memorable way to learn this lesson.
quote_address in particular is worth a look because it accumulates a row per shipping estimate, so it grows faster than the others.
Cart price rules
Every active cart price rule is evaluated on every quote recalculation — which happens on address changes, shipping method selection, coupon entry, and quantity updates. Rules with complex conditions across large catalogs are expensive, and stores accumulate expired-but-still-active rules over years.
Audit the active rule list. Deactivate anything past its end date rather than leaving it enabled with a date condition.
Third-party payment scripts
Payment providers ship JavaScript SDKs, and they vary enormously in weight. Some load the full SDK on checkout entry even though it's only needed once that method is selected.
Load payment SDKs on demand where the provider supports it. Where they don't, at least load them asynchronously so they aren't blocking checkout render. And measure them — a payment SDK adding 400ms to checkout load is worth raising with your provider or weighing when you renegotiate.
The form itself
Some of the biggest checkout wins aren't technical.
Guest checkout, enabled and obvious. Forcing account creation is consistently one of the largest abandonment drivers in checkout research. If you need accounts for B2B pricing, that's a segmented decision — not a blanket one.
Fewer fields. Every optional field you can remove is friction removed. Company name, second address line, and phone number are worth questioning individually.
Address autocomplete, implemented carefully. It reduces typing and errors, but a badly integrated autocomplete widget adds a third-party script and a layout shift. Reserve the dropdown space.
Correct autocomplete and inputmode attributes. Free, and materially faster on mobile — inputmode="numeric" on postcode and card fields brings up the right keyboard.
Don't validate on every keystroke. Aggressive per-character validation runs JavaScript on every input event and is a real INP contributor on a form with fifteen fields. Validate on blur.
Measure the funnel, not the page
Lighthouse on a checkout URL tells you very little — it can't populate a cart, and the empty-cart state isn't what shoppers experience.
Measure the real thing instead:
- Instrument the steps. Time from checkout load to shipping form interactive, time from address entry to rates displayed, time from payment selection to order placed. These are the numbers that map to abandonment.
- Log server-side timings on the REST endpoints checkout uses. A slow
estimate-shipping-methodsshows up here before customers report it. - Watch abandonment by step in analytics. A spike at the shipping step after a deploy is a performance regression until proven otherwise.
- Alert on it. Checkout is the one place where a performance regression is an incident, not a ticket. Treat it that way.
What we'd do first
On a slow Magento checkout, in this order:
- Network waterfall on a real device with a real cart. Find the longest bar.
- Shipping carrier timeouts and rate caching — this is the most common culprit and often the fastest fix.
- Quote table sizes and cleanup cron.
- Defer payment SDKs and remove the pre-address shipping estimate call.
- Cart price rule audit.
- Instrument the funnel so the next regression is caught in hours, not quarters.
Then, honestly, have the conversation about replacing the Knockout checkout. Steps 1–6 will get you real improvement, and there's a ceiling above them that only an architectural change clears. Knowing where that ceiling is — and what it's costing you in abandoned carts — is the difference between an informed decision and a recurring frustration.
Emyrix works on Magento and Adobe Commerce checkouts — performance, custom payment and shipping logic, and the emergency support for when checkout breaks at the worst possible moment. Get in touch.