MVP Development Cost in 2026: What a First Version Really Costs
What an MVP costs in 2026: real ranges for SaaS, mobile, marketplace and store MVPs, what to cut from version one, and the foundations you should never skip.
Read articleHow to build a multi-tenant SaaS: shared tables or schema per tenant, row-level security, tenant-aware jobs and billing, from a codebase serving 17 projects.

Most decisions in a SaaS product can be changed next month. A button moves, a plan gets a new price, a report gets a new column. A few can't. Get them wrong and you are rewriting queries across the whole codebase with paying customers on top of it.
This article is about those few. They come from Turner 10, a system that started in 2016 for one housing scheme in Bahawalpur and now runs 17 projects from one codebase, each in its own workspace with its own users, accounts and settings. Nobody called it SaaS at the start. It became one, and it taught us which early choices matter.
If you are planning a multi-tenant SaaS, these are the seven to settle before the first sprint.
It sounds like a formality. It isn't.
In a CRM, a tenant is usually a company. In Turner 10 it's a project: a housing scheme, a sub-sector, a head office. One developer can own several projects. So "tenant" and "customer" are not necessarily the same thing.
Decide early:
Every table in your database will carry the answer, so it's worth an afternoon of argument now.
This is the decision people ask about most, and there are three honest answers.
| Approach | Good for | The catch |
|---|---|---|
Shared tables with a tenant_id column |
Most B2B SaaS. Cheapest to run, one migration updates everyone | Every query must filter by tenant. One missed filter is a data leak |
| A schema per tenant | Customers who want their data kept apart without paying for a server | Migrations run once per tenant, so you need tooling from day one |
| A database per tenant | Hospitals, finance, contracts that demand it | Highest running cost; onboarding and upgrades must be automated |
For most products we start with shared tables and enforce isolation in two places, which is the next decision. If a large customer later needs separate storage, a well-structured shared model can move that one customer to its own schema or database without rewriting the product. Going the other way, from a database per tenant back to shared tables, is much harder.
"Every query filters by tenant" is a promise developers make and code eventually breaks. A report written in a hurry, a background job, an admin endpoint: one of them will forget.
So isolation should be enforced in places that don't depend on every developer remembering:
In the data layer. Queries go through a repository or ORM layer that adds the tenant filter automatically, so a developer has to go out of their way to skip it.
In the database itself. PostgreSQL's row-level security can refuse to return another tenant's rows even if the application forgets to ask:
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON invoices
USING (tenant_id = current_setting('app.tenant_id')::uuid);
The application sets app.tenant_id at the start of each request, from the authenticated session, and the database does the rest. It's the safety net under the safety net.
Never in the browser. The tenant comes from the server-side session, not from a URL parameter or a field the client sends. If a user can change a number in the address bar and see another company's invoices, isolation was never real.
In Turner 10, access is re-checked on the server on every call, and a user only ever sees the modules their role allows in the project they're working in.
This is where good multi-tenant apps leak most quietly.
A web request has a logged-in user and a tenant. A background job usually doesn't. The nightly job that sends payment reminders, the import that processes an uploaded spreadsheet, the report emailed every Monday: each of them runs outside a request, and each one has to be told which tenant it belongs to.
The rule we follow: every job carries its tenant ID as part of its payload, sets the tenant context before it touches the database, and is tested with two tenants' data present at once. The bug you're looking for is the reminder that goes to the right customer list in the wrong company.
Two levels of permission get mixed up all the time.
The first is tenant isolation: company A never sees company B. That's architecture, and it should be impossible to get wrong.
The second is roles inside a tenant: in company A, the accountant sees the books, the sales officer sees the leads, the owner sees everything. That's configuration, and it changes as customers grow.
Keep them separate in the code. Turner 10 has thirteen modules in five groups, and each role opens only the modules it needs, re-checked on every request. Customers ask for new roles constantly. If roles are tangled with isolation, every new role is a security review. If they're separate, it's a settings change.
Billing looks like a feature you add before launch. It's really a data model decision.
And make payments idempotent from the first day. On OpenInterview.me, the Stripe flow records each payment exactly once, even if a customer double-clicks or Stripe delivers the same webhook twice, which Stripe says it may do. Retrofitting that after real money has been double-recorded is a miserable week.
Two questions that sound like later problems and aren't.
Data residency. A customer in the UK may need their data in a UK region. A hospital may need it on its own server. If your model can't place one tenant's data somewhere specific, you will lose those deals. You don't need to build it on day one, but you shouldn't build anything that makes it impossible.
Language and direction. If you'll ever sell in the Gulf or Pakistan, Arabic and Urdu mean right-to-left layouts, different fonts and different number formats. Turner 10 runs in English, Urdu and Arabic on every screen. Designed in from the start, that's a modest cost. Retrofitted, it touches nearly every component.
Less than people expect, if it's decided early. Our cost estimator puts a typical SaaS MVP at $12,500 to $20,500 over six to nine weeks, and multi-tenancy adds roughly 60 hours to a traditional build before the AI saving. The expensive version is the one where tenancy is bolted on after launch, because by then every query, job and report has been written without it.
We build with a team of AI agents and senior engineers, and this is exactly the split that makes sense: agents are fast at the repetitive part of multi-tenant code, the tenant filters on every repository, the tests that try to read across tenants, the migrations. The seven decisions above are the part a person has to own.
These decisions drive the budget, so read MVP development cost in 2026 next. If the same system needs a mobile app, Flutter vs React Native covers the choice, and custom ERP vs Odoo vs ERPNext explains when a multi-tenant ERP is worth building yourself.
What is multi-tenant SaaS architecture? A way of building one software product that serves many customers (tenants) from the same codebase and infrastructure, while keeping each customer's data, users and settings separate from everyone else's.
Is row-level security enough to isolate tenants? It's an excellent safety net, but don't make it the only layer. Enforce the tenant in your data access layer too, and always take the tenant from the server-side session.
Should I start single-tenant and switch later? Usually not. Moving from one database per customer to shared tables is harder than the other way round. Start shared, with strict isolation, unless a contract requires otherwise.
How long does it take to build a multi-tenant SaaS MVP? Typically six to nine weeks with AI-assisted delivery for a focused first version, with a working demo every week.
If you're planning a SaaS and want a second opinion on these decisions, get a free project plan. We'll tell you what we'd decide, and why, before you write a line of code.
Answer three quick questions and we'll send you a written plan with scope, team, timeline and estimate.
Monthly note
What worked on real client projects, what didn't, and the numbers behind it. Short enough to read over coffee.