The Cheapest CUDA GPU on AWS Has an Arm CPU — and You Probably Want the Intel One A developer's benchmark of the two cheapest CUDA GPU instances on AWS reveals that while the Arm-based g5g.xlarge is 20% cheaper per hour than the Intel-based g4dn.xlarge, the Intel instance is more cost-effective for token generation due to a packaging issue in vLLM's Docker images. The arm64 image lacks SM 7.5 kernels, forcing a source build that adds overhead, whereas the amd64 image includes precompiled kernels for the T4 GPU. This article provides a step by step deployment guide for Gemma 4 E2B onto the two cheapest whole GPU CUDA instances AWS sells, and compares what they cost to run. A suite of Python MCP tools is built to simplify management of the vLLM hosted deployment. Everything was measured on 2026-08-30. The question is simple: if you want a CUDA GPU on AWS as cheaply as possible, which one do you rent? Two instance families sit at the bottom of the price list, and they carry the same generation of NVIDIA Turing silicon. G5g pairs a T4G with a Graviton2 host on aarch64. G4dn pairs a T4 with an Intel host on x86 64. The GPUs are effectively the same part. The host CPU is the variable. The answer turns out to depend entirely on whether you are buying hours or tokens. Start with price. Every NVIDIA instance type in us-east-1 was priced from the AWS Pricing API rather than from documentation: aws pricing get-products --region us-east-1 --service-code AmazonEC2 \ --filters Type=TERM MATCH,Field=instanceType,Value=g4dn.xlarge \ Type=TERM MATCH,Field=location,Value="US East N. Virginia " \ Type=TERM MATCH,Field=operatingSystem,Value=Linux \ Type=TERM MATCH,Field=tenancy,Value=Shared \ Type=TERM MATCH,Field=preInstalledSw,Value=NA \ Type=TERM MATCH,Field=capacitystatus,Value=Used Sixty four types came back. Keeping only those that give you a whole GPU rather than a fractional slice: | Rank | Instance | Host CPU | $/hr On-Demand | $/hr Spot | GPU | VRAM | |---|---|---|---|---|---|---| | 🥇 | g5g.xlarge | Graviton2 arm64 | 0.4200 | 0.1458 | T4G | 15,360 MiB | | 🥈 | g4dn.xlarge | Intel x86 64 | 0.5260 | 0.3559 | T4 | 15,360 MiB | | 🥉 | g5g.2xlarge | Graviton2 | 0.5560 | — | T4G | 15,360 MiB | g4dn.2xlarge | Intel | 0.7520 | — | T4 | 15,360 MiB | | g6.xlarge | AMD x86 64 | 0.8048 | 0.7033 | L4 | 22,888 MiB | The cheapest real CUDA GPU on AWS is an Arm box. It is 20 percent cheaper per hour on demand and 59 percent cheaper on spot. Three instances are cheaper still, at 0.2020, 0.2375 and 0.4750, but all three are fractional L4 slices with 2,861 to 5,722 MiB, and none of them can map Gemma 4 E2B's 10.2 GB checkpoint. The cheapest slice that could, g6f.4xlarge at 11,444 MiB, costs 0.95 per hour. So the headline is the Arm box. It is also the wrong number to buy on, and the rest of this article is why. Read off the running instances rather than the spec sheets: | Property | T4 on G4dn | T4G on G5g | |---|---|---| | Compute capability | 7.5 | 7.5 | VRAM, nvidia-smi | 15,360 MiB | 15,360 MiB | | Memory clock | 5,001 MHz | 5,001 MHz | | Bus width | 256 bit | 256 bit | | Theoretical peak bandwidth | 320.1 GB/s | 320.1 GB/s | | GPU KV cache allocated by vLLM | 329,579 tokens | 329,579 tokens | Every measurable property matches, down to vLLM independently arriving at a KV cache of exactly 329,579 tokens on both. Whatever separates these deployments, it is not the accelerator. This is the mechanism, and it has nothing to do with how fast either CPU runs. vllm/vllm-openai publishes one manifest list with two platforms, and they are not compiled for the same GPUs. Read straight out of the registry config blobs: linux/amd64 sha256:2286e8533ca8 TORCH CUDA ARCH LIST=7.5 8.0 8.6 8.9 9.0 10.0 12.0 sm 75 present linux/arm64 sha256:2a7cde230b59 TORCH CUDA ARCH LIST=8.0 8.7 8.9 9.0 10.0 11.0 12.0 sm 75 absent Same tag, same day. Only the amd64 image carries SM 7.5. The host architecture selects the manifest. An Intel host pulls kernels that run on its T4. A Graviton2 host pulls an image with no kernels for its own GPU, and the Dockerfile sets no +PTX , so there is not even a JIT fallback. That rig compiles vLLM from source before it serves a token. This is a packaging decision by the vLLM project, not a property of either CPU, and it is the single largest cost difference between the two families. G4dn gives you 4 GiB per vCPU. G5g gives you 2: | Instance | vCPU | Host RAM | |---|---|---| g4dn.xlarge | 4 | 16 GiB | g5g.xlarge | 4 | 8 GiB | Gemma 4 E2B's checkpoint is 9.54 GiB. On g5g.xlarge , with about 7.5 GiB usable, the kernel declines to map it and vLLM crash loops before a single page is faulted in: RuntimeError: unable to mmap 10246621918 bytes from model.safetensors: Cannot allocate memory 12 That is a failure of the mapping, not of residency, and a swapfile fixes it. But the cheapest CUDA instance on AWS needs configuration the next one up does not. g4dn.xlarge has 16 GiB and maps the checkpoint with no swapfile at all. g4dn.xlarge needs 4 vllm/hf-token AmazonSSMManagedInstanceCore git clone https://github.com/xbill9/gemma4-dev cd gemma4-dev/gpu-vllm-g4dn-2b pip install -r requirements.txt The requirements are small: mcp httpx boto3 The Hugging Face token is fetched at boot and never placed in user data, because instance metadata is readable by anything on the box. The fetch is wrapped in set +x , because the bootstrap runs under set -x and bash traces assignments with their values. The MCP server is a single Python file started over stdio. The standard MCP libraries abstract the transport, so the tool implementations are identical no matter which client connects. Registration lives in four places and all four must name the server identically: .mcp.json , the plugin manifest, .codex/config.toml , and enabledMcpjsonServers . A rename that updates three of four leaves an approval gate naming a tool that does not exist, and a gate on a tool name that does not exist fails open and says nothing. ./project-setup.sh --server-name gpu-vllm-g4dn-2b Quota first: check g4dn quotas | Running On-Demand G and VT instances vCPU | 16 | | All G and VT Spot Instance Requests vCPU | 16 | g4dn.xlarge needs 4 vCPUs. Quota is not capacity. G family spot in us-east-1 has been exhausted in every AZ but one with quota to spare, and the one AZ with capacity was the most expensive. Price is not a proxy for availability: aws ec2 get-spot-placement-scores --region us-east-1 --instance-types g4dn.xlarge \ --target-capacity 1 --single-availability-zone --region-names us-east-1 use1-az1 1 use1-az2 3 use1-az4 3 use1-az5 3 use1-az6 3 use1-az4 maps to us-east-1c , which scored 3 and carried the lowest spot price at 0.3559. create g4dn instance subnet id=subnet-0c2872fe4182b9ec1 security group id=sg-01ee54036d37aa770 iam instance profile=