Karya Semi
HomeBlogSearchCategoriesAboutContact
Karya Semi

Less noise. More notes.

HomeBlogAboutContactPrivacy PolicyDisclaimer

© 2026 Karya Semi. All rights reserved.

XGitHubLinkedIn
  1. Home
  2. /Categories
  3. /Software Engineering

Scaling AI Workloads in Modern Infrastructure Engineering

Optimize AI pipelines. Use ai infrastructure engineering patterns to scale workloads, manage GPU clusters, and solve operational bottlenecks.

Dian Rijal Asyrof/August 28, 2026/7 min read
Illustration for Scaling AI Workloads in Modern Infrastructure Engineering

Moving AI workloads from development notebooks to production environments changes the infrastructure equation. Traditional web applications are generally I/O bound, spending most of their lifecycle waiting for database queries or network calls. AI workloads are different. They are compute-bound, memory-bound, and highly sensitive to hardware latency.

If you run large language models (LLMs) or diffusion models using the same patterns as traditional HTTP endpoints, your cluster will face runaway costs—often because teams fail to budget for the real cost structure of AI agents—GPU starvation, and cascading timeouts. As teams shift to engineering for the agentic era, managing these pipelines at scale requires restructuring your compute, storage, and networking layers.

The Compute Bottleneck: GPU Scheduling and Resource Allocation

GPUs are scarce resources. Leaving them idle is a waste of capital. Kubernetes is the standard for orchestration, but its default scheduler treats GPUs as binary resources. A container gets one GPU or zero.

This approach fails for mixed workloads. A lightweight embedding model does not need an entire physical GPU. It needs a fraction of it.

To share GPU resources, you have three primary options:

First, time-slicing. Multiple containers share the GPU by taking turns. The driver switches context between them. This is simple to set up but introduces latency spikes. If one container starts a heavy computation, other containers must wait.

Second, Multi-Instance GPU (MIG). This technology splits a single physical GPU into independent instances at the hardware level. Each instance has its own dedicated memory and compute cores. If one instance runs out of memory, it does not crash the others. This provides clean hardware-level isolation.

Third, virtual GPUs (vGPU). This is software-based sharing. It allows flexible allocations, but it lacks strict memory isolation. A bad query on one container can degrade performance for everyone else on the same physical card.

For production APIs with strict SLAs, MIG is the safest choice.

Here is a Kubernetes pod spec using fractional GPU resources via the NVIDIA device plugin:

apiVersion: v1
kind: Pod
metadata:
  name: embedding-service
spec:
  containers:
  - name: predictor
    image: embedding-model:v1
    resources:
      limits:
        nvidia.com/mig-1g.10gb: 1

This requests a specific MIG profile instead of the whole GPU.

Handling GPU Starvation and Queuing

When traffic spikes, you cannot spin up ten more GPU nodes instantly. Cold starts for GPU instances take minutes. You need a queue.

Instead of letting HTTP requests pile up at the API gateway, route them to a message broker like RabbitMQ or Redis. The worker pool pulls jobs from the queue based on GPU availability.

If your workers process jobs faster than the queue grows, the system remains stable. If the queue builds up, you trigger autoscaling. You scale the queue consumers, not the HTTP endpoints.

This pattern decouples client requests from GPU execution. If a GPU node dies, the request remains in the queue. The client gets a pending status instead of a gateway timeout.

Mitigating the Storage Bottleneck

GPUs process data at extreme speeds. If your storage layer cannot feed data to the GPU fast enough, the processor sits idle. This state is called GPU starvation. It is a common cause of wasted cloud spend.

Standard cloud object storage is too slow for direct access within the execution loop. Downloading a 50GB dataset or model checkpoint over the network at runtime introduces massive latency.

Implement a multi-tiered caching strategy. Use fast local NVMe drives attached to the GPU instances as scratch space. Before starting a training job or serving a model, run a pre-start script to pull the weights or data blocks from object storage to the local NVMe disk.

If you scale across multiple nodes, look at distributed file systems like JuiceFS or SeaweedFS. These platforms cache metadata and frequently accessed data blocks on local SSDs while using object storage as the source of truth.

Here is an initialization script for a container to pull model weights locally before starting the main process:

#!/usr/bin/env bash
set -euo pipefail
 
WEIGHTS_DIR="/mnt/nvme/models/llama-3-8b"
S3_URI="s3://my-model-registry/llama-3-8b"
 
if [ ! -d "$WEIGHTS_DIR" ]; then
  echo "Local cache miss. Downloading weights from storage bucket..."
  mkdir -p "$WEIGHTS_DIR"
  aws s3 sync "`S3_URI" "`WEIGHTS_DIR" -quiet
else
  echo "Local cache hit. Model weights are ready."
fi
 
exec python3 -m vllm.entrypoints.openai.api_server -model "$WEIGHTS_DIR"

This script ensures the application server only starts once the weights are locally cached, avoiding runtime network latency.

LLM Serving: Prefill, Decode, and Dynamic Batching

Serving LLMs requires a different approach than traditional REST APIs. An LLM request has two distinct phases.

The prefill phase processes the input prompt. This is compute-bound. The engine processes all input tokens in parallel.

The decode phase generates the output tokens. This is memory-bandwidth bound. The engine generates one token at a time. To generate token N, the engine must load the entire model weights and the key-value (KV) cache of all previous tokens into SRAM.

Because of this, processing requests one by one is highly inefficient. The GPU spends most of its time waiting for memory transfers.

To solve this, use dynamic batching. Instead of waiting for a batch to fill, the inference engine groups incoming requests on the fly. If Request A is mid-generation and Request B arrives, the engine inserts Request B into the next iteration of the decode loop. This is known as continuous batching or iteration-level scheduling.

Engines like vLLM, TensorRT-LLM, and Triton implement this pattern.

Dynamic batching increases the time-to-first-token (TTFT) for incoming requests if the queue is full. You must balance throughput and latency. Set a maximum batch size and a timeout threshold to prevent requests from waiting too long in the scheduler.

Model Quantization and VRAM Optimization

Model size directly dictates your infrastructure requirements. A 70B parameter model stored in FP16 (16-bit floating-point) requires roughly 140 GB of VRAM just to load the weights. Add the KV cache for concurrent users, and you need multiple high-end GPUs just to run a single replica.

Quantization reduces the precision of the model weights, shrinking the memory footprint. Common formats include INT8, INT4, AWQ, and GPTQ.

Quantizing a model to 4-bit precision reduces the memory requirement by nearly 75%. The 70B model now fits into a single 40GB or 48GB GPU. This reduction lowers your hardware costs.

Quantization can degrade model accuracy slightly. Test your models against evaluation benchmarks after quantization to ensure the performance drop is acceptable for your use case.

Event-Driven Autoscaling with KEDA

Traditional autoscalers use CPU or memory utilization to scale instances. This does not work for GPU workloads. A GPU running inference will show high VRAM usage even when idle because the runtime reserves memory beforehand. CPU usage remains low because the heavy lifting happens on the GPU cores.

To scale accurately, you must monitor queue depth. If requests are piling up in your message broker, you need more workers.

Use Kubernetes Event-driven Autoscaling (KEDA) to scale your deployments based on external metrics. Here is a KEDA ScaledObject configuration that scales a GPU worker pool based on the number of pending tasks in a Redis queue:

apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: gpu-inference-scaler
  namespace: ai-workloads
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: gpu-worker
  minReplicaCount: 1
  maxReplicaCount: 10
  cooldownPeriod: 300
  triggers:
  - type: redis
    metadata:
      address: redis-master.default.svc.cluster.local:6379
      listName: inference_jobs
      listLength: "5"

This configuration adds worker pods when the number of jobs in the inference_jobs list exceeds 5 per active pod. The cooldownPeriod is set to 300 seconds (5 minutes) to prevent thrashing, where nodes are repeatedly created and destroyed due to brief traffic spikes.

Observability: Metrics that Matter

Monitoring AI infrastructure requires looking beyond basic system metrics. You must collect metrics from the GPU driver level and the inference engine itself.

Key infrastructure metrics:

  • GPU Compute Utilization: The percentage of time the GPU kernels were active.
  • VRAM Allocation: The amount of memory reserved vs. actually used.
  • PCIe Bandwidth: The data transfer rate between the CPU host and the GPU. High PCIe utilization indicates that data transfers are bottlenecking your pipeline.

Key application metrics:

  • Time to First Token (TTFT): The latency between sending the request and receiving the first generated token. This measures how fast your system handles the prefill phase.
  • Time Per Output Token (TPOT): The average time to generate each subsequent token. This measures the efficiency of your decode phase.
  • KV Cache Usage: The percentage of memory allocated for storing token history. If this hits 100%, the engine will pause requests or drop them.

Use the NVIDIA DCGM Exporter to scrape GPU metrics and expose them to Prometheus. Combine these with engine-level metrics to build a complete dashboard.

Multi-Node Networking: Infiniband and RoCE

When scaling large training runs or running massive models that do not fit on a single node, you must distribute the workload across multiple servers. This setup requires high-speed communication between GPUs on different nodes.

Standard Gigabit Ethernet is too slow and introduces too much latency. You need specialized networking hardware.

Infiniband is the industry standard for low-latency, high-throughput clustering. It bypasses the host operating system's network stack using Remote Direct Memory Access (RDMA), allowing GPUs to read and write directly to the memory of remote GPUs.

RDMA over Converged Ethernet (RoCE) is an alternative that runs RDMA over standard Ethernet infrastructure. Setting up RoCE requires configuring your network switches to support lossless Ethernet, which is complex but cheaper than deploying dedicated Infiniband hardware.

Without these protocols, multi-node scaling efficiency drops rapidly. The GPUs spend more time waiting for network packets than running computations.

Cost Containment and Spot Instance Lifecycle Management

Running GPU clusters 24/7 is financially draining. To keep costs manageable, you must implement strict lifecycle policies.

Use spot instances (or preemptible VMs) for non-critical workloads like batch processing, model training, and offline evaluation. Spot instances offer discounts up to 80% compared to on-demand pricing.

But they can be reclaimed by the cloud provider at any time, often with only a 30-second to 2-minute warning. To handle this, your applications must be resilient to sudden termination.

For training jobs, implement automated checkpointing. Save the model state to shared storage or object storage at regular intervals.

Use a node termination handler in your Kubernetes cluster. This agent listens for the cloud provider's termination signal and immediately drains the node, allowing the scheduler to reschedule the pod on a warm node before the hard shutdown occurs.

For serving workloads, you cannot rely entirely on spot instances due to latency and availability risks. Instead, use a hybrid node pool. Keep a baseline of on-demand instances to handle minimum traffic, and scale up using spot instances during peak hours. If the spot instances are reclaimed, the on-demand instances keep the service running while the system provisions new nodes.

DR

Dian Rijal Asyrof

Writes about useful AI tools, programming practice, and the craft of building reliable software.

Previous articleImproving LLM Code Generation Quality using agent.mdNext articleAutopsy of an LLM Agent Infinite Loop: 245 Retries Burned on Hallucinated Request
InfrastructureAI EngineeringScalingLLMsLLM
On this page↓
  1. The Compute Bottleneck: GPU Scheduling and Resource Allocation
  2. Handling GPU Starvation and Queuing
  3. Mitigating the Storage Bottleneck
  4. LLM Serving: Prefill, Decode, and Dynamic Batching
  5. Model Quantization and VRAM Optimization
  6. Event-Driven Autoscaling with KEDA
  7. Observability: Metrics that Matter
  8. Multi-Node Networking: Infiniband and RoCE
  9. Cost Containment and Spot Instance Lifecycle Management

On this page

  1. The Compute Bottleneck: GPU Scheduling and Resource Allocation
  2. Handling GPU Starvation and Queuing
  3. Mitigating the Storage Bottleneck
  4. LLM Serving: Prefill, Decode, and Dynamic Batching
  5. Model Quantization and VRAM Optimization
  6. Event-Driven Autoscaling with KEDA
  7. Observability: Metrics that Matter
  8. Multi-Node Networking: Infiniband and RoCE
  9. Cost Containment and Spot Instance Lifecycle Management

See also

Illustration for Breakdown of Modern AI Chip Architectures
Technology/Aug 28, 2026

Breakdown of Modern AI Chip Architectures

Evaluate memory bandwidth, compute tradeoffs, and silicon design in modern ai chip architectures hardware. Optimize next-gen accelerators for AI workloads.

7 min read
ChipsChip
Illustration for Improving LLM Code Generation Quality using agent.md
Programming/Aug 28, 2026

Improving LLM Code Generation Quality using agent.md

Define agent md llm context to standardize repo rules. Stop AI code hallucinations, boost output accuracy, guide coding assistants.

5 min read
AI CodingLLMs
Illustration for Ramp Releases Unified API Router for Dynamic LLM Switching
AI/Aug 22, 2026

Ramp Releases Unified API Router for Dynamic LLM Switching

Integrate ramp ai model router to swap LLM providers dynamically. Optimize cost and latency via unified API. Switch models instantly in production.

7 min read
LLMsLLM