Tiers and deployment models
The four tiers
Section titled “The four tiers”| Tier | Deployment | Rate / burst (req/s) | Quota / day | Lambda reserved concurrency |
|---|---|---|---|---|
BASIC |
pooled | 50 / 50 | 1,000 | shared account pool |
STANDARD |
pooled | 75 / 100 | 3,000 | shared account pool |
PREMIUM |
pooled | 100 / 200 | 5,000 | shared account pool |
PLATINUM |
silo | 300 / 300 | 10,000 | 5 per function |
Tier settings are defined once in server/cdk/lib/tenant-template/tiers.ts.
How a tier is applied
Section titled “How a tier is applied”- The bootstrap stack creates one API Gateway API key per tier and stores each key’s id and value in SSM Parameter Store (
apiKeyBasicTierKeyId,apiKeyBasicTierValue, and so on). - Each tenant template stack reads the keys for the tiers it serves and attaches them to its usage plans.
- The REST API uses
apiKeySourceType: AUTHORIZER. Clients never send an API key: the authorizer returns the tier’s key asusageIdentifierKey, and API Gateway counts the request against that plan. - Over the limit, API Gateway returns
429. The SaaS app shows a friendly message for it.
A pooled stack only knows the Basic, Standard and Premium keys, so a Platinum user’s token is rejected there with 401. That user belongs on their own silo stack.
Pooled vs silo
Section titled “Pooled vs silo”| Pooled stack | Silo stack | |
|---|---|---|
CDK_PARAM_TENANT_ID |
pooled (default) |
the tenant’s id |
| User pool | shared, one group per tenant | the tenant’s own |
| Tables | shared, isolated by LeadingKeys |
the tenant’s own |
| Lambdas reach DynamoDB with | the authorizer’s tenant-scoped credentials | their own role |
| Usage plans | Basic, Standard, Premium | Platinum |
| Created by | deploy.sh |
the provisioning job, when a Platinum tenant is onboarded |
Both are the same CDK code, so services don’t branch on the deployment model beyond picking their DynamoDB client.
Everything is serverless and on-demand, so an idle silo stack costs close to nothing. Each Platinum tenant is still a full stack (an API, about 17 Lambdas, 2 tables and a user pool), and reserved concurrency takes 5 × functions out of the account’s concurrency pool per tenant.