Medusa v2 Marketplace in Production: A Case Study
The production stack behind a Medusa v2 marketplace with 10,000 products and 50 vendors: the architecture, what it actually costs on Railway and Cloudflare R2, and the two pitfalls that cost the most time — the WooCommerce migration and worker mode.
Medusa v2 is an open-source commerce framework in TypeScript, built around Modules and Workflows, and it is the core of a marketplace I run in production: 10,000 products, 50 vendors, everything self-hosted. This article is the case study I looked for before building and never found: the actual stack, the monthly bill calculated against today's price lists, and the two pitfalls that consumed more time than everything else combined.
Every price and version below was checked against the primary sources on August 27, 2026. Where a number is my own production experience rather than a price list, I say so explicitly, because the two get mixed up in most cost articles, and the mix is exactly what makes them useless.
Why Medusa v2 and not Shopify or Sharetribe?
Because a marketplace lives or dies on logic no SaaS platform lets you own: commission models, vendor onboarding rules, order splitting, payout rhythms. On Medusa that logic is TypeScript in my repository; on a hosted platform it is a feature request. That was the decision in one sentence; the longer version has two halves.
Shopify is the better choice for a standard single-vendor catalog, and I say that as someone whose business is building the alternative; my Medusa vs Shopify cost breakdown draws that line in numbers. Sharetribe is the faster start for validating a marketplace idea before writing code, and Mirakl plays in a different, enterprise league; the marketplace platform comparison covers all three across GMV scales. Medusa wins when the marketplace is the product: when the commission math and vendor rules are the moat, and when platform fees on growing GMV read like a tax on your own success.
What does the production stack look like?
Six services, one picture: a Next.js storefront talks to a Medusa v2 backend running in two processes — server and worker — with PostgreSQL and Redis behind them, product images in Cloudflare R2, and Stripe handling payments. The marketplace layer on top of Medusa is Mercur (MIT license, 1,738 GitHub stars as of the check date), which contributes the vendor panel, order splitting, commissions, and payouts.
| Layer | Tool | Version / plan | Why |
|---|---|---|---|
| Commerce core | Medusa | v2.19.0 (Aug 13, 2026) | Modules + Workflows, TypeScript, MIT core |
| Marketplace layer | Mercur | current main, MIT | vendor accounts, splitting, commissions, payouts |
| Storefront | Next.js | App Router | React ecosystem, static + dynamic mix |
| Database | PostgreSQL | Railway service | Medusa's primary store |
| Cache / queues | Redis | Railway service | cache, event bus, workflow engine, locking |
| Images | Cloudflare R2 | Standard storage | S3-compatible, zero egress fees |
| Payments | Stripe | — | split payments for vendor payouts |
| Hosting | Railway | Hobby → usage-based | one platform for all backend services |
The deployment shape follows Medusa's own production guide: two instances of the same application, one with MEDUSA_WORKER_MODE=server handling requests, one with MEDUSA_WORKER_MODE=worker processing background jobs, and the docs are explicit that your host "must offer at least 2GB of RAM". Redis is not optional decoration here. In production it backs four separate Medusa modules: caching, the event bus, the workflow engine, and locking.
Where does the storefront live? Medusa's docs endorse the split explicitly: deploy the Next.js storefront to a frontend host such as Vercel while keeping the Medusa server on a host that runs long-lived Node.js processes, because the backend is a server, not a serverless function. Worth knowing if you follow that advice: Vercel's Hobby plan is restricted to non-commercial use, so a commercial storefront starts at the $20 Pro plan there. I keep everything on one platform instead. Fewer dashboards, one bill, and with per-second billing the storefront is a rounding error next to the backend. The full Railway-versus-Vercel-versus-VPS trade-off deserves its own article: the deployment comparison walks all three paths with verified pricing.
Two operational facts from my side of the fence, clearly labeled as experience: individual services build in two to three minutes on Railway and deploy in parallel, and the stack has run without a single infrastructure incident since launch. Railway also ships an MCP server, which means my AI coding setup can inspect and manage the infrastructure directly; I describe that workflow in the Medusa and AI agents guide.
What does a deploy actually look like, mechanically? npx medusa build produces a standalone bundle in .medusa/server that, per the build docs, does not rely on the source TypeScript files and can be copied to a production server reliably. The general deployment guide then has database migrations run through a predeploy script executing medusa db:migrate before the production start, and gives you a health endpoint at /health plus the admin at /app for the smoke test. On Railway that whole sequence is a git push: both Medusa services rebuild from the same commit, run their migrations once, and roll over.
The two-to-three-minute builds matter here more than they sound. A deploy you can run ten times a day without ceremony changes how small your changes get, and small changes are how a two-person-scale operation ships a marketplace without incidents.
What does a self-hosted marketplace really cost?
My real total first, because it is the number everyone asks for: the complete backend — Medusa server, worker, PostgreSQL, Redis, all on Railway — costs $40–60 a month, and the roughly 6 GB of product images in R2 cost under a dollar. That is the bill Railway actually charges for 10,000 products and 50 vendors.
Now the projection part, done honestly. Railway bills resources per second of actual consumption, so the way to estimate is to convert its current rates (checked Aug 27, 2026) to monthly figures: memory at $0.00000386 per GB-second works out to about $10.14 per GB held for a full month, vCPU at $0.00000772 per second to about $20.29 per fully-used core-month, egress at $0.05 per GB. The Hobby plan costs $5 a month and includes $5 of usage. Cloudflare R2 charges $0.015 per GB-month with free egress, and its free tier (10 GB of storage, one million writes, ten million reads monthly) covers a surprising amount of catalog imagery.
| Scenario | Assumptions | Calculated monthly cost |
|---|---|---|
| Small shop | server+worker averaging 1 GB RAM combined, shared fractional vCPU, 1 GB Postgres, small Redis, images within R2 free tier | ≈ $15–25 |
| My marketplace (10k products, 50 vendors) | 2–3 GB RAM across four services, moderate CPU, ~6 GB images in R2 | $40–60 (actual bill) + under $1 R2 |
| Larger marketplace | 6–8 GB RAM, sustained CPU on workers, 50 GB images, meaningful egress | ≈ $120–200 |
Read the table as what it is: the middle row is a real invoice, the other two are arithmetic from the rate card with the assumptions stated. Your CPU profile will differ, and Railway's per-second billing means idle time is cheap. That is precisely why a marketplace backend, mostly waiting for requests, costs less than the provisioned-server mental model suggests.
Two details the table hides. First, R2 operations: the initial import of a 10,000-product catalog writes every image once, and even at several images per product that stays in the tens of thousands of Class A operations against a free allowance of one million per month — the storage side of my migration cost exactly nothing. Second, egress: R2's zero egress fee is structural, not promotional. Image traffic is the one cost line that scales with marketing success rather than catalog size, and on providers that bill egress per gigabyte it becomes the classic surprise item. R2 charges nothing for it.
The line item that dwarfs all of this is development. Infrastructure at $60 a month is noise against engineering time, and that ratio is the honest core of every build-vs-SaaS calculation I have published. If you want to test your own case against real numbers before committing months, a two-week PoC Sprint with your actual vendor model is the cheapest way I know to find out.
Which two Medusa v2 pitfalls cost the most time?
The two expensive lessons had nothing to do with framework bugs. Both were boundary problems — the data migration into Medusa and the production process model — and both are predictable enough that you can budget for them, which is the point of this section.
Pitfall one: migrating out of WordPress. My marketplace did not start on Medusa; it started on WordPress, and moving a living catalog out of it was the single largest work package of the whole project. The structural mismatch is the trap: WooCommerce stores products as posts with metadata, loosely typed and forgiving, while Medusa wants a structured model of products, variants, options, and prices.
A marketplace migration adds a dimension WordPress never had on top, because every one of those 10,000 products needed an owner among the 50 vendors. The vendor attribution alone justified its own mapping table, and the variant remodeling forced decisions WooCommerce had let us postpone for years: which attribute combinations are real purchasable variants, and which were just description text wearing a dropdown costume. Images had to leave the WordPress media library for R2.
What worked was treating it as a staged pipeline rather than a weekend script:
- Export the catalog and customers from WooCommerce.
- Remodel products, variants, and vendor ownership for Medusa's structure.
- Import in batches, images going straight to R2.
- Run a parallel phase with test orders before switching traffic.
None of this is exotic engineering, but it is a project with its own timeline rather than an import button. It is the main reason my honest answer to "how long to production?" is a range: a few weeks in the best case, months when integrations and data work pile up.
Pitfall two: worker mode is not optional. Medusa's deployment documentation describes a split the community learns the hard way: run one instance with MEDUSA_WORKER_MODE=server, a second with MEDUSA_WORKER_MODE=worker and DISABLE_MEDUSA_ADMIN=true, and give Redis to the caching, event bus, workflow engine, and locking modules. A single instance appears to work in development and then degrades in production, because background jobs (image processing, event subscribers, scheduled workflows) compete with customer requests for the same process. On Railway the split is simply two services from the same repository with different environment variables; the docs' 2 GB RAM floor is real, and budgeting it per instance from day one is cheaper than discovering it under load.
How much does the AI workflow actually help?
Enough that I count it as part of the stack, and I will not dress that up with productivity percentages, because I did not run a controlled experiment while shipping a marketplace. What I can report is the shape of the work. Two MCP servers sit in my coding environment: Railway's, which lets the agent inspect services, deployments, and logs directly instead of me narrating them, and GitHub's for the repository side. Medusa meets the agent halfway from the other direction with its official MCP server and installable agent skills, which is unusual among commerce frameworks and the reason its AI tooling gets its own article on this blog.
The unglamorous win is documentation: generating and maintaining internal docs for a six-service stack went from a chore I postponed to something that happens as a side effect of the work. The full walkthrough of the Claude Code workflow behind this is now its own article; the honest preview is that infrastructure-aware agents changed my daily speed more than code completion ever did.
What would I do differently, and when is Medusa the wrong choice?
Three changes, if I were starting today. I would run the server/worker split from the first deploy instead of treating it as a production detail. I would budget the WordPress migration as a separate project phase with a deadline attached, because "we'll import the data along the way" is how weeks disappear. And I would wire the AI tooling earlier: the Railway MCP server plus Medusa's agent skills changed my daily development speed enough that I now consider them part of the stack.
And the honesty paragraph this blog owes every reader: Medusa is the wrong choice when your catalog and checkout are standard and no developer capacity exists. In that case a SaaS platform is cheaper in every scenario I have calculated, and the when-Shopify-wins section of my comparison exists precisely because pretending otherwise would sell you a maintenance burden. Medusa earns its keep when custom logic is the product, and a marketplace with its own commission model is the textbook case. A production-readiness checklist distilled from this build is in the works as a downloadable companion; until then, the marketplace how-to covers the operational side, and my independent Mercur review weighs the platform's maturity honestly.
If you are standing where I stood, deciding whether to own the stack or rent it, book a call and bring your vendor model; thirty minutes against real numbers beats another week of tab hoarding. The full series lives on the e-commerce topic page, the German version of this case study here, and the wider platform landscape in the open source ecommerce field guide.

AI Agent & RAG Developer
AI Agent & RAG Developer with 10+ years of software engineering experience. Specialized in intelligent AI solutions for enterprises in the DACH & Nordic region.
More about me