In our last lesson, we made the foundational decision to build our SaaS using a Shared Database, Shared Schema multi-tenancy model. This choice prioritizes scalability and cost-efficiency, and we committed to engineering robust security using PostgreSQL's Row-Level Security. Now that we've determined how our data will be stored, we need to zoom out and define the overall structure of the system.
This lesson is about creating the master blueprint for our application. We will design a high-level architecture diagram, a crucial artifact for any senior engineer or architect. This diagram will serve as our map, identifying every major component—from the frontend client to backend services and databases—and illustrating how they communicate. Mastering this skill moves you from thinking about individual features to seeing the system as a cohesive, interconnected whole.
The Two Halves of a SaaS Architecture: Control Plane and Application Plane
Before we can draw our diagram, we need a mental model for organizing a SaaS system. A powerful and widely-adopted pattern is to divide the architecture into two distinct halves: the Control Plane and the Application Plane. This separation of concerns is fundamental to building, operating, and scaling a multi-tenant product effectively.
An excellent book, "Building Multi-Tenant SaaS Architectures," provides a thorough explanation of this concept.
[PDF] Building Multi-Tenant SaaS Architectures
This excerpt will introduce you to the core concept of the Control and Application planes. Understanding this distinction is key to thinking like a SaaS architect.
Read the section The Two Halves of Every SaaS Architecture in Chapter 2. Focus on the distinct responsibilities of each plane. Notice that the Control Plane is not multi-tenant, but rather manages the multi-tenant Application Plane.
To summarize the key ideas from the reading:
- Application Plane: This is where your product's core features live. For our project, this is where construction project management, task tracking, and file management happen. It is inherently multi-tenant, and all the design considerations we've discussed (like tenant isolation) apply here.
- Control Plane: This is the "brain" that orchestrates the entire system. It handles cross-cutting concerns that are essential for the business of SaaS but are not specific to any single tenant's use of the product. It manages and operates the Application Plane.
Let's break down the components of each plane.
Inside the Control Plane
The Control Plane contains all the services needed to manage the lifecycle of a tenant. Think of it as the administrative backend for you, the SaaS provider. The components here are responsible for onboarding new tenants, managing their identity, handling billing, and provisioning the resources they need in the Application Plane.
This diagram illustrates a typical tenant onboarding flow, which is orchestrated entirely by the Control Plane.

This diagram shows the sequence of services within the Control Plane that are triggered when a new tenant signs up.
Let's explore the essential services that reside here, as detailed in the "Building Multi-Tenant SaaS Architectures" book.
[PDF] Building Multi-Tenant SaaS Architectures
Now, let's dive into the specific services that make up a typical Control Plane.
Read the section Inside the Control Plane in Chapter 2. As you read, map the services described (Onboarding, Identity, Metrics, Billing, Tenant Management) to the components shown in the "Tenant Onboarding Architecture" diagram above.
The key services of the Control Plane include:
- Onboarding/Registration Service: The entry point for a new company. It orchestrates the entire sign-up process.
- Tenant Management Service: A central service to create, update, and manage the state of tenants (e.g., their subscription plan, status, unique ID).
- User Management & Identity Service: Manages user accounts, binds them to a tenant, and handles authentication and authorization policies.
- Billing Integration Service: Connects to a payment provider (like Stripe) to manage subscriptions, plans, and invoices.
- Tenant Provisioning Service: Interacts with the Application Plane to set up the necessary resources for a new tenant.
Inside the Application Plane
The Application Plane is where your users spend their time. It delivers the features they pay for. In a pooled model like ours, every service and resource in this plane must be acutely aware of "who" is making the request. This is where the concept of Tenant Context becomes critical.
[PDF] Building Multi-Tenant SaaS Architectures
This section covers the core multi-tenant principles that must be implemented within the Application Plane.
Read the section Inside the Application Plane in Chapter 2. Pay close attention to the concept of Tenant Context and how it flows through the system to enforce Tenant Isolation.
Four crucial themes dominate the Application Plane:
- Tenant Context: Every incoming request must be resolved to a specific tenant. This context, often carried in a JWT token, acts as a "passport" that travels with the request, informing every downstream service which tenant's data it should be operating on.
- Tenant Isolation: This is the enforcement mechanism. Every single database query and API call must use the Tenant Context to filter data. This is where our RLS policies in PostgreSQL will provide a powerful safety net.
- Data Partitioning: This refers to the data isolation strategy we chose in the last lesson—a pooled model where all tenants share tables, distinguished by a
tenant_idcolumn. - Tenant Routing: In a simple pooled model, routing is straightforward. However, as a SaaS grows, it might introduce different deployment models for different tiers.
Architectural Flexibility: Pool, Silo, and Hybrid Models
While we've chosen a fully pooled model as our starting point for its efficiency, a senior architect always designs for future flexibility. The business might decide to offer a "Premium" or "Enterprise" tier that provides dedicated resources for higher performance and isolation guarantees.
This is where the vocabulary of Pool (shared resources) and Silo (dedicated resources) becomes essential. A mature SaaS architecture often employs a hybrid or mixed-mode model, combining these patterns to serve different customer segments.

This diagram illustrates a common SaaS strategy where different subscription tiers (Basic, Premium, Platinum) map to different deployment models (Pool, Bridge/Hybrid, Silo), balancing cost and isolation.
The "Building Multi-Tenant SaaS Architectures" book provides the formal definitions for these patterns.
[PDF] Building Multi-Tenant SaaS Architectures
Let's formalize our understanding of these deployment models.
First, read the section Introducing the Silo and Pool Models to solidify the terminology. Then, quickly skim the sections on A Hybrid Full Stack Deployment Model and The Mixed-Mode Deployment Model to see how these concepts are combined in practice.
For our project, we will start with a pure Pool Model for all tenants. However, by designing our services with a clear understanding of Tenant Context from day one, we leave the door open to introduce Silo or Hybrid tiers later without a major architectural rewrite. This is a hallmark of forward-thinking system design.
High-Level Architecture for the Construction Management SaaS
Now, let's synthesize these concepts into the high-level architecture for our system. We will structure our design into logical layers, a common practice for organizing complex systems. Your experience with full-stack Django/React applications means you're already familiar with the client-server model; we're now formalizing it with more specific components.
Here is the blueprint for our platform:
1. Client Layer
- Flutter Application (Mobile & Web): A single codebase delivering the user interface to both mobile devices and web browsers. This is what the end-user interacts with.
2. Edge & Gateway Layer
- Load Balancer: The first point of contact for all incoming traffic. It distributes requests across multiple instances of our API Gateway to ensure high availability and handle load.
- API Gateway: The single entry point into our backend. It is responsible for:
- Routing incoming requests (e.g.,
/projects/*) to the correct backend service (Project Management Service). - Terminating SSL/TLS.
- Handling initial authentication by validating JWTs.
- Aggregating responses from multiple services if needed.
- Routing incoming requests (e.g.,
3. Service Layer (The Application Plane)
This layer contains our core business logic, broken down into a set of communicating FastAPI microservices. Each service has a distinct responsibility.
- Auth Service: Handles user registration, login, password management, and JWT generation. It owns the
userstable. - Tenant & Subscription Service: Corresponds to the Control Plane's management functions. It handles company registration (tenant creation), subscription tier management, and feature gating. It owns the
tenantsandsubscriptionstables. - Project Management Service: The core of our product. Manages CRUD operations for projects, tasks, and milestones.
- File Management Service: Handles file uploads. It doesn't store files itself but will generate secure, pre-signed URLs for clients to upload directly to cloud storage, and then save the metadata.
- Notifications Service: Manages the creation, storage, and retrieval of user notifications.
- Async Worker Service (Celery/ARQ): Runs background jobs that are too slow to be handled in a web request. Examples include sending invitation emails, generating monthly reports, or processing large file uploads.
4. Data & Infrastructure Layer
This layer provides the foundational persistence and messaging capabilities for our services.
- PostgreSQL Database: Our primary database, using the Shared DB/Shared Schema model we decided on. All services in the Application Plane will connect to this database to read and write tenant-scoped data.
- Redis: Serves two critical functions:
- Cache: For storing frequently accessed, non-critical data to improve performance (e.g., dashboard analytics).
- Message Broker: For the Celery/ARQ worker service to manage the queue of background tasks.
- Cloud Object Storage (e.g., AWS S3): Used for storing large binary files like construction plans, documents, and photos.
This layered architecture provides a clear separation of concerns, allowing us to develop, deploy, and scale each part of the system independently.
Conclusion
In this lesson, we have created the high-level architectural blueprint for our SaaS platform. This is a critical step that bridges the gap between abstract requirements and a concrete implementation plan.
Key Takeaways:
- SaaS architectures are best understood when divided into a Control Plane (managing the system) and an Application Plane (delivering features).
- Deployment models range from Silo (dedicated) to Pool (shared), and mature systems often use a hybrid approach to support different pricing tiers.
- Our architecture will be layered, with a Flutter client, an API Gateway, a set of focused FastAPI microservices, and a robust data layer featuring PostgreSQL, Redis, and cloud storage.
- Tenant Context is the thread that ties the entire Application Plane together, ensuring every operation is securely scoped to the correct customer.
Preview of the Next Lesson:
With our high-level components identified, our next step is to formalize the boundaries between them. We will introduce concepts from Domain-Driven Design (DDD) to define bounded contexts and service boundaries. This will help us refine our microservice architecture, ensuring each service has a clear, cohesive responsibility, which is crucial for long-term maintainability and scalability.