How a multi-tenant SaaS platform is built: Fleet, your platform stack and your apps
Fleet is the service that provisions each customer's infrastructure. The Control Plane is the service where operators set plans, settings and tenant allocation. Tenant allocation means which parts of a customer's stack, such as database and compute, are shared or dedicated. Implementation details for engineering evaluation: layered services, published protocols, per-organization and per-instance storage, tier-aware database scaling and an SDK for platform integration on AWS.
Elastic by design
Scale any layer without touching the rest
Stateless services, per-job worker fleets and service-owned databases give the platform independent scaling dials, vertical and horizontal, at every layer on AWS Fargate and EC2.
Load balancer
per-service routing
measured load
capacity follows
today
2 vCPU
4 GB memory
under load
8 vCPU
32 GB memory
neighbors untouched
Deliveries
own fleet
Imports
hot queue
Workflow runs
own fleet
one job type per worker · own compute · dedicated workers available per customer
service db
Identity
service db
Data engine
service db
Automation
writer
one write path
replica
Reader 1
replica
Reader 2
a hot database moves to its own server · redis can go dedicated per service
Technologies your engineers already operate
The platform uses Python and TypeScript services with PostgreSQL, Redis, Kafka and S3 on AWS. Shared libraries apply the same authentication, configuration and telemetry contracts across services.
Backends
Python + FastAPI services, one per capability, behind a shared base library (models, CRUD, auth, rate limiting, tracing).
Frontends
React + TypeScript, one component library and one config bootstrap shared across every app and the customer portal.
Data
PostgreSQL per application instance for app data and per organization for platform services, with managed connection pooling and, on Large and Extra Large deployment tiers, Aurora readers; Redis for cache and tokens; Kafka for events; S3 for objects.
Cloud
AWS only — managed RDS, S3 and KMS, provisioned for each client. Customer data can be placed in the region it belongs to, including the EU.
Every client stack is deployed in four ordered stages
Fleet builds each stack as code from one reviewed deployment file, one stage at a time. Each stage uses only the recorded outputs of the stage before it, and every apply follows a refreshed preview whose change set must match what was approved.
- 01
Network
The private network for the stack: isolated subnets, outbound gateway and base firewall rules.
- 02
Shared infrastructure
The PostgreSQL cluster, Redis, Kafka and object storage that every service in the stack uses.
- 03
Service data and secrets
A database, encryption keys and credentials for each service, created inside the shared infrastructure.
- 04
Services and edge
The running services and their release pipelines, the web frontends and public DNS.
Deployments run from inside the stack's private network. Operators preview each change, approve the exact resources it will touch, and the platform reads the result back after it is applied. A change that touches a data store requires a fresh snapshot first.
Partial by design
Bound a deployment at any stage. A network-and-data environment with no services is a supported shape, and a real apply refuses to reach below a stage that is already complete.
Account and size per environment
Each environment names its AWS region and runs in its own account, for development, staging, recovery or a specific client. The deployment file carries the sizing, so two environments differ by their file.
Pause, resume, tear down
Pause scales services to zero and stops the database; resume restores what pause recorded. Teardown snapshots the database first, keeps the state store and signed images, and is safe to re-run.
The Control Plane supplies typed configuration to each service
Services read typed configuration from the Control Plane. Operators also compose plans from application features, quotas and supported AWS resource allocations, including customer-specific plans and organization overrides.
Typed sections
Settings are typed sections written whole, for example PUT /config/auth. Unknown fields are rejected.
The narrowest value wins
Settings can be set for the platform, a region, an organization, an app instance or a single user, with the narrowest value winning. Unset sections fall back to platform defaults.
Custom plans combine features, quotas and infrastructure
Create a plan for one customer, set feature and quota values, attach pooled or dedicated AWS resources, and assign it without changing product code.
Plan upgrades can change the isolation boundary
Offer a shared-to-dedicated database, compute or observability upgrade, or place the tenant on an isolated stack. The Control Plane tracks eligible component migrations while Fleet provisions the target AWS resources.
Standard protocols define external integration
The platform uses OIDC, OAuth, SAML, LDAP, SCIM, CloudEvents and OpenTelemetry so existing identity, event and observability tools can connect through documented contracts.
OIDC + OAuth 2.0
The OpenID Connect provider implements authorization-code flow with PKCE, publishes signing keys and rotates refresh tokens.
CloudEvents v1.0
Every platform event is a CNCF CloudEvents envelope on Kafka — one canonical wire format, no bespoke event shapes.
OpenTelemetry
Traces, metrics and structured logs across every service; one trace ID follows a request end to end.
SCIM 2.0
Enterprise identity providers (Okta, Microsoft Entra ID, OneLogin) provision users and groups directly.
Signed webhooks
HMAC-SHA256 per-subscriber signatures, exponential retry, dead-letter — verifiable on the receiver.
JSON Schema-validated app manifests
Each app declares its platform integrations in versioned YAML, validated against JSON Schema on publish.
Storage placement and request scope enforce tenant isolation
Customer data in Authorization, Audit, Comments, Support, AI and sign-in accounts is kept in a separate database for each organization. Data and Automation use a separate database for each app instance. Notification delivery is planned to follow. Shared services scope customer queries by organization and app instance. Every customer starts on shared infrastructure; supported components can move to infrastructure provisioned for that customer alone, sold as a plan upgrade, with the application code unchanged.
Pooled by default
Most tenants share infrastructure with strict per-query scoping, which is cheaper and simpler to operate.
Erasure by contract
Apps declare export and erasure endpoints, and the Control Plane tracks the cascade across installed apps.
Services scale with load
Customer-facing services start with two tasks by default. ECS target tracking on CPU and memory adds capacity up to the configured maximum and removes it back to the floor.
Database read capacity
Managed connection pools absorb session spikes. On the Large deployment tier one Aurora reader is added and on Extra Large two, while transactions and consistent reads stay on the writer.
Dedicated resources by plan
- 01
Offer it per component
Each app lists which of its components can run dedicated: database, compute, cache, event topics, sign-in issuer, storage encryption and monitoring. Each keeps a shared default.
- 02
Put it on a plan
In the Control Plane, choose shared or dedicated for each component of a plan and set its size. Price the plan like any other and publish it.
- 03
Provisioned on subscribe or upgrade
When a customer subscribes or upgrades, the platform builds their dedicated components and points the app at them. Eligible running components move with tracked migration, cutover and rollback.
Customer-managed keys require a dedicated database. How to define a dedicated resource.
Review the request path and isolation boundaries
A solution architect will walk your team through the request path, the tenancy model and the isolation boundaries against the SaaS you are building.