“What’s the memory bandwidth on a DGX Spark?” is the wrong first question. The honest answer is another question: which bandwidth, and for which kernels? A single GB/s figure on a spec sheet tells you almost nothing about whether your workload will run at 30% or 80% of the box’s headline number — and that gap is the difference between a machine that fits your problem and a capital commitment you regret after the code is written. The naive read treats memory bandwidth as a scalar you compare across boxes, the way you’d compare clock speeds. The expert read treats it as a structural property of the memory subsystem that interacts with the shape of your workload. On a DGX Spark, with its unified LPDDR5X memory feeding a tightly coupled CPU-GPU fabric, that interaction is more consequential than on a discrete-GPU box, not less — because the memory model your kernels see is genuinely different, and code written against the wrong mental model does not port cleanly to it. Which bandwidth are you actually asking about? There is no single “the bandwidth.” A DGX Spark, like any modern accelerated system, exposes a hierarchy of memory paths, and each has a different ceiling. The one printed on the marketing page is the aggregate system-memory bandwidth — the rate at which the unified LPDDR5X pool can feed the fabric. That is the number that matters when a kernel streams large tensors that don’t fit in cache. It is not the number a kernel sees when it’s hitting on-die SRAM, shared memory, or register-resident data. The distinction matters because different kernels live in different parts of that hierarchy. An attention kernel that keeps its working set resident in on-chip memory is limited by a bandwidth figure that never appears on any spec sheet. A large-context inference pass that must repeatedly re-read a multi-gigabyte KV cache is limited by the system-memory figure — and will get nowhere near the compute peak. Reading a single GB/s number and assuming it governs your whole workload is like reading a CPU’s peak FLOPS and assuming your branch-heavy code will hit it. Unified memory changes the shape of this problem rather than removing it. The absence of a discrete PCIe hop between host and device removes one class of bottleneck — the staging copy — but it does not make the LPDDR5X pool infinitely fast. What it does is make the same pool serve both CPU-side preprocessing and GPU-side compute, which means contention becomes a first-class concern. We treat unified-memory contention the same way we’d treat a shared NUMA domain: something to profile, not assume away. The mechanics of that shared address space are worth understanding directly, which is why we cover how unified virtual memory works and what it means for GPU inference as a companion piece. Compute-bound or memory-bound: the question that decides everything Every kernel sits somewhere on a spectrum defined by its arithmetic intensity — the ratio of floating-point operations performed to bytes moved from memory. This is the single most useful number for reasoning about DGX Spark bandwidth, and it is almost never on the spec sheet. A kernel with high arithmetic intensity does a lot of math per byte fetched. Dense matrix multiplication at large tile sizes is the canonical example: fetch a block, reuse it many times, amortise the memory cost. These kernels are compute-bound, and they benefit from FLOP headroom. A kernel with low arithmetic intensity — elementwise operations, layer norm, the KV-cache reads in autoregressive decode — moves a lot of bytes per flop. These kernels are memory-bound, and no amount of FLOP headroom helps them. They saturate the memory subsystem and stall while the arithmetic units sit idle. The roofline model formalises this: plot arithmetic intensity on the x-axis and achievable throughput on the y-axis, and you get a “roof” that rises with intensity until it hits the compute ceiling and then flattens. Where your kernel lands under that roof tells you which ceiling you’re hitting. This is not exotic — it’s the same discipline that makes reading peak versus achieved throughput on an inference path tractable rather than mystifying. A workload characterised by arithmetic intensity before hardware commitment is a workload you can size honestly. A worked example with explicit assumptions Suppose you’re serving a large-context transformer and want to know, before buying, whether a DGX Spark’s memory bandwidth is your ceiling. Assume, for illustration, a system-memory bandwidth of B GB/s and a decode step that must re-read a KV cache of K gigabytes per token generated (the numbers are illustrative — substitute your own measured cache size and the box’s published bandwidth). Bytes moved per token ≈ K GB (KV read) plus weight streaming if weights don’t stay resident. Memory-bound token rate ≈ B / K tokens per second — this is a ceiling imposed purely by bandwidth, independent of how many FLOPS the GPU can do. If your target token rate is below that ceiling, compute or scheduling is your constraint. If it’s above, you are memory-bound and a bigger FLOP number will not save you. The point of the arithmetic isn’t the exact figure — it’s that the ceiling is computable from published specs plus one measured quantity (your cache footprint), before any capital is committed. That is the whole ROI argument: knowing you’ll run at 30% of peak rather than 80% is a decision you can make on paper. Which workloads hit the bandwidth wall? Not every workload is bandwidth-limited on a DGX Spark, and treating them all the same wastes the machine either way. The table below maps common workload classes to their dominant constraint. Evidence class for the constraint column is observed-pattern — these are the patterns we see across GPU-optimisation engagements, not a published benchmark of this specific box. Workload class Dominant constraint Why Large-context autoregressive decode Memory bandwidth KV-cache re-reads per token; low arithmetic intensity Batch prefill / prompt processing Compute Large dense GEMMs; high arithmetic intensity, reuses fetched data Small-batch, low-latency inference Memory bandwidth Weights streamed per request without amortisation Large-batch throughput serving Mixed → compute as batch grows Batching raises arithmetic intensity of the GEMMs Training (backward pass) Mixed Gradient/activation movement is heavy, but large GEMMs offset it Fine-tuning with large activations Memory bandwidth (capacity + BW) Activation footprint stresses the unified pool The pattern worth internalising: prefill is usually compute-bound, decode is usually memory-bound, and the same model can therefore be limited by different ceilings at different phases of the same request. This is exactly why disaggregating those phases has become a serving technique — the two halves want different hardware profiles. If you’re serving at scale, the reasoning behind separating prefill and decode for GPU throughput is the operational corollary of this bandwidth analysis. How does bandwidth planning connect to your compute API and roadmap? Reading bandwidth correctly is not a one-off procurement exercise; it shapes the code you write. If you commit to a DGX Spark on FLOP figures alone and then write kernels against an implicit memory model — assuming, say, that a fetched tile stays cheap to re-read — you produce code whose performance is silently pinned to this box’s memory hierarchy. Move it to a discrete-GPU system with a different cache-to-HBM ratio, or to an edge target with a fraction of the bandwidth, and the assumptions break in ways that don’t show up until you profile. This is the same failure class we see in CUDA lock-in: a workload tuned for one memory model that doesn’t survive the move to another. Treating bandwidth as a structural property — the way you’d treat a compute API’s execution model — keeps the code honest across targets. It’s why the decision to fit hardware to a workload sits alongside decisions like porting a GPU inference path off CUDA lock-in: both are about not baking a single box’s characteristics into code you’ll want to move. For a full picture of where the DGX Spark’s bandwidth sits relative to its other trade-offs, and where the box fits an on-premise inference strategy, our broader GPU engineering and performance work is the anchor. Characterising a workload’s arithmetic intensity before committing to hardware is the input that turns a spec-sheet comparison into an engineering decision. FAQ What should you know about NVIDIA DGX Spark memory bandwidth in practice? The DGX Spark uses a unified LPDDR5X memory pool that feeds a coupled CPU-GPU fabric, so there is no discrete PCIe staging copy between host and device. In practice, the headline GB/s figure describes the rate at which that pool can stream large tensors, but your kernels experience a hierarchy of bandwidths depending on whether their working set lives in on-chip memory or the shared pool. What it means practically is that the single spec-sheet number governs only your bandwidth-bound kernels, not your whole workload. What is the difference between the DGX Spark’s unified system-memory bandwidth and the bandwidth a GPU kernel actually sees? System-memory bandwidth is the aggregate rate of the LPDDR5X pool — the ceiling for kernels that stream data too large to keep on-chip. A kernel that keeps its working set resident in shared memory or registers is limited by on-die paths that never appear on any spec sheet and are far faster. The gap means a favourable system-bandwidth figure can coexist with a kernel that’s actually limited by something else entirely, in either direction. How do I tell whether my workload is compute-bound or memory-bound on a DGX Spark before committing to the hardware? Compute the arithmetic intensity of your dominant kernels — floating-point operations per byte moved — and place it on a roofline against the box’s published bandwidth and FLOP ceilings. High intensity (large dense GEMMs) lands you compute-bound; low intensity (KV-cache reads, elementwise ops) lands you memory-bound. You can estimate the memory-bound ceiling from published bandwidth plus one measured quantity like your cache footprint, entirely on paper before purchase. Which workload classes are limited by DGX Spark memory bandwidth rather than compute? Large-context autoregressive decode, small-batch low-latency inference, and fine-tuning with large activation footprints are typically bandwidth-limited because they move many bytes per flop. Batch prefill, prompt processing, and large-batch throughput serving are usually compute-bound because batching raises arithmetic intensity and amortises fetched data. The same model can be compute-bound during prefill and memory-bound during decode — a distinction driving prefill/decode disaggregation. How does memory-bandwidth planning connect to my choice of compute API and long-term hardware roadmap? If you tune kernels to an implicit memory model, their performance becomes silently pinned to that box’s cache-to-memory ratio and won’t port to a discrete GPU or an edge target without breaking. Treating bandwidth as a structural property — like a compute API’s execution model — keeps code honest across targets. This is the same failure class as CUDA lock-in: a workload tuned for one hardware profile that doesn’t survive the move. What percentage of peak throughput should I realistically expect from a memory-bound workload on DGX Spark? For a genuinely memory-bound kernel, achieved compute throughput as a percentage of theoretical FLOP peak can sit well below the headline number — the arithmetic units stall waiting on memory. The honest expectation is set by arithmetic intensity: the more bytes moved per flop, the further below peak you’ll run. The useful outcome is knowing whether that figure is closer to 30% or 80% before you commit capital, which the roofline analysis gives you on paper. The real discipline here isn’t chasing a bigger GB/s number — it’s refusing to spec hardware before you know which ceiling your kernels hit. A workload flagged as memory-bound on the target box, using arithmetic intensity, is exactly the input a GPU performance audit turns into a defensible hardware decision rather than a spec-sheet guess.