[ECS EC2] Add cpuReservation parameter to separate scheduling from runtime limits
- Dominant language
- Shell
- Stars
- 5.4k
- Forks
- 334
- PR merge metrics
- No merged PRs in 30d
Description
# Add CPU reservation parameter separate from CPU limit in ECS EC2
**Labels**: ECS, feature-request, EC2
## Problem
The `cpu` parameter in ECS EC2 does two things at once:
1. **Scheduling**: ECS uses it to decide if a task fits on an instance
2. **Runtime limit**: The container cannot exceed this CPU value
This forces users to choose between efficiency and protection.
## Current situation
**Memory works correctly** - it has two separate parameters:
```json
"memoryReservation": 256, // Used for scheduling
"memory": 1024 // Used as hard limit
```
**CPU does not** - it has only one parameter:
```json
"cpu": 512 // Used for BOTH scheduling AND limit
```
## The problem this creates
I have 28 services averaging 25% CPU usage with occasional spikes to 50%.
**If I set cpu limit** (`"cpu": 512`):
- ✅ One service cannot saturate the instance (protection works)
- ❌ Each service reserves 512 units even though it only uses ~100
- ❌ Instance appears "full" to the scheduler even though 75% CPU is idle
- ❌ Must provision 3x more instances than needed
**If I don't set cpu limit** (`"cpu": null`):
- ✅ Services share CPU efficiently
- ❌ One attacked/buggy service can use 100% CPU
- ❌ All other services on that instance become unresponsive
- ❌ Lose 5 services instead of 1 during incident
## Requested feature
Add `cpuReservation` parameter:
```json
{
"containerDefinitions": [{
"cpuReservation": 128, // ECS scheduler uses this for placement
"cpu": 512, // Runtime enforces this as maximum
"memoryReservation": 256,
"memory": 1024
}]
}
```
**How it would work:**
- Scheduler sees: "This task needs 128 CPU units minimum"
- Runtime enforces: "This task cannot exceed 512 CPU units"
- Result: Efficient packing + protection against runaway containers
## Real impact
**Current setup (with protection):**
- 6 instances × 2048 CPU units = 12,288 total
- Each service reserves: 512 units
- Maximum services: 12,288 ÷ 512 = 24 services
- Actual CPU usage: 25% (wasted capacity)
**With cpuReservation:**
- Same 6 instances = 12,288 total
- Each service reserves: 128 units (scheduling)
- Each service limited to: 512 units (protection)
- Maximum services: 12,288 ÷ 128 = 96 services
- Can safely run ~50 services with bursting
- **Cost savings: ~50%** (3 instances instead of 6)
## Why this matters
- **Cost**: Cannot efficiently pack containers without sacrificing protection
- **Feature parity**: Kubernetes has had this (requests vs limits) since the beginning
- **Consistency**: Memory already works this way in ECS
- **Production safety**: Forces choice between cost and reliability
## Current workarounds
None work properly:
1. **CPU shares only**: No hard limit, one service can still saturate instance
2. **Overprovision instances**: Expensive and wasteful
3. **No limits**: Unacceptable for production (noisy neighbor problem)
## Related
- Issue #1646 (same request, opened Jan 2022, no AWS response)
- Kubernetes documentation: resource requests vs limits
Contributor guide
Research direction
Start by reviewing the ECS EC2 task-definition CPU semantics described here and compare them with the memoryReservation and memory parameters. Read related issue #1646 for prior context. Done would require an accepted design and AWS implementation or roadmap resolution for a separate cpuReservation parameter, but no repository files or tests are identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 25/100