We built a project management SaaS that hit 500 paying tenants in 8 months. At 100 tenants, everything was fine. At 300, one tenant's data export job started slowing down the database for everyone else. Classic noisy neighbor problem. We'd chosen shared-database multi-tenancy (the cheapest option) and hadn't implemented per-tenant resource limits. The fix took 3 weeks. If we'd designed for it upfront, it would have taken 3 days. Multi-tenancy architecture is boring until it's the most important thing.
What We'll Cover
Multi-Tenancy Patterns
| Pattern | How It Works | Isolation Level | Cost per Tenant | Best For |
|---|---|---|---|---|
| Shared database, shared schema | All tenants in same tables. tenant_id column on every table |
Low (one bad query affects all) | Lowest | SMB SaaS, freemium products, under 1,000 tenants |
| Shared database, separate schemas | One database, each tenant gets their own schema (PostgreSQL schemas) | Medium (data isolation, shared resources) | Low | Mid-market SaaS, compliance needs, 100-5,000 tenants |
| Database per tenant | Each tenant has their own database instance | High (full isolation) | Highest | Enterprise SaaS, healthcare/fintech compliance, data residency |
| Hybrid | Shared database for small tenants, dedicated for enterprise | Variable | Variable | SaaS with both SMB and enterprise tiers |
Our Recommendation
Start with shared database + tenant_id column. It's the simplest, cheapest, and works for 90% of SaaS products until 1,000+ tenants. Add PostgreSQL row-level security (RLS) for data isolation. Migrate to database-per-tenant for enterprise customers when they demand it — not before.
-- PostgreSQL Row-Level Security
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON projects
USING (tenant_id = current_setting('app.current_tenant')::uuid);
-- Set tenant context per request (in your middleware)
SET app.current_tenant = 'tenant-uuid-here';
-- Now SELECT * FROM projects only returns current tenant's data
-- Even if application code forgets the WHERE clause
Subscription Billing Architecture
| Billing Provider | Monthly Cost | Best For | India Support |
|---|---|---|---|
| Stripe Billing | 0.5% per invoice (on top of payment processing) | Global SaaS, complex pricing models, usage-based billing | Yes — INR, UPI, auto-debit |
| Razorpay Subscriptions | 2% per transaction | India-focused SaaS, UPI autopay, emandate support | Best for India — native UPI recurring |
| Chargebee | $249-549/month + per txn | Complex billing: metered, tiered, hybrid pricing. Revenue recognition | Yes — works with Indian gateways |
Pricing Model Patterns
- Flat-rate: $29/month for everything. Simple, predictable. Hard to capture value from large customers
- Per-seat: $10/user/month. Aligns with team growth. Customers game it by sharing accounts
- Usage-based: Pay per API call/GB stored/email sent. Fair, but unpredictable revenue. Track usage meticulously
- Tiered: Free / Starter ($29) / Pro ($79) / Enterprise (custom). Most common. Works for most SaaS
Tenant Isolation: Beyond the Database
- API rate limiting per tenant. One tenant's batch job shouldn't affect others' API performance. Use Redis-based rate limiting with per-tenant buckets
- Background job isolation. Separate queues or priority levels per tenant tier. Enterprise jobs get priority. Free tier jobs run at low priority
- Storage isolation. S3 bucket per tenant or prefix-based separation. Never let tenant A access tenant B's files
- Feature flags per tenant. Enable beta features for specific tenants. Use feature flags not just for rollout, but for tier-based access control
Scaling from 10 to 10,000 Tenants
| Stage | Tenants | Architecture | Infrastructure |
|---|---|---|---|
| MVP | 1-50 | Monolith. Shared DB. Simple auth | Single server or Vercel + managed DB |
| Growth | 50-500 | Monolith with background workers. RLS. Caching | 2-3 servers + read replica + Redis |
| Scale | 500-5,000 | Extract heavy services (billing, notifications). Connection pooling. CDN | Container orchestration. Multiple DB replicas. Queue system |
| Enterprise | 5,000+ | Hybrid tenancy. Dedicated instances for enterprise. Cell-based architecture | Multi-region. Per-tenant resource limits. Dedicated infra for large tenants |
Tenant Onboarding: First 5 Minutes Matter
SaaS products live or die by onboarding. 40-60% of free trial users never return after their first session. Your onboarding flow should get users to the "aha moment" within 5 minutes.
- Seed with sample data. Don't show an empty dashboard. Pre-populate with example projects, tasks, or whatever your product manages
- Interactive walkthrough. 3-5 step guided tour highlighting the core action. Not a product tour of every feature — just the one thing that delivers value
- Self-serve team invitation. The person who signs up isn't always the end user. Make it dead simple to invite team members
Frequently Asked Questions
Which multi-tenancy pattern should I start with?
Shared database with tenant_id column and PostgreSQL row-level security. It's the cheapest, simplest to operate, and works for 90% of SaaS products. Move to database-per-tenant only when enterprise customers contractually require it.
How do I handle data residency requirements in SaaS?
Deploy in multiple regions (AWS Mumbai for India, EU-West for GDPR, US-East for US). Route tenants to the appropriate region based on their data residency requirement. This requires database-per-tenant or at least region-per-tenant. Plan for this early if you expect enterprise customers.
How much does it cost to build a SaaS product?
SaaS MVP (core features + billing + onboarding): ₹20-40 lakh over 3-5 months. Growth stage (team features, integrations, analytics): add ₹30-60 lakh. Enterprise features (SSO, audit logs, compliance): add ₹20-40 lakh. Infrastructure costs scale with tenants — budget ₹10K-1L/month depending on usage.