GPU Capacity Planning

GPU capacity planning is harder than CPU capacity planning because the resource is both scarce and workload-shaped. A CPU service usually asks for more cores or more instances. A GPU service has to answer a tighter question:

Which accelerator, in which Region/AZ, at which batch size, for which model, under which latency or training target?

The wrong GPU can be expensive even when it is cheap per hour. A smaller GPU may force low batch sizes, spill to CPU, or fail to fit the model. A larger GPU may cost more per hour but finish the work faster enough to be cheaper per unit of work.

Prerequisites

Workload shapes

GPU demand should be classified before picking an instance type.

Workload shapePrimary metricCommon constraintPlanning question
Online inferencep95/p99 latency, throughput per dollarlatency, memory, queueingHow many requests/tokens can this model serve within the SLO?
Offline / batch inferencerows, images, or tokens per hour per dollarthroughput, input pipeline, memoryWhich GPU completes the backfill cheapest before the deadline?
Trainingtime to useful checkpoint or convergencememory, interconnect, dataloader, optimizer stateWhich cluster shape reaches the target model quality cheapest?
Fine-tuningstep time and time to convergenceactivation memory, optimizer stateCan the model train safely on smaller GPUs, or does it need larger memory?
Experimentationqueue time and iteration speedquota, preemption toleranceShould this run on reserved, on-demand, or spare/preemptable capacity?

The same model can need different capacity for different modes. An instance type that is good for low-latency serving can be a poor training choice if optimizer state and activations do not fit. A GPU that is overkill for one request can be efficient for batched offline inference.

Batch size means different things

For inference, batch size is the number of prompts, images, requests, or tokens grouped into one GPU pass. Larger batches usually improve throughput because the GPU does more parallel work per kernel launch. They can hurt latency because requests wait for the batch to fill or finish.

For training, batch size is the number of examples used for one optimizer step. Larger batches increase activation memory and can change model behavior. When the desired logical batch does not fit in memory, teams may use gradient accumulation: split one logical batch across several smaller GPU passes, accumulate gradients, then run one optimizer step.

Do not compare inference and training batch sizes as if they were the same quantity. They answer different questions.

What to benchmark

GPU right-typing should benchmark the workload’s real shape, not just a synthetic matrix multiply or vendor peak FLOPS (floating-point operations per second) number.

For inference, vary:

  • instance family and GPU generation;
  • model size and memory footprint;
  • precision or quantization;
  • context length / sequence length;
  • inference batch size;
  • concurrency;
  • request mix;
  • input pipeline and CPU preprocessing;
  • latency target.

Measure:

  • requests/sec, rows/sec, images/sec, or tokens/sec;
  • time to first token when serving generated text;
  • p50/p95/p99 latency;
  • cost per million requests or tokens;
  • GPU utilization;
  • GPU memory headroom;
  • CPU memory and CPU saturation;
  • queueing delay.

For training and fine-tuning, vary:

  • training batch size;
  • gradient accumulation steps;
  • precision;
  • checkpoint frequency;
  • dataloader parallelism;
  • number of GPUs per job;
  • single-node vs multi-node layout;
  • interconnect and network placement.

Measure:

  • step time;
  • examples/sec or tokens/sec;
  • time to target quality or convergence;
  • GPU utilization;
  • GPU memory headroom;
  • activation memory;
  • optimizer-state memory;
  • dataloader throughput;
  • checkpoint overhead;
  • network bandwidth and all-reduce time (time spent combining gradients across GPUs) for distributed jobs.

Decision rule

Pick the instance type using cost per unit of useful work:

inference_cost = cost_per_hour / useful_inferences_per_hour
training_cost  = cost_per_hour * hours_to_target_checkpoint

The cheap hourly instance loses if it needs many more nodes, runs smaller batches, misses the latency target, or fails from CPU/memory bottlenecks. The expensive hourly instance wins if it reduces total nodes, finishes sooner, or keeps enough memory headroom to avoid retries and operational churn.

The benchmark must show both cost and constraint:

ClaimEvidence needed
”This GPU is cheaper”Cost per unit of work, not hourly rate
”This GPU is fast enough”p95/p99 latency or training step/convergence time
”This GPU fits”Model weights + activations + KV cache (transformer key/value cache) / optimizer state + headroom
”This fleet is reliable”Capacity availability, fallback shape, quota, and reservation plan

Capacity procurement

GPU planning has longer lead times than ordinary CPU planning because supply is thin and provider-specific. The capacity request should state:

  • workload type: inference, training, fine-tuning, evaluation, experimentation;
  • model or model family;
  • instance type candidates;
  • count and duration;
  • Region/AZ constraints;
  • required start date;
  • fallback instance types;
  • whether queueing, lower batch size, lower context length, or degraded model quality is acceptable;
  • whether capacity must be reserved or can run opportunistically.

The capacity decision and the right-typing decision interact. Benchmarking may show that one GPU is best, but the provider may not have enough of it in the needed AZ. A practical plan includes the preferred shape and fallback shapes.

Failure modes

Failure modeWhat it looks likeFix
Benchmark ignores batch sizeFleet looks expensive after launchRe-run with realistic inference/training batches
Benchmark ignores CPU/input pipelineGPU appears underutilizedMeasure CPU memory, dataloading, preprocessing, and queueing
Chosen GPU barely fitsSmall model or context change causes OOMKeep explicit GPU memory headroom
Capacity request arrives lateProvider cannot deliver scarce GPUsForecast earlier or choose fallback families
Quota exists but nodes do notJobs are admitted but cannot scheduleReconcile quota with physical supply and reservations
Reservation exists but workload misses itReserved GPUs sit idle while on-demand launches elsewhereFix targeting, resource groups, scheduler integration, or labels

See also