What Happens at 100% CPU on an Amazon EC2 C-Series Instance?
When a compute-intensive batch job reaches 100 percent CPU utilization on an Amazon EC2 C-series instance, the virtual machine continues to run at its full provisioned capacity without experiencing CPU credit throttling or unexpected surcharge billing. Unlike T-series burstable instances, C-series compute-optimized instances provide dedicated, fixed performance for every allocated virtual CPU (vCPU). However, operating at maximum processor capacity means any additional compute threads will enter a run queue, causing increased execution times, higher context-switching overhead, and potential delays in operating system tasks, health checks, and network packet processing.
Fixed Performance vs. Burstable Instances
To understand how an EC2 C-series instance behaves under full load, it helps to contrast it with AWS burstable performance instances (such as the T3 or T4g families). Burstable instances operate on a credit system where baseline CPU utilization is capped at a fraction of a vCPU, and sustained 100 percent usage either drains CPU credits—eventually throttling the processor back to baseline—or incurs extra charges in Unlimited mode.
Amazon EC2 C-series instances (such as C5, C6i, C6g, and C7g) are fixed-performance, compute-optimized instances. When you provision a C-series instance, you receive full, continuous access to the underlying hardware threads or cores mapped to your vCPUs:
- No Throttling: You can run all vCPUs at 100 percent utilization 24 hours a day, 7 days a week, without performance degradation from hypervisor rate-limiting.
- No Burst Charges: Your hourly instance cost remains constant regardless of whether your average CPU utilization is 1 percent or 100 percent.
- Consistent Clock Speeds: Powered by high-frequency Intel Xeon, AMD EPYC, or AWS Graviton processors, C-series instances are engineered to maintain sustained all-core turbo clock frequencies during heavy batch processing.
Operating System Scheduling and Run Queue Contention
While the AWS Nitro hypervisor will not throttle your C-series instance at 100 percent CPU utilization, the guest operating system must manage how threads share the finite number of vCPUs.
If your batch job spawns strictly as many active worker threads as there are vCPUs (\(N_{\text{threads}} = N_{\text{vCPUs}}\)), the workload runs at peak efficiency. Each thread can stay pinned to a vCPU with minimal interruption. However, if the total number of runnable threads exceeds the number of available vCPUs (\(N_{\text{threads}} > N_{\text{vCPUs}}\)), contention occurs:
\[\text{CPU Saturation Ratio} = \frac{R}{N_{\text{vCPUs}}}\]
Where \(R\) represents the number of
runnable processes in the operating system run queue (visible via the
r column in vmstat or load averages in
uptime). When \(\frac{R}{N_{\text{vCPUs}}} > 1\),
threads must wait for CPU time slices.
Context Switching Overhead
When the run queue grows beyond the vCPU count, the Linux kernel scheduler (such as the Completely Fair Scheduler, or CFS) must rapidly switch between active threads to ensure fairness. High context switching leads to:
- Direct CPU Overhead: The processor spends cycles saving and restoring CPU registers rather than executing batch application code.
- CPU Cache Thrashing: As threads are swapped out and replaced by others, L1, L2, and L3 processor caches are invalidated and overwritten, increasing memory access latency.
Hardware Architecture Considerations: x86 vs. Graviton
How a C-series instance performs at 100 percent CPU utilization also depends on the underlying processor architecture of the specific C-series family you choose.
Intel and AMD C-Series (C5, C6i, C6a, C7i, C7a)
On most x86-based C-series instances (excluding bare-metal sizes), each vCPU corresponds to a single Simultaneous Multithreading (SMT) hardware thread (Intel Hyper-Threading). Two vCPUs share the execution resources of a single physical processor core.
When a compute-intensive batch job pushes all vCPUs from 50 percent to 100 percent utilization, total throughput does not double. Because pairs of vCPUs contend for the same physical core execution units (such as floating-point units and vector processing pipelines), scaling from 50 percent to 100 percent utilization typically yields an additional 15 to 30 percent increase in actual throughput rather than a linear 100 percent gain.
AWS Graviton C-Series (C6g, C7g, C8g)
On AWS Graviton-based instances, each vCPU is a physical core with no SMT sharing. Two vCPUs do not compete for the same core pipeline. Consequently, scaling a batch workload up to 100 percent CPU utilization on a Graviton C-series instance exhibits much more linear throughput scaling up to the point of saturation.
Impact on I/O, Networking, and System Agents
Even if a batch job is purely compute-bound, no EC2 instance operates in a complete vacuum. Reaching 100 percent CPU utilization across all vCPUs can starve background processes that are essential for cluster management and data persistence:
- Network and EBS Interrupts: Modern C-series
instances built on the AWS Nitro System offload virtualization and I/O
functions to dedicated hardware, preventing hypervisor steal time
(
%st). However, the guest OS kernel still requires CPU cycles to handle network interrupts (%si/ softirq) and write checkpoints to Amazon EBS. - Orchestration and Monitoring Agents: Background
daemons such as the Amazon ECS agent,
kubelet(on Amazon EKS), AWS Systems Manager Agent (SSM), and CloudWatch agent require small slices of CPU time. If the batch job runs at default or elevated priority and saturates all cores, these agents may fail to respond to heartbeat probes. - False-Positive Instance Failures: If an orchestrator or load balancer health check times out because the OS could not schedule the agent thread in time, the control plane may mark the instance as unhealthy and terminate it mid-job.
Best Practices for Running Batch Jobs at 100% CPU
For batch processing workloads—such as video encoding, financial risk modeling, scientific simulations, or data compression—running near 100 percent CPU utilization is often the goal, as it maximizes cost efficiency per dollar spent on EC2. To maintain stability at maximum load, apply the following practices:
1. Match Worker Threads to vCPU or Physical Core Counts
Configure your batch application thread pool to match the hardware concurrency of the instance. For floating-point-heavy workloads on x86 instances, test whether binding one thread per physical core (\(0.5 \times N_{\text{vCPUs}}\)) completes batches faster than saturating all hyperthreads.
2. Lower the Process Priority of the Batch Job
Use the Linux nice command or cgroups (such
as Kubernetes CPU shares/requests or systemd CPUWeight) to
run the batch worker at a slightly lower scheduling priority than system
daemons:
nice -n 10 ./run-batch-worker --threads $(nproc)This allows the batch job to consume 100 percent of the CPU when nothing else needs it, while guaranteeing that SSH, SSM, monitoring agents, and kernel I/O threads immediately preempt the batch job when they need a few milliseconds of compute time.
3. Monitor Load Average Alongside CPU Utilization
Amazon CloudWatch CPUUtilization tops out at 100
percent, which masks whether your instance is running efficiently with 1
thread per vCPU or thrashing with 50 threads per vCPU. Use the
CloudWatch Agent to collect internal OS metrics—specifically
cpu_usage_iowait, processes_running, and
system load averages (load1, load5,
load15)—to verify that 100 percent utilization reflects
productive compute rather than scheduling bottleneck.