A CUDA Graph is a representation of a sequence of dependent GPU operations—including kernel launches and memory copies—that can be captured as a single, reusable unit of work. This graph structure is defined once and then launched repeatedly with minimal driver overhead, eliminating the latency of individual kernel submissions and enabling highly predictable, low-latency execution. It is a foundational technique for hardware-aware model optimization on NVIDIA GPUs.
Glossary
CUDA Graph

What is CUDA Graph?
A definition of CUDA Graph, a core NVIDIA technology for minimizing CPU overhead in GPU workloads.
The primary benefit is the drastic reduction of CPU involvement during launch. Instead of the driver managing each operation separately, the entire pre-defined workflow is executed by the GPU's hardware scheduler. This is critical for latency-sensitive inference and tight loops in high-performance computing. CUDA Graphs integrate with frameworks like TensorRT and PyTorch to accelerate neural network execution by capturing and optimizing entire model forward passes.
Key Features of CUDA Graphs
CUDA Graphs capture a sequence of dependent GPU operations (kernels and memory copies) into a single, reusable unit of work. This eliminates the driver overhead of individual launches, providing deterministic, low-latency execution.
Single Launch Overhead
A primary benefit of CUDA Graphs is the elimination of repeated launch overhead. In a traditional CUDA workflow, each kernel launch or memory copy requires CPU intervention to manage the driver API, incurring latency. A CUDA Graph captures the entire workflow once. Subsequent executions launch the entire pre-defined graph with a single, low-latency CPU call (cudaGraphLaunch), bypassing the driver for each individual operation. This is critical for latency-sensitive applications like real-time inference.
Graph Capture and Instantiation
The workflow involves two distinct phases:
- Capture: The application executes its normal CUDA sequence (using streams, events, and kernels) within a capture scope (
cudaStreamBeginCapture/cudaStreamEndCapture). The CUDA driver records the kernels, dependencies, and parameters into a cudaGraph_t object. - Instantiation: The captured graph is instantiated into an executable form (
cudaGraphInstantiate). This process validates the graph and creates a cudaGraphExec_t object, which is the launchable entity. Instantiation has a one-time cost; the executable graph can be launched thousands of times with minimal overhead.
Parameter Updating with Graph Nodes
CUDA Graphs support efficient updates without re-capturing the entire graph. Kernel node parameters (e.g., pointers to input data) and memory copy node parameters can be updated in the executable graph (cudaGraphExecKernelNodeSetParams, cudaGraphExecMemcpyNodeSetParams). This allows the graph structure (the dependency graph) to remain static while dynamic data pointers or copy sizes can be modified. This is essential for batched inference where the model architecture is fixed, but input data changes per batch.
Conditional and Event-Based Graph Nodes
Advanced graph features enable dynamic control flow within the static graph structure:
- Conditional Nodes: Allow a subgraph to execute based on a runtime value computed on the device, enabling if-then-else logic within the graph.
- Event Record/Wait Nodes: Enable synchronization points within the graph, allowing parts of the graph to wait for an event recorded earlier in the same graph or in an external stream. This facilitates complex, inter-stream dependencies while maintaining the single-launch benefit.
Overlap and Dependency Optimization
During capture, the CUDA driver analyzes the true dependencies between operations. When instantiated and launched, the runtime can schedule independent kernels and memory copies with maximal overlap, often achieving better utilization than manually managed streams. The graph's internal scheduler has a complete, global view of all work, allowing for optimizations that are difficult to orchestrate manually. This reduces bubbles in the GPU's execution pipeline.
How CUDA Graph Works
CUDA Graph is a performance optimization technique in NVIDIA's CUDA platform that captures a sequence of GPU operations into a single, reusable unit of work.
A CUDA Graph is a recorded sequence of dependent GPU operations—including kernel launches and memory copies—that is captured once and can be launched repeatedly as a single unit. This eliminates the overhead of individual CPU-driven kernel launches and API calls, drastically reducing latency for repetitive workloads. The graph structure allows the CUDA driver to see the entire workflow upfront, enabling deep optimizations in scheduling and resource management.
The workflow involves a capture phase, where operations are recorded into a graph object, followed by an instantiation into an executable graph. Once instantiated, the graph can be launched with minimal host-side overhead, often using a single API call. This is particularly powerful for inference servers and tight loops where the same operations are executed repeatedly on different input data, shifting the performance bottleneck from CPU dispatch to pure GPU execution.
CUDA Graph vs. Standard Kernel Launch
A direct comparison of the execution model, CPU overhead, and performance characteristics between traditional CUDA kernel launches and the CUDA Graph optimization technique.
| Feature / Metric | Standard Kernel Launch | CUDA Graph |
|---|---|---|
Execution Model | Individual, imperative launches via runtime API (e.g., cudaLaunchKernel) | Single, pre-defined graph of operations launched as one unit |
CPU Overhead per Launch | High (Driver call, argument marshaling, scheduling) | Minimal to zero (Launch is a single driver call for the entire graph) |
Kernel Launch Latency | Present for every kernel | Eliminated after initial capture; only graph launch latency remains |
Synchronization Overhead | High (Frequent cudaStreamSynchronize or device synchronize calls) | Low (Implicit dependencies encoded in graph; fewer sync points needed) |
Memory Copy Overhead | Individual cudaMemcpyAsync calls with launch overhead | Memory copies are nodes in the graph; overhead eliminated after capture |
Optimal Use Case | Dynamic workloads with changing execution paths | Static, repetitive sequences of kernels and memory operations |
Runtime Flexibility | High (Kernel parameters and launch configuration can change each call) | Low (Graph is static; parameters can only be updated via node-specific APIs) |
Performance Benefit | Baseline | Up to 20-30% reduction in end-to-end latency for graph-compatible workloads |
Primary Use Cases for CUDA Graphs
CUDA Graphs capture a sequence of GPU operations (kernels, memory copies) into a single, reusable unit of work. This eliminates the per-launch CPU overhead inherent in the standard CUDA launch API, providing deterministic, low-latency execution for repetitive workloads.
Iterative Algorithm Kernels
Many numerical algorithms (e.g., solvers, simulations, physics engines) consist of tight loops where the same kernel pattern executes thousands of times with slightly varying parameters. Examples include:
- Jacobi or Gauss-Seidel iterative solvers
- Conjugate Gradient methods
- Monte Carlo simulation steps Capturing this loop body as a graph eliminates the launch latency for every iteration. The graph is launched repeatedly from the GPU, with parameters updated via graph node updates or user-defined graph nodes, minimizing CPU involvement and maximizing GPU utilization.
Reducing Jitter in Real-Time Systems
Applications with strict real-time constraints, such as autonomous vehicle perception pipelines, robotic control loops, or high-frequency trading signal processing, cannot tolerate variable execution latency (jitter). The standard CUDA launch path involves unpredictable CPU scheduling and driver queue management. By using a pre-compiled CUDA Graph, the entire computational pipeline is submitted to the GPU as one atomic unit. This bypasses much of the driver's runtime scheduling, yielding sub-millisecond, deterministic launch times essential for hard real-time systems.
Overlapping Complex Multi-Stage Pipelines
Advanced workloads like training or graphics rendering involve complex, staged pipelines with dependencies. Manually managing streams and events for overlap is error-prone. CUDA Graphs excel here by allowing the capture of an entire, dependency-resolved workflow spanning multiple CUDA streams. The graph's internal representation explicitly encodes kernel concurrency and memory copy dependencies. When launched, the GPU scheduler executes this pre-defined, optimal schedule every time, ensuring maximum hardware occupancy and efficient overlap of computation and data movement without runtime CPU analysis.
Microbenchmarking & Profiling
When profiling GPU kernel performance, the goal is to measure the true GPU execution time, isolated from CPU launch overhead and driver noise. Using CUDA Graphs provides a "clean" measurement by:
- Eliminating launch latency from the timed region.
- Ensuring identical execution traces across multiple runs for consistent results.
- Allowing precise measurement of kernel fusion benefits by capturing fused and unfused operation sequences in separate graphs for direct comparison. This is invaluable for performance architects optimizing low-level kernels.
Dynamic Shape Workloads with Conditional Execution
While graphs are static, they support controlled dynamism for variable input sizes or conditional paths. Using graph node update APIs (e.g., cudaGraphExecKernelNodeSetParams), kernel parameters can be modified between launches. For conditional logic, conditional nodes or user-defined nodes can be embedded within the graph at capture time. This allows a single graph to handle a family of related workloads—like processing images of different resolutions or executing different model branches based on input—while still retaining most of the launch overhead benefits. The key is that the graph structure (the nodes and their dependencies) remains fixed.
Frequently Asked Questions
CUDA Graphs are a core NVIDIA technology for minimizing CPU overhead in GPU workloads by capturing and replaying sequences of operations. These questions address its core mechanics, benefits, and practical applications.
A CUDA Graph is a representation of a sequence of GPU operations—including kernel launches and memory copies—that can be captured once and launched repeatedly as a single unit with minimal CPU overhead. It works by recording the dependency graph of operations during an initial execution phase. Instead of the CPU issuing individual API calls for each kernel and memory transfer for every iteration, the runtime captures the entire workflow's structure and parameters. This captured graph is then instantiated and can be launched with a single cudaGraphLaunch call. The CUDA driver executes the entire pre-defined sequence directly, bypassing the per-kernel driver overhead and enabling more efficient GPU utilization by reducing latency and improving submission throughput.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
CUDA Graphs are a key technique for minimizing CPU overhead in GPU workloads. The following concepts are foundational to understanding its role within the broader ecosystem of hardware-aware compilation and execution.
Graph Compilation
Graph Compilation is the overarching process of transforming a high-level neural network computational graph into an optimized, hardware-specific sequence of low-level operations. This involves several stages:
- Operator Lowering: Decomposing framework-specific layers (e.g., a PyTorch
Conv2d) into primitive tensor ops. - Graph Optimization: Applying transformations like operator fusion, constant folding, and dead code elimination.
- Schedule Generation: Determining the precise order and parallel execution strategy for kernels. A CUDA Graph is the final, captured output of this process for NVIDIA GPUs—a static, executable representation of the optimized graph.
Operator Fusion
Operator Fusion is a critical compiler optimization that merges multiple sequential operations into a single, fused kernel. This is a primary optimization performed before CUDA Graph capture.
- Mechanism: Combines ops like Convolution, BatchNorm, and ReLU activation to create a single kernel.
- Benefit: Dramatically reduces kernel launch overhead and minimizes costly round-trips to global memory for intermediate results.
- CUDA Graph Role: The fused kernel sequence is captured as a single node in the graph. This eliminates the per-launch latency for each individual operation, compounding the performance gains of fusion.
Just-In-Time (JIT) Compilation
Just-In-Time (JIT) Compilation is a strategy where code is compiled into machine instructions at runtime. This contrasts with the Ahead-Of-Time (AOT) approach used for CUDA Graphs.
- JIT (e.g., PyTorch Eager Mode): Each operation is dispatched individually, with drivers compiling kernels on-the-fly. This introduces overhead on every launch.
- AOT / CUDA Graph: The entire workflow is compiled and captured once. The resulting graph is launched repeatedly with near-zero CPU overhead.
- Trade-off: JIT offers dynamic flexibility, while CUDA Graphs provide maximal performance for static, repeatable workloads.
Kernel Launch Overhead
Kernel Launch Overhead refers to the latency incurred by the CPU driver stack each time it schedules a GPU kernel for execution. This overhead is the primary problem CUDA Graphs solve.
- Components: Includes argument marshaling, kernel validation, security checks, and scheduling onto the GPU's command queue.
- Impact: For workloads comprising many small kernels (common in machine learning), this overhead can dominate total execution time.
- CUDA Graph Solution: By capturing the entire sequence into a graph, the launch overhead is paid once during capture. Subsequent graph launches replay the pre-validated, scheduled sequence with minimal CPU involvement.
Command Buffer & Replay
A CUDA Graph is fundamentally a recorded command buffer that can be replayed. This is its core execution mechanism.
- Capture Phase: All GPU operations (kernels, memory copies) are recorded into a graph object, creating a dependency-ordered command buffer.
- Graph Instantiation: The captured graph is instantiated into an executable graph, which is a hardened, ready-to-run form.
- Replay Phase: Launching the graph submits the entire pre-recorded command buffer to the GPU in a single, low-latency operation. The GPU driver replays the commands directly, bypassing the standard per-kernel launch pipeline.
Static vs. Dynamic Graph
CUDA Graphs represent a static graph execution paradigm, which differs from frameworks that use dynamic graphs.
- Dynamic Graph (Eager Mode): The execution graph is built on-the-fly by interpreting Python code. Operations are dispatched immediately, allowing for flexible control flow (e.g.,
ifstatements). - Static Graph (CUDA Graph): The entire execution path must be known and fixed at capture time. Control flow must be unrolled, and tensor shapes must be constant.
- Optimization Implication: The static nature is what enables aggressive whole-program optimization, kernel fusion, and the elimination of launch overhead, but it requires the workload to be predictable and repeatable.

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us