Average ecommerce conversion rate, by device and traffic source
The average ecommerce conversion rate for a shop is moved most by two things: the device people are browsing on, and where they came from.
Phones tend to be where people look and desktops where they buy, and a visitor arriving from your own email list usually converts better than one arriving from a cold ad. A store's blended rate is mostly a description of its mix of those. Two shops with identical products and pages can report very different numbers and both be doing fine. For the general question, see what is a good conversion rate; this page is about shops.
How it's measured
Conversion rate = orders ÷ sessions
Shop platforms and analytics tools each count sessions in their own way, and each misses sessions the other sees, so the rate in your store's dashboard and the rate in your analytics will not match. Neither is wrong. Pick one and use it consistently. The conversion rate formula page has the Google Sheets version.
Published benchmarks
Benchmarks for shops are published by analytics vendors, shop platforms and agencies, and the useful ones split by device. These are the published figures, with what each one counts.
| Context | Reported conversion rate | Source |
|---|---|---|
| All ecommerce, blended, worldwide | 2.68% | Statista, 2025 |
| Desktop | 3.4% | Contentsquare, Digital Experience Benchmark, 2026 |
| Mobile (70% of sessions in the same study) | 2.0% | Contentsquare, Digital Experience Benchmark, 2026 |
| Paid traffic, DTC brands, median | 2.01% (top 10% of brands above 4.7%) | Triple Whale, Ecommerce Benchmarks, 2025 |
| Paid traffic, desktop and mobile, same panel | 3.9% and 1.8% | Triple Whale, Ecommerce Benchmarks, 2025 |
Nobody with a large panel publishes a split by traffic source (email, organic search, paid social) that is worth quoting, so there is no row for it. Your own GA4 property has it: the session default channel group dimension against sessions and key events gives you the split for your shop, which is the number you wanted anyway.
Why benchmarks mislead
Device mix does most of the damage. As an illustration with made-up numbers, a shop gets 4,000 desktop sessions and 120 orders from them (3.00%), and 10,000 mobile sessions and 150 orders (1.50%). Its blended rate is 270 orders over 14,000 sessions, 1.93%. A shop with the same two device rates but half as much mobile traffic would report a higher blended figure without converting any single visitor better. Compare device with device.
The same arithmetic applies to channels. A shop that has built an email list looks better than one that buys its traffic, whatever the pages are like.
Price moves it too. A £15 phone case and an £800 sofa convert at different rates because the decisions are different sizes. Benchmarks rarely split by order value, so check the AOV formula alongside the rate before comparing yourself to anyone.
Tracking gaps push the measured rate up. Consent banners and blocked scripts remove sessions from the count while the orders still land, by a different amount on every site.
The stores in a benchmark are the ones trading long enough and large enough to be sampled.
Find your own baseline
Compute the rate per device and per source from your own data, with the segment in column A, sessions in column B and orders in column C:
=IF(SUMIF(A:A, "mobile", B:B)=0, "", SUMIF(A:A, "mobile", C:C) / SUMIF(A:A, "mobile", B:B))
Repeat for desktop and for each channel you care about. Then track each segment against its own figure over time. If mobile is converting at a third of desktop, the question is whether the mobile checkout is the problem or whether mobile traffic is simply earlier in the decision.
Keeping it current
A scheduled Fresh Sheets report can keep Google Analytics 4 sessions and key events by device category and channel group in a tab of its own, with your purchase key event standing in for orders, so the segmented baseline updates on its own.
Fresh Sheets replaces each tab's contents on every refresh, so keep your formulas on a separate tab. This version finds the sessions column by heading, so it still works if a field is added and the columns move:
=SUMIF(INDEX('GA4'!A:Z, 0, MATCH("Device category", 'GA4'!1:1, 0)), "mobile", INDEX('GA4'!A:Z, 0, MATCH("Sessions", 'GA4'!1:1, 0)))