You Have Exceeded Your Domain: Hitting AWS Amplify’s Custom Domain Limit in a Multi-Tenant App
Wherein we discover that AWS also has feelings about how many subdomains one app should have.
AWS Amplify imposes a hard limit on the number of custom domains that can be associated with a single app. In a single-tenant setup this is irrelevant. In a multi-tenant setup where each tenant gets their own subdomain, it is a countdown timer you didn’t know was running.
The Constraint
Each Amplify app has a per-app limit on custom domain associations. Adding domains beyond the limit returns an error — sometimes a clear quota exception, sometimes a silent failure depending on how the call is made. The limit itself is not prominently documented alongside the service’s getting-started guides or pricing pages. It lives quietly in Service Quotas, waiting.
Why It Surfaces Late
Tenant counts grow gradually. Domain associations accumulate one by one. The limit is never a concern in development, rarely a concern in early rollout, and then suddenly a concern when the 51st (or 101st, or 201st) tenant is onboarded and their subdomain simply never resolves. The tenant exists in the database. The onboarding flow completed without errors. Everything is fine, except the domain doesn’t work and nobody knows why yet.
This is the worst kind of bug: silent, delayed, and customer-facing.
Approaches to Working Within the Limit
1. Request a Quota Increase
Worth attempting, but the Amplify custom domain limit appears to be a hard cap of 50 per app — not an adjustable quota. Service Quotas lists it, but increase requests have come back declined. AWS support has confirmed this is a service-level constraint rather than an account-level one.
Which means the remaining options are not “if the quota increase doesn’t work” fallbacks. They are the plan.
2. Distribute Tenants Across Multiple Amplify Apps
If quota increases aren’t sufficient or approved, tenants can be distributed across multiple Amplify apps, each deploying the same build artifact against the same backend. Each app carries its own domain limit, so N apps give N times the capacity.
The tradeoff is that deployments now need to target all apps, environment variables must be kept in sync across all of them, and monitoring must cover all of them. What was one app to reason about is now a fleet.
This is most workable when tenant provisioning is automated — the logic assigns each new tenant to whichever app has remaining domain capacity, and the operator never touches it manually. If provisioning is manual, this approach will eventually be forgotten and misapplied.
3. Wildcard Domain with Application-Layer Routing
Rather than associating each tenant subdomain individually with Amplify, associate a single wildcard domain (*.example.com) once. Routing is then handled at the application layer: the frontend reads the subdomain from the current URL and loads the appropriate tenant configuration.
This removes per-tenant domain associations entirely. The limit becomes irrelevant — one wildcard association covers every subdomain you will ever create.
The catches:
-
Amplify supports wildcard subdomains on custom domains, but verify it’s enabled on the specific app
-
Wildcard TLS certificates cover one level of subdomain depth only —
tenant.example.comis covered,region.tenant.example.comis not -
DNS-layer tenant isolation disappears. A misconfigured or malicious tenant slug could resolve to another tenant’s context, so the application must validate the resolved tenant explicitly, not trust the subdomain blindly
-
Tenants who bring their own root domain (rather than using a subdomain of yours) still require individual associations and are unaffected by this approach
4. Proxy Layer in Front of Amplify
A CloudFront distribution or other reverse proxy sits in front of Amplify. The proxy handles tenant subdomain resolution and forwards all traffic to Amplify on a single domain. SSL terminates at the proxy. Amplify never sees the tenant subdomains at all.
This gives complete control over subdomain routing with zero Amplify domain associations beyond the one the proxy uses. It is the most flexible option for large or unbounded tenant counts, and the most infrastructure to maintain. CloudFront adds request handling overhead; whether that matters depends on the application’s latency requirements.
Monitoring for the Limit
Domain association failures should be caught at provisioning time, not discovered by a confused tenant filing a support ticket.
-
Handle
createDomainAssociationerrors explicitly, separating quota exceptions from transient failures — they require different responses (raise a quota vs. retry) -
Alert immediately on quota exceptions; they mean the ceiling has been reached, not that something is temporarily broken
-
Track domain association count against the approved quota and alert at 80% utilization — quota increase requests take days to process, and that lead time needs to exist before the ceiling is hit
Summary
| Approach | Complexity | Scales To | Notes |
|---|---|---|---|
| Quota Increase | Low | Higher fixed ceiling | Always try this first. |
| Multiple Amplify Apps | Medium | N × limit | Requires coordinated deployments and provisioning logic. |
| Wildcard Domain + App Routing | Medium | Unlimited subdomains | Useful for subdomain-based tenants, but does not help tenants using their own root domains. |
| Proxy Layer | High | Unlimited | Most flexible approach, but introduces additional infrastructure and operational overhead. |
The quota increase is the right first move. The wildcard approach is the right long-term architecture if all tenants use platform-provided subdomains. The proxy is the right answer if they don’t. Multiple apps is usually the wrong answer — it multiplies operational surface area without eliminating the underlying constraint.