Building a Multi-Tenant SaaS: Lessons from 7 State-Specific School Report Platforms
How I built a multi-tenant architecture that powers NSW, ACT, WA, NT, VIC, QLD, and SA school report platforms. Technical deep-dive on shared infrastructure, state-specific customizations, and scaling across multiple states.
Building a Multi-Tenant SaaS: Lessons from 7 State-Specific School Report Platforms
When I set out to build school report comment tools for Australian teachers, I faced a challenge: each state has unique reporting requirements, curriculum standards, and departmental language. NSW teachers need NESA-aligned comments. WA teachers reference SCSA standards. VIC teachers work with VCAA guidelines. Building seven separate applications would be inefficient—but building one generic platform would fail teachers who need state-specific guidance.
This is the story of how I built a multi-tenant architecture that powers seven distinct school report platforms while sharing core infrastructure, AI models, and deployment pipelines.
The Problem: State-Specific Requirements
Australia's education system is decentralized. Each state and territory has its own:
- Curriculum authority (NESA, ACT Directorate, SCSA, NT DoE, VCAA, QCAA, SA Department for Education)
- Reporting language and achievement standards
- Five-point scale variations and descriptors
- Learning area terminology
A NSW teacher searching for "report comments" needs results aligned with NESA achievement standards. A WA teacher needs SCSA language. Building separate applications would mean:
- 7x the deployment overhead
- 7x the infrastructure costs
- 7x the maintenance burden
- Lost opportunities for shared learnings and improvements
The Solution: Multi-Tenant Architecture
I built a single codebase that serves multiple domains, each with state-specific customizations:
- nswschoolreports.com.au - NSW/NESA aligned
- actschoolreports.com.au - ACT Directorate standards
- waschoolreports.com.au - SCSA guidelines
- ntschoolreports.com.au - NT DoE descriptors
- vicschoolreports.com.au - VCAA expectations
- qldschoolreports.com.au - QCAA standards
- saschoolreports.com.au - SA Department alignment
Core Infrastructure
The shared foundation includes:
- Next.js application with dynamic routing
- AI-powered comment generation (shared model, tuned per state)
- User authentication and session management
- Analytics and usage tracking
- Database schema with tenant isolation
State-Specific Customizations
Each tenant gets:
- Custom domain routing
- State-specific curriculum mapping
- Departmental language and terminology
- Achievement standard filters
- Learning area taxonomies aligned to that state
Technical Implementation
Domain-Based Tenant Detection
The application detects the tenant based on the incoming domain:
```typescript function getTenantFromDomain(domain: string): Tenant { const tenantMap: Record<string, Tenant> = { 'nswschoolreports.com.au': 'NSW', 'actschoolreports.com.au': 'ACT', 'waschoolreports.com.au': 'WA', // ... other tenants } return tenantMap[domain] || 'DEFAULT' } ```
Shared AI Model with State Tuning
Rather than maintaining seven separate AI models, I use a shared model with state-specific prompts and fine-tuning:
- Base model understands curriculum-aligned comment generation
- State-specific prompts inject departmental language
- Achievement standard filters ensure compliance
- Tone controls work across all states
Database Schema with Tenant Isolation
All data is isolated by tenant ID:
```sql CREATE TABLE comments ( id UUID PRIMARY KEY, tenant_id VARCHAR(10) NOT NULL, user_id UUID NOT NULL, learning_area VARCHAR(100), achievement_level VARCHAR(20), content TEXT, created_at TIMESTAMP DEFAULT NOW() );
CREATE INDEX idx_comments_tenant ON comments(tenant_id); ```
Scaling Challenges
Performance at Scale
With active users across seven tenants:
- Database queries must be tenant-aware
- Caching strategies respect tenant boundaries
- CDN configuration serves correct domain
- Analytics track per-tenant metrics
Deployment Strategy
Each tenant gets:
- Custom domain DNS configuration
- SSL certificate management
- Environment-specific configurations
- Separate analytics tracking
But deployments are unified:
- Single codebase deploys to all tenants
- State-specific configs load at runtime
- Zero-downtime deployments
- Rollback affects all tenants simultaneously
SEO Considerations
Each tenant needs its own SEO presence:
- Unique meta titles and descriptions
- State-specific keywords (e.g., "NESA report comments" vs "SCSA achievement standards")
- Schema.org structured data per tenant
- Canonical URLs pointing to correct domain
- Sitemap generation per tenant
Lessons Learned
1. Start with Shared Infrastructure
Building the multi-tenant architecture from day one was crucial. Retro-fitting tenant isolation would have been significantly harder.
2. Configuration Over Code
State-specific differences live in configuration files, not scattered throughout the codebase. This makes adding new tenants straightforward.
3. SEO is Per-Tenant
Each domain needs its own SEO strategy. Google indexes each domain separately, so keyword targeting, schema markup, and content structure must be tenant-aware.
4. Shared Improvements Benefit All
When I improve the AI model, all seven tenants benefit. When I optimize performance, all users see faster load times. This compound effect is powerful.
5. Monitoring and Analytics
Tracking metrics per tenant helps identify which states need more support, which features resonate, and where to focus development efforts.
The Results
Today, the multi-tenant platform serves:
- Active users across multiple states
- 7 state-specific domains
- 99.9% uptime across all tenants
- Shared infrastructure costs
- Unified development workflow
Teachers get state-aligned tools. I get scalable infrastructure. Everyone wins.
Next Steps
The architecture is designed to scale. Adding new tenants (like Tasmania or international markets) requires:
- Adding domain configuration
- Creating state-specific curriculum mappings
- Configuring SEO metadata
- Deploying (same codebase, new tenant)
The multi-tenant approach has proven itself: it's efficient, scalable, and delivers better results than separate applications ever could.