Migrating from Shopify or Magento to Solidus: The Five Year Total Cost of Ownership

The email usually arrives in the second week of January, after someone has done the year end numbers. It says something like: we paid more to Shopify and the apps last year than we paid our best employee, and we still cannot change the checkout. Or, from the Magento side: the agency wants sixty thousand for the upgrade to the next version and we are not sure what we get for it beyond staying alive. Both emails end the same way. Would it actually be cheaper to have our own shop, and what would moving involve? I wrote a general comparison of the platforms a couple of weeks ago. This is the spoke that hangs off it: the money, worked through properly over five years, and then the migration itself, step by step, including the parts that the migration guides written by platform vendors leave out because they make the vendor look bad.

The January email

The email usually arrives in the second week of January, after someone has done the year end numbers. It says something like: we paid more to Shopify and the apps last year than we paid our best employee, and we still cannot change the checkout. Or, from the Magento side: the agency wants sixty thousand for the upgrade to the next version and we are not sure what we get for it beyond staying alive.

Both emails end the same way. Would it actually be cheaper to have our own shop, and what would moving involve?

I wrote a general comparison of the platforms a couple of weeks ago. This is the spoke that hangs off it: the money, worked through properly over five years, and then the migration itself, step by step, including the parts that the migration guides written by platform vendors leave out because they make the vendor look bad.

I will use one fictional but typical shop for the whole article so the numbers stay comparable. Call it the garden shop. It sells tools, seeds and furniture, does about two million euros a year, has around three thousand SKUs with variants, ships to Germany, Austria and the Netherlands, and has a small team of six. It has been on its current platform for four years. Every number below is rounded and drawn from real projects that looked a lot like this one, and your shop will differ. Use the shape, not the decimals.

Why "what does it cost per month" is the wrong question

Platform vendors price in months because a small monthly number is easy to say yes to. Shopify Advanced is a few hundred a month. Magento Open Source is free. Both statements are true and both are close to meaningless, because the platform fee is the smallest line on the bill.

The bill has five parts, and only the first is on the pricing page.

The platform itself: plan fee, or licence for Adobe Commerce, or nothing for Magento Open Source and Solidus.

The things you bolt on: apps, plugins, extensions, themes, and the licences some of them carry.

The people: agency retainers, freelancers, the hours your own staff spend fighting the platform instead of selling.

The percentages: transaction fees, payment surcharges, the revenue share that some plans quietly take.

The forced spend: version upgrades, end of life migrations, the app that gets acquired and triples its price, the rebuild you did not plan.

Add those up over five years, which is a realistic life for a shop platform before the next big decision, and the comparison looks nothing like the pricing page. So that is what we are going to do.

The garden shop on Shopify: five years

Let me start with Shopify because it is the one where the numbers surprise people most.

Plan. The garden shop needs Advanced for the reporting and the lower external payment fee. Around four hundred euros a month once you convert. Twenty four thousand over five years. If they move to Plus, which they will be tempted to do the moment they want a proper B2B price list or a custom checkout, add roughly two thousand three hundred a month on top. That alone is a hundred and forty thousand over five years, and I will come back to it.

Apps. I audited a shop almost exactly like this one last spring. Twenty one apps. Reviews, a bundle builder, German legal texts, cookie consent with consent mode, invoicing that the tax adviser would accept, back in stock alerts, a search and filter app because the built in one could not handle three thousand SKUs with attributes, a translation app, a loyalty scheme, an upsell widget, a returns portal, a form builder, a size guide, a shipping rate calculator for the three countries, and a handful of small ones nobody remembered installing. Total: eight hundred and ninety euros a month. Fifty three thousand over five years, and that assumes none of them raise prices, which every one of them does.

Theme and agency. A decent theme, customised, with the seasonal changes a garden shop needs, costs the garden shop about fifteen thousand in year one and eight to ten thousand a year after that in agency time. Call it fifty thousand over five years.

Percentages. Here is the one nobody sees coming. The garden shop wants Kauf auf Rechnung through a German provider, because a quarter of its customers ask for it, and it negotiated a good rate with a local acquirer for cards. Using an external payment provider on Advanced means Shopify charges an additional 0.6 percent on every order. On two million a year that is twelve thousand euros a year, sixty thousand over five years, for the privilege of not using Shopify's own payments. Many shops give up and use Shopify Payments, which then means the invoice product they wanted comes through Klarna at Klarna's rate instead.

Forced spend. Shopify does not have version upgrades in the Magento sense, which is a genuine advantage. What it has instead is app churn. Over five years the garden shop will replace, on average, one app a year because it was discontinued, acquired, or broke after a platform change. Each replacement is a small project. Ten thousand over five years is generous.

Total, standard Shopify: around two hundred and forty thousand euros over five years. With Plus, three hundred and eighty thousand. And at the end of it the garden shop owns a CSV export.

The garden shop on Magento Open Source: five years

Magento is free, and a Magento shop is the most expensive thing on this list to keep alive.

Platform. Nothing, if you stay on Open Source. If you are on Adobe Commerce the licence for a shop this size starts around twenty five thousand a year and goes up with revenue. I will assume Open Source, because that is what most DACH SMEs on Magento actually run.

Hosting. A Magento 2 store with three thousand SKUs and a few hundred orders a day needs a real server, or two, with OpenSearch, Redis and a page cache in front. Managed Magento hosting for this size runs four to six hundred a month. Thirty thousand over five years.

Extensions and theme. The garden shop has a Hyvä theme, because the default one was unusably slow, and about fifteen paid extensions: a German legal pack, a one page checkout, layered navigation, an ERP connector, an invoice module, a few payment modules, a blog, an SEO suite. Licences and renewals come to roughly three hundred a month. Eighteen thousand over five years, plus the theme licence.

Agency. This is the big one. Magento agencies charge Magento rates. The garden shop is on a retainer of twenty hours a month at a hundred and thirty an hour, so about thirty one thousand a year, which covers security patches, the quarterly upgrades, extension conflicts after every upgrade, and a small amount of actual improvement. A hundred and fifty five thousand over five years.

Forced spend. Magento 2 gets a major release roughly every couple of years and each one breaks a handful of extensions and the theme. Budget one proper upgrade project of twenty to thirty thousand in the five years, on top of the retainer. And there is the shadow of a bigger one: if Adobe's direction of travel continues, the garden shop may find that Open Source becomes a community fork with a smaller ecosystem, and that is a rebuild conversation.

Total, Magento Open Source: around two hundred and forty thousand euros over five years. Almost identical to Shopify, oddly, but with much more of it going to people rather than to a vendor, and with a far higher variance, because a bad upgrade year can double the agency line.

The garden shop on Solidus: five years

Now the version where the money looks different, and I will try to be as honest about it as I was about the others.

Build. This is the number that stops people. A Solidus shop for the garden shop, built properly with a real design, tests, the three country payment mix, invoicing, the legal texts, an ERP connection, migration of the data and the redirects, is sixty to eighty thousand euros. Say seventy. It is a one off, it is paid once, and the shop it produces is yours.

Hosting. A Solidus shop of this size runs comfortably on a single virtual server with PostgreSQL, deployed with Kamal, for sixty to a hundred euros a month including backups and monitoring. Six thousand over five years. That is not a typo. It is what happens when there is no Elasticsearch cluster and no page cache layer to keep a slow frontend alive.

Extensions. The official Solidus extensions are open source and free. The ones the garden shop needs, Stripe or Braintree, internationalisation, a few promotion rules, cost nothing. Anything else is built into the shop as part of the build number above.

Maintenance. This is the honest ongoing line. Rails and Solidus upgrades, dependency updates, security scanning, the occasional small improvement. For a well tested shop this is eight to twelve thousand a year, and it tends to go down after year two because the shop stops changing. Fifty thousand over five years.

Percentages. None. Use whichever payment provider you like, negotiate whatever rate you can, no platform takes a cut.

Forced spend. There has never been a Solidus rebuild release. Rails major upgrades happen every couple of years and on a tested codebase they are days, not projects. I budget nothing here and have never had to spend it.

Total, Solidus: around a hundred and twenty six thousand euros over five years. And the shape matters more than the total. Seventy of it is in the first six months. After that the garden shop spends about ten thousand a year, and it is spending it on its own software.

Putting the three side by side

Five year totals for the garden shop, rounded:

Shopify standard: two hundred and forty thousand. Shopify Plus: three hundred and eighty thousand. Magento Open Source: two hundred and forty thousand. Solidus: a hundred and twenty six thousand.

Year one alone looks the opposite. Shopify: fifty thousand. Magento, if you already have it: fifty thousand. Solidus: eighty thousand. That is why people stay where they are. The pain of year one on Solidus is real and the savings only show up from year two.

Break even for the garden shop is somewhere in the second year against Shopify standard and Magento, and inside the first year against Shopify Plus. From there the gap widens by fifty to seventy thousand a year.

And there is the number that is not on any of the lists, which I wrote about in the comparison piece: the cost of the things you cannot do. The garden shop wanted a trade price list for landscape gardeners, a delivery slot picker for furniture, and a bundle builder for seed collections. On Shopify the first needed Plus, the second needed an app that did not quite work, and the third was a compromise. On Solidus all three are features in the build. I have not priced those into the comparison because they are impossible to price fairly, but they are usually why the January email gets sent in the first place.

When you should not migrate

I want to put this before the how, because I would rather lose a project than do one that should not happen.

Do not migrate if your shop is under half a million a year and your requirements are conventional. The Solidus build is a fixed cost and it does not shrink much with revenue. At that size Shopify is the right answer and the rent is tolerable.

Do not migrate if your current platform is working and the only complaint is the bill. Migrations carry risk. If the thing that hurts is the money and you can live with it, the honest advice is to keep going and revisit when a real capability wall appears.

Do not migrate in the two months before your peak season. For the garden shop that means nothing goes live between February and May. Cut over in your quietest quarter.

Do not migrate if you cannot name the person on your side who owns the data. Not the agency, not me. Someone in your business who knows what a variant is, why the old SKUs have suffixes, and which customers are trade. Without that person the migration produces a beautiful shop full of wrong data.

If none of those apply, here is what it actually involves.

What migrates, what does not, and what has to be rebuilt

The single most useful thing I can give you is this list, because it is the list vendors do not publish.

Migrates cleanly, with mapping work. Products, variants, prices, images, categories, stock levels, shipping zones and rates, tax rules, static content. This is most of the effort but none of the risk. It is a mapping exercise between two data models and a lot of checking.

Migrates partially. Order history. You can bring across orders as records, with line items, totals, addresses and status, so customer service can look things up and customers can see their history. What you cannot bring across is the ability to act on an old order in the new system: refunds, reorders, returns on pre migration orders usually have to be handled from the old platform or manually. Plan for it. Reviews, if your review app allows export, which not all do. Discount codes, which are worth recreating by hand rather than importing because half of them are dead anyway.

Does not migrate, ever. Customer passwords. Shopify, Magento and every other serious platform store passwords as one way hashes, and rightly so, and they will not give you the hashes even if they could. Payment tokens, meaning saved cards and the subscription mandates attached to them. These belong to the payment provider and the platform, and moving them requires a provider level token migration that is possible with Stripe, Braintree and Adyen but must be planned months ahead and is impossible with Shopify Payments because it is not portable at all. Apps and their data, unless the app has an export. Your theme.

Has to be rebuilt. The storefront, in full. Every integration: ERP, warehouse, email marketing, accounting, marketplaces. Every custom feature that lived in an app. The checkout, which on Solidus you will finally own.

If your migration plan does not have three columns matching those headings, it is not a plan yet.

The customer account problem, and how to turn it into a campaign

Because passwords cannot move, every customer will have to set a new one. Owners hear this and panic. It is actually a gift if you treat it as one.

The bad version: you migrate, customers try to log in, it fails, they hit "forgot password", half of them give up, your support inbox fills, and your first month on the new shop looks like a disaster in the numbers.

The good version: two weeks before cutover you email every active customer, in the tone of a launch, with the news that the new shop is coming and what is better about it. On cutover day the new shop has every customer account pre created with their email, their addresses and their order history, and a flag that says "password not yet set". The first time they try to log in, or click the link in the launch email, they land on a page that says welcome to the new shop, set your password, here is a voucher for the inconvenience. The voucher costs you five euros a customer. The re engagement it produces is worth ten times that, and you get a clean consent record for every customer who comes through it, which in the DACH market is something you should want anyway.

I have run this on three migrations. The shops that treated it as a campaign saw login rates recover in about two weeks. The one that did not took three months.

Order history: bring it, but decide how far back

Bring five years, not fifteen. Old orders have old addresses, old prices, old products that no longer exist, and each one has to be mapped to something in the new catalogue or to a placeholder. The mapping work is linear in the number of orders. Customer service almost never needs an order older than the returns window plus the warranty period, which for the garden shop is two years. I usually bring three years into the new shop as read only history and archive the rest as a database export that the old platform's admin can still open for a while.

One thing that does matter: order numbers. Your accounting, your invoices and your customers all reference them. The new shop must never reuse a number the old shop issued. Start the new sequence above the highest old number with a visible gap, and tell your tax adviser you did.

The URL map, which is where migrations lose money

This is the part I am most insistent about, because it is the part that decides whether the migration costs you organic traffic.

Every product, category, content page and blog post on the old shop has a URL. Some of those URLs have years of links and rankings behind them. The new shop will have different URLs unless you go out of your way to preserve them, and even where you preserve them the platform's conventions differ. Shopify has /products/ and /collections/. Magento has whatever the SEO extension decided, often with .html on the end. Solidus will have whatever you tell it to have.

The deliverable is a spreadsheet, and it has an owner. Column one, every old URL that has ever received a visit or a link in the last twelve months, which you get from Search Console and your analytics. Column two, the new URL it maps to. Column three, the type of redirect, which is 301 in almost every case. Column four, a checkbox for tested.

Garden shop scale, that is about four thousand rows. It takes someone two to three days to build properly and it is the best three days in the whole project. Every row that is missing is a page that will 404 after cutover, and Google notices within days.

The redirects live in the new shop, not in a DNS service or a proxy, because they need to survive every future deploy. I build them as a table in the database with an admin screen, so the garden shop's own staff can add one when they spot a stray in Search Console after launch.

Payment tokens and subscriptions

If the garden shop has customers with saved cards, or a subscription product, this is the item that has to start earliest.

With Stripe, Braintree or Adyen, saved payment methods can be migrated between accounts through the provider, and in the best case the new Solidus shop connects to the same provider account and simply keeps using the same tokens. That is the goal: same provider account, new platform, no token migration at all. It works if the old platform let you use your own provider account, which Magento does and Shopify only does with penalties.

With Shopify Payments, tokens are not portable. Full stop. Customers with saved cards will have to re enter them, and subscriptions running through a Shopify subscription app will have to be recreated with fresh mandates. That is a customer contact exercise with a deadline, and it needs to start six weeks before cutover so that every subscriber has been asked twice.

I wrote a whole piece on the hidden dangers of switching payment gateways after a project where this went wrong, and I recommend reading it before you decide the payment side is a detail.

The parallel run and the freeze

For the last three to four weeks before cutover, both shops exist. The old one is live and taking orders. The new one is complete, on a staging domain, being tested by your team with real products and test payments.

During those weeks you freeze the catalogue. No new products, no price changes, no category restructures on the old shop, because every change has to be replicated by hand on the new one and the risk of drift goes up with each. Owners hate this. Marketing hates it more. Do it anyway, and schedule the migration so that the freeze does not collide with a launch.

Orders and customers are the exception. They keep flowing into the old shop until the last moment, and the final data migration, on cutover morning, brings across the delta: everything that changed since the last full import. That delta import is rehearsed at least twice on staging before the real day, timed, and documented step by step, so that on the day it is boring.

Cutover day

Pick a Tuesday or Wednesday morning in your quietest month. Never a Friday, never before a bank holiday, never during a campaign.

The sequence I use. Six in the morning, put the old shop into maintenance mode with a friendly message. Run the delta import. Verify order counts, customer counts, stock levels against the old shop's admin. Switch the domain to the new shop. Run the smoke test: a real order with a real card for one euro, in each country, with each payment method, then refund it. Check the top fifty URLs from the redirect map by hand. Check Search Console for crawl errors within the hour. Lift maintenance mode. Send the launch email.

By ten in the morning you are either live or you have rolled back, and rolling back means pointing the domain at the old shop again, which is why the old shop stays exactly as it was, untouched, for thirty days after cutover. Not a day less. Do not cancel the Shopify plan on cutover day, however good it feels. Cancel it a month later, after you have exported everything one final time and confirmed the new shop's first month end closed cleanly.

A realistic timeline for the garden shop

Weeks one to two: discovery, the three column list, the URL map begins, the data owner is named, the payment provider question is answered.

Weeks three to ten: the build. Storefront, checkout, payments, integrations, the admin features the team needs. Catalogue migration scripts written and run repeatedly against a copy of the old data until they are clean. Every feature has a test, which is how I know the delta import on cutover day will work. I wrote about how that testing looks in practice in my Cucumber piece.

Weeks eleven to thirteen: parallel run. Team testing on staging, freeze on the old shop, customer emails go out, subscription mandates collected, two full rehearsals of cutover.

Week fourteen: cutover, then two weeks of watching Search Console and the support inbox like a hawk.

Fourteen weeks, of which the garden shop's own team is heavily involved for about five. Cost inside the seventy thousand build number. And this is worth stating plainly: the migration, including the build, costs less than one year of what the garden shop was paying on Shopify Plus, and less than eighteen months of what it paid on standard Shopify or on Magento.

The mistakes, in the order I see them

No URL map, or a URL map done by the agency without anyone from the shop checking it. Result: a traffic dip that looks like the new shop is worse, when actually it is four hundred 404s.

No customer plan. The password problem discovered on cutover day. Support meltdown.

No freeze, or a freeze that marketing quietly ignored. Products on the new shop with last month's prices.

Cancelling the old platform too early, and discovering that the one export nobody ran was the one with the reviews in it.

Treating payment tokens as a technical detail for the last week.

Migrating fifteen years of orders because "we might need them", and spending three weeks mapping products that were discontinued in 2014.

Letting the migration become a redesign. It is tempting to change everything at once. Do not. Migrate the shop as it is, with the same structure and roughly the same look, cut over, stabilise, then improve. A migration and a redesign together doubles the risk and makes it impossible to tell which one caused the dip.

And the one that costs the most: nobody on the owner's side who understands the data. Every migration I have seen go badly had that in common.

What the garden shop looks like in year three

Two years after cutover, the garden shop is spending about ten thousand a year on its platform, all of it with a developer who knows the codebase and documents it. It has the trade price list, the delivery slots and the bundle builder, because those were features rather than apps. It pays no percentage to anyone. Its hosting bill is less than one of the apps it used to run. When the owner wants a change, it takes days and the change is tested. When Rails releases a new version, it is a morning.

That is not a sales pitch, it is just what owning the shop looks like once the first year is behind you. Whether it is worth the first year is your call, and I am happy to run your numbers rather than my garden shop's. Sometimes the answer is stay where you are. When it is not, at least now you know what the move actually involves.

If you want your own numbers run through this model, send me your plan tier, your app list and your last twelve months of agency invoices and I will tell you what a Solidus build would cost against it and whether the migration is worth doing at all. Sometimes it is not, and I will say so.

1%of every invoice goes to a UK charity you pick.

A donation, never sponsorship. You choose the cause at onboarding.

The story behind the pledge →

Stay ahead of your competition.

The latest innovative products and services, straight to your inbox before your competitors hear about them.

Get up to 5% off your first six months: 1% per topic you pick, the full 5% when you take everything. Limited offer · ends 31 December 2026.

New clients only. Terms apply.

* Up to 5% off your first six monthly invoices, new clients only. Full terms.

Questions about pricing, contracts or how we work together?

Read the FAQ