Spar Tech Labs Logo
Spar Tech Labs
Engineering Guide

SaaS architecture: MVP to scale (without a rewrite)

Most SaaS rewrites happen for boring reasons: no boundaries, auth bolted on late, messy data ownership, and “we’ll fix ops later.” This practical checklist gives you a simple path: ship fast now, keep the foundations clean, and scale calmly later.

Who it’s for
  • Founders shipping an MVP that should scale
  • Teams rebuilding a fragile dashboard
  • Products adding billing & permissions
What you’ll have
  • A clean app shape to avoid future rewrites
  • Sane multi-tenant and RBAC baselines
  • A deployable system with monitoring hooks
Typical timeline

MVP foundations in ~1–2 weeks. MVP features in ~3–6 weeks, production hardening in ~6–12 weeks (scope dependent).

Step 1: Pick a “boring” baseline stack

Your MVP is not the time to invent infrastructure. Choose tools with predictable ops: Postgres, a job queue, and a straightforward API layer.

A practical baseline
DB: PostgreSQL
API: Next.js route handlers or small Node API
Auth: Managed (Auth0/Clerk) or NextAuth
Jobs: BullMQ or Cloud Tasks
File storage: S3-compatible + signed URLs

Step 2: Define boundaries (even in one repo)

“Boundaries” doesn’t mean microservices. It means your business logic shouldn’t be scattered across React components and random API handlers. Keep a clean home for domain logic.

Example folder shape (monorepo-style)
src/
  app/                 # Next.js routes + pages
  components/          # UI components
  lib/                 # shared helpers
  domain/              # your business rules (pure-ish logic)
    billing/
    orgs/
    users/
  server/              # DB, queues, integrations
    db/
    jobs/
    integrations/

The “domain” folder is the trick. It becomes the stable center of your app.

Step 3: Decide your tenant model early

Multi-tenancy touches everything: queries, permissions, billing, and even analytics. Pick one model now.

Shared schema (most common)

Every table includes tenant_id. Easiest to operate. Requires discipline in queries.

DB per tenant (heavier ops)

Stronger isolation. Harder migrations. Usually only worth it for strict enterprise cases.

Practical rule (shared schema model)
Every tenant-owned table gets:
- tenant_id (indexed)
- created_at, updated_at
- created_by_user_id (optional)

And every query must filter by tenant_id.
If you forget tenant_id filters even once, you create data-leak risk and expensive future refactors.

Step 4: Put RBAC in place early

The easiest RBAC is: org → membership → role. Keep it small and expand later.

Minimal RBAC model
orgs
  id, name

users
  id, email

memberships
  id, org_id, user_id
  role # 'owner' | 'admin' | 'member'
Practical tip

Don’t scatter permission checks in UI components. Make your API reject unauthorized actions. The UI can hide buttons, but the API must enforce rules.

Step 5: Make migrations a first-class habit

If you skip migrations early, you’ll fear schema changes later. Every PR that changes schema must include a migration. Keep seed data separate, and test migrations on a fresh DB.

Step 6: Separate request work from background work

Your API should stay fast and predictable. Anything that can take seconds (PDF processing, emails, large exports) belongs in background jobs. The API enqueues the job and returns an ID; the worker does the heavy lifting.

Step 7: Add “basic observability”

You don’t need a fancy platform. You need the basics to ensure production remains calm.

  • Error tracking (server + client)
  • Request latency (p50/p95)
  • Job failures and retries
  • Auth events (logins, invites)
  • Billing events (subscription changes, failed payments)

Step 8: Security defaults that pay off

Most SaaS breaches come from simple mistakes. These guardrails are cheap early, expensive late.

  • Validate inputs at API boundary
  • Rate limit logins & sensitive actions
  • Signed URLs for uploads
  • Secrets in env manager, never DB
  • Audit role and billing changes

Step 9: Scaling without drama

Scaling is usually a sequence of small upgrades, not one big rewrite.

The calm checklist
  • Add read replicas only after you know what queries are heavy
  • Cache expensive reads only after you measure bottlenecks
  • Split workers by job type when one queue starts blocking everything
  • Add an API gateway/rate limits before large integrations
  • Add per-tenant limits (max seats, max usage) to protect reliability

Frequently Asked Questions

Do I need microservices to “scale”?

Almost never at MVP stage. Clean boundaries inside one codebase gets you very far. Split services only when measurement proves it’s necessary.

What’s the biggest early architecture mistake?

Skipping tenant + RBAC decisions early. You can add features later, but retrofitting multi-tenancy and permissions touches everything.

When should I add billing?

As soon as pricing becomes real. Even before full Stripe flows, design your data model around plans, entitlements, and usage limits.