← All posts

The checkout failures nobody reports

A checkout that loses an order does not usually throw an error. It succeeds, returns 200, and quietly writes the wrong thing. Two ways I have watched that happen.

The checkout problems that cost real money are almost never the ones in your error log. An exception gets noticed. Somebody sees a stack trace, files a ticket, and it gets fixed inside a week.

The expensive ones return 200.

A stalled dependency looks like a slow site

One shop had reports of a slow cart. Sometimes a timeout, sometimes a 503, sometimes a 524, nothing consistent enough to reproduce on demand. Nothing in any log.

The integration client that fetched live prices from the ERP had no timeout configured. Not a long one. None. It ran on library defaults, which mean wait forever, and the PHP pool above it was equally patient.

So when the ERP went quiet, a worker sat there holding the request until some proxy in front gave up and showed the customer an error page. The 503 at sixty seconds and the 524 at a hundred were two different proxies abandoning the same hung worker, not two separate faults.

The logs were empty because the client never timed out, so it never threw, so nothing was ever written. An empty error log was the symptom, not the reassurance everyone read it as.

The diagnostic that actually worked: only the queries touching the pricing backend hung. Everything else on the same page stayed under half a second. A sick server slows everything. A stalled dependency slows exactly the calls that use it.

Two writes to the same cart, one of them lost

The other kind is quieter still, because the customer sees nothing at all.

Magento does not write the column you changed. cartRepository->save() serialises the whole in-memory object into the UPDATE. So two requests that each load the cart, set one different field, and save produce a lost update. Whichever commits last writes back the value it read before the other one committed.

A front end firing two mutations in one Promise.all hits this perhaps one time in three. Both calls return success. The field is simply empty afterwards, and the order goes through with something missing that nobody notices until a human does.

It is also hard to reproduce, because the repository caches loaded quotes by id. Ask for the same cart twice in one process and you get the same object back, so both halves of your test mutate one instance and the bug politely disappears.

What to actually check

  • Every outbound client in the checkout path needs an explicit timeout, and a decision about what the page does when it fires. A dependency that can hang forever eventually will, usually during a sale.

  • Any two operations that write the same row need to be serialised, merged into one write, or locked. Different fields of the same row is not safe here.

  • Treat an empty error log as a question rather than an answer, particularly when the complaint is about speed.

None of this shows up in a conversion report as a bug. It shows up as a slightly worse number that everybody explains away.

© 2026 Gunnie · Magento & Adobe Commerce Expert