Zum Inhalt springen

From Monolith to SaaS in 5 Lessons (5-Minute Read)

Can you turn a brittle legacy app into a multi-tenant SaaS without rewriting it from scratch?
We just did. In four sprints, our team relaunched a seven-year-old e-commerce monolith as a subscription-based platform powered by Angular 19 SSR, Node 20 + Fastify and Terraform Cloud.

This post distills everything that worked, what blew up in our faces, and a copy-paste migration checklist. Grab a coffee: 8-minute read.

1 — Why Even Migrate? (Hint: Money & Velocity) ☕

Metric Before After Delta
Monthly Release Cadence 1 / month 12 / month × 12
Infra Cost / Tenant €165 €97 -41 %
LCP 75th p (field) 4.1 s 1.9 s -54 %
Net Promoter Score 34 65 +31

ROI kicker: each 1-second LCP drop boosted funnel conversion by 6 %. Numbers made finance very, very happy.

2 — Audit the Monster in 3 Dimensions 🕵️

Before touching code, we ran a 3-D audit. Score every module 1 → 5:

Dimension 5 = Red-Zone Symptoms
Coupling Cross-module imports, fat controllers, tangled AngularJS & jQuery
Test Coverage < 10 % paths exercised
Rollback Blast Radius DB migrations are irreversible, prod config differs from staging

Rule of thumb: anything scoring ≥ 4 goes into the “strangler fig” backlog—decouple after you stabilize the happy path.

3 — Architecture Choice: Modular Monolith + Feature Flags 🚀

Why not micro-services right away?

Option ⏱️ Speed to Ship 🔒 Tenant Isolation 👷‍♂️ Ops Burden
Lift-and-Shift Docker ⚡ Fast 😰 Minimal 😀 Low
Modular Monolith + Flags 🔄 Balanced 🙂 Good 🟡 Medium
Micro-services (DDD) 🐢 Slow 😎 Great 🔴 High

We chose Modular Monolith:

  • Single repo keeps onboarding trivial.
  • Feature flags let us ship dark features to one tenant at a time.
  • Move to services only when a module outgrows the monolith.

4 — Frontend Overhaul: Angular 19 with Native SSR 🖼️

# add server-side rendering in two commands
npx ng add @angular/ssr
npm run build:ssr && npm run serve:ssr

`

Two lessons learned

  1. Lazy-hydrated Islands: heavy graphs & charts blew up renderApplication memory. We wrapped them with ngSkipHydration and hydrated on IntersectionObserver.
  2. TC39 Temporal API: Angular 19’s new date pipes + Node 20 eliminated 30 kB of Moment.js dead weight.

Result: LCP < 2 s on real Moto G4 devices.

5 — Backend & Tenancy: Fastify + Postgres RLS 🗄️

  • Fastify because 80 k req/s on a single M6g large with zero tuning.
  • Row-Level Security (policy USING (tenant_id = current_setting('app.tenant_id'))) keeps one DB until we hit 1 TB—then we partition.
  • Observability: OpenTelemetry → Grafana Cloud; one dashboard per tenant with UID templating.

6 — CI/CD: Green-Only Deploys in 45 Lines 📦

`yaml

.github/workflows/deploy.yml (core)

on: [push]
jobs:
test: … # npm ci && npm test
build_ssr: … # npm run build:ssr
deploy:
needs: build_ssr
runs-on: ubuntu-latest
permissions: { id-token: write }
steps:
– uses: hashicorp/setup-terraform@v3
– run: terraform init && terraform apply -auto-approve
`

Prod deploy in 11 min. If tests fail, prod is untouched.

7 — Security First (Really) 🔐

Layer Must-Have Control Tooling
Auth Passwordless magic-link + OAuth 2.1 Auth.js & Argon2
API Per-tenant rate-limit + HMAC sigs Fastify hooks, Redis
Data AES-256 PII encryption + RLS Postgres 15, AWS KMS
Infra CIS Level 1 as code tfsec, Open Policy Agent

Fun fact: Week 1, 37 % of traffic was credential-stuffing bots—blocked automatically.

8 — Cost Lever Matrix 💸

Lever Year-1 Savings How
Edge Caching -23 % Cloudflare caches SSR HTML + stale-while-revalidate
Serverless Cron -11 % Nightly reports moved to AWS Lambda
Cloud Credits -17 % AWS Activate + open-source sponsorship
Multi-AZ +6 % cost Worth it: SLA 99.95 % → churn -1.2 %

9 — Five Lessons We Keep Re-Learning 🤹‍♂️

  1. Feature flags > long-lived branches.
  2. Measure field LCP, not just Lighthouse.
  3. Docs or die. Every interface change = one ADR file.
  4. Tenant-id on Day 0 – retro-fitting is hell.
  5. Post-launch “broken windows” sprint saves morale.

10 — Pocket Checklist (Steal Me) ✅

  1. ☐ Build a coupling matrix
  2. ☐ Add tenant_id column everywhere now
  3. ☐ Ship risky slices behind flags
  4. ☐ Synthetic health check per tenant
  5. ☐ Schedule “Fix Broken Windows” sprint after go-live

Get the 28-Page Migration Workbook

Need the detailed budgets, Terraform modules and RLS snippets?
Grab the full PDF here → Novane (free, no email gate).

Shipping a SaaS is never one-click magic. But with a modular plan, ruthless DevOps discipline and an obsession for user experience, you can turn a creaky monolith into a growth flywheel in under a month. Share your war stories below—let’s swap scars! 🚀


Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert