Guide · Service Quotas · DynamoDB · Lambda · ECS
AWS Service Quotas for MCP Servers — Monitoring and Requesting Limit Increases
AWS service quotas (formerly called service limits) are the per-account, per-region ceilings on the number of resources you can create and the throughput you can consume. For MCP server operators, quota exhaustion is an operational failure that looks identical to a software bug from the outside: the MCP server stops accepting new connections, tool calls start failing with cryptic errors, and your CloudWatch alarms fire on symptoms rather than causes. The correct remedy is not a code fix but a quota increase request — which takes hours to days when done reactively. This guide covers the AWS Service Quotas API, the CloudWatch metrics that expose quota consumption, how to identify which quota is being exhausted, and how to request increases proactively before the ceiling is reached.
TL;DR
Use aws service-quotas list-service-quotas --service-code SERVICECODE to view current limits. Use aws service-quotas get-aws-default-service-quota to see the default before any increases. Monitor quota consumption via the AWS/Usage CloudWatch namespace — the ResourceCount metric per service and resource type shows current usage. Create alarms at 80% of quota value. Use aws service-quotas request-service-quota-increase for adjustable quotas. Keep the requestId to poll status with get-requested-service-quota-change.
Key quotas for MCP servers
These AWS service quotas are most likely to constrain MCP server scaling:
| Service | Quota name | Default | Quota code | Impact |
|---|---|---|---|---|
| Lambda | Concurrent executions | 1,000 | L-B99A9384 | All Lambda-backed MCP tool handlers share this pool |
| Lambda | Provisioned concurrency utilization | Varies | L-DC2196D0 | Warm Lambda cold-start mitigation |
| ECS | Running tasks per cluster (Fargate) | 500 | L-3794C6DC | Hard ceiling on MCP server instance count |
| ECS | Tasks per service | 5,000 | L-DC8A8B7C | Per-service scaling ceiling |
| DynamoDB | Table count per account per region | 2,500 | L-F98FE922 | Multi-tenant MCP table per customer pattern |
| DynamoDB | Read capacity units per table | 40,000 | L-DEFA7B0A | Provisioned mode read throughput ceiling |
| API Gateway | API calls per second (REST) | 10,000 | L-B3A6C3A9 | Burst limit for HTTP MCP transport |
| CloudWatch | Alarms | 5,000 | L-74FC7D96 | Alert coverage for large MCP fleet |
Discovering quotas with the Service Quotas API
The Service Quotas API distinguishes between the default quota (the value AWS sets for all accounts) and the applied quota (the value in your account, which may be higher after approved increases).
# List all adjustable quotas for a service
aws service-quotas list-service-quotas \
--service-code lambda \
--query 'Quotas[?Adjustable==`true`].{Name:QuotaName,Value:Value,Code:QuotaCode}' \
--output table
# Get the applied quota for Lambda concurrent executions in this account
aws service-quotas get-service-quota \
--service-code lambda \
--quota-code L-B99A9384 \
--query '{Name:Quota.QuotaName,Applied:Quota.Value}'
# Get the AWS default (before any increases)
aws service-quotas get-aws-default-service-quota \
--service-code lambda \
--quota-code L-B99A9384 \
--query '{Name:Quota.QuotaName,Default:Quota.Value}'
# List recent increase requests in this account
aws service-quotas list-requested-service-quota-changes-by-service \
--service-code lambda \
--query 'RequestedQuotas[*].{Code:QuotaCode,Status:Status,Desired:DesiredValue}'
Service codes for common MCP server dependencies:
| Service | Service code |
|---|---|
| AWS Lambda | lambda |
| Amazon ECS | ecs |
| Amazon DynamoDB | dynamodb |
| Amazon API Gateway | apigateway |
| Amazon ECR | ecr |
| Amazon CloudWatch | monitoring |
| AWS Fargate | fargate |
| Amazon EFS | elasticfilesystem |
Programmatic quota check at startup
The best time to discover a quota problem is during deployment validation, not at runtime. Add a quota check to your MCP server deployment pipeline or startup code:
import { ServiceQuotasClient, GetServiceQuotaCommand } from '@aws-sdk/client-service-quotas';
import { CloudWatchClient, GetMetricStatisticsCommand } from '@aws-sdk/client-cloudwatch';
const quotasClient = new ServiceQuotasClient({ region: 'us-east-1' });
const cloudwatch = new CloudWatchClient({ region: 'us-east-1' });
interface QuotaCheck {
serviceCode: string;
quotaCode: string;
quotaName: string;
usageMetric?: { namespace: string; metricName: string; dimensionName: string; dimensionValue: string };
warnAtPercent?: number;
}
const MCP_QUOTA_CHECKS: QuotaCheck[] = [
{
serviceCode: 'lambda',
quotaCode: 'L-B99A9384',
quotaName: 'Lambda concurrent executions',
usageMetric: {
namespace: 'AWS/Usage',
metricName: 'ResourceCount',
dimensionName: 'Resource',
dimensionValue: 'Executions',
},
warnAtPercent: 80,
},
{
serviceCode: 'ecs',
quotaCode: 'L-3794C6DC',
quotaName: 'ECS running Fargate tasks per cluster',
warnAtPercent: 75,
},
];
async function checkQuotas() {
for (const check of MCP_QUOTA_CHECKS) {
const quota = await quotasClient.send(new GetServiceQuotaCommand({
ServiceCode: check.serviceCode,
QuotaCode: check.quotaCode,
}));
const limit = quota.Quota?.Value ?? 0;
if (check.usageMetric) {
const stats = await cloudwatch.send(new GetMetricStatisticsCommand({
Namespace: check.usageMetric.namespace,
MetricName: check.usageMetric.metricName,
Dimensions: [
{ Name: check.usageMetric.dimensionName, Value: check.usageMetric.dimensionValue },
],
StartTime: new Date(Date.now() - 5 * 60 * 1000), // last 5 minutes
EndTime: new Date(),
Period: 300,
Statistics: ['Maximum'],
}));
const currentUsage = stats.Datapoints?.[0]?.Maximum ?? 0;
const pct = (currentUsage / limit) * 100;
if (pct >= (check.warnAtPercent ?? 80)) {
console.warn(`QUOTA WARNING: ${check.quotaName}: ${currentUsage}/${limit} (${pct.toFixed(1)}%)`);
}
}
}
}
Requesting quota increases
Use the Service Quotas API to request increases for adjustable quotas. Only some quotas are adjustable — non-adjustable quotas are hard limits that require a formal support case with AWS. Check Quota.Adjustable before submitting a request.
# Request an increase for Lambda concurrent executions (from 1000 to 3000)
aws service-quotas request-service-quota-increase \
--service-code lambda \
--quota-code L-B99A9384 \
--desired-value 3000 \
--query '{RequestId:RequestedQuota.Id,Status:RequestedQuota.Status}'
# Poll the request status
aws service-quotas get-requested-service-quota-change \
--request-id REQ_ID \
--query '{Status:RequestedQuota.Status,CaseId:RequestedQuota.CaseId}'
# List all pending requests across all services
aws service-quotas list-requested-service-quota-changes \
--status PENDING \
--query 'RequestedQuotas[*].{Service:ServiceCode,Quota:QuotaName,Status:Status,Desired:DesiredValue}'
Request status transitions:
| Status | Meaning |
|---|---|
PENDING | Request submitted, not yet reviewed by AWS |
CASE_OPENED | AWS Support case opened; a CaseId is available |
APPROVED | Increase approved; the new limit is active |
DENIED | Request denied; check the denial reason and re-submit with justification |
CASE_CLOSED | Support case closed |
NOT_AVAILABLE | Quota not adjustable via self-service API; requires direct Support engagement |
Approval typically takes 1–3 business days for common quotas. For latency-sensitive increases (scaling event approaching), mark the Support case as urgent and reference the specific AWS service event. Lambda concurrent executions, ECS Fargate running tasks, and DynamoDB table count are almost always approved up to 10x the default if the request includes a brief workload justification.
Using Service Quotas with AWS Organizations
Service Quotas can be managed at the organizational level using quota templates. A quota template pre-requests a quota increase for newly-created member accounts, so new accounts start with higher limits than the AWS default without manual requests per account.
# List quota templates defined in the management account
aws service-quotas list-service-quota-increases-by-template \
--aws-region us-east-1 \
--query 'ServiceQuotaIncreaseRequestInTemplateList[*].{Service:ServiceCode,Quota:QuotaName,Value:DesiredValue}'
# Add a quota template entry for Lambda concurrent executions
aws service-quotas put-service-quota-into-template \
--service-code lambda \
--quota-code L-B99A9384 \
--aws-region us-east-1 \
--desired-value 2000
# Associate the template with the organization (apply to all new member accounts)
aws service-quotas associate-service-quota-template
Quota templates apply only to accounts that join the organization after the template is defined — they do not retroactively update existing member accounts. For existing accounts, you must submit individual increase requests or use an automated Lambda-based solution (see quota increase automation).
Common failures
| Symptom | Cause | Fix |
|---|---|---|
TooManyRequestsException from Lambda with no throttling alarms firing | Lambda concurrent executions quota exhausted — this exception is distinct from function-level throttles which appear in CloudWatch Lambda metrics | Check AWS/Usage ResourceCount Executions metric against your quota; request increase or add Lambda reserved concurrency to protect critical handlers |
ECS service stuck at PROVISIONING and not starting tasks | Fargate running tasks per cluster quota reached | Check aws ecs list-tasks --cluster CLUSTER --desired-status RUNNING | wc against quota; deregister unused tasks or request quota increase |
DynamoDB table creation fails: LimitExceededException: Too many tables | DynamoDB table count quota (default 2,500) reached | List and delete unused tables with aws dynamodb list-tables; request quota increase for multi-tenant deployments |
request-service-quota-increase returns NoSuchResourceException | The quota code is not valid for the region, or the quota is not adjustable via API | Verify the quota code with list-service-quotas; for non-adjustable quotas, file a Support case directly |
Quota increase request stays in PENDING for more than 5 business days | High request volume at AWS or insufficient justification in the request notes | Use get-requested-service-quota-change to retrieve the CaseId, then update the Support case with workload details and urgency level |