TL;DR. EMR Serverless pricing in US East is $0.052624 per vCPU-hour and $0.0057785 per GB-hour on x86, about 20% less on Graviton, billed per second on the workers a job holds. The same 8 vCPU and 64 GB cost $0.791 an hour on Serverless and $0.630 on an r5.2xlarge under EMR on EC2, so Serverless costs less only when an EC2 cluster would sit idle for more than about a fifth of its billed hours. The worked nightly job below clears it. After that, the bill tracks what each job asks for: executor sizes, warm pools and an unbounded executor ceiling.

This post prices one nightly Spark job on Serverless (x86 and Graviton), EMR on EC2 and EMR on EKS, computes the break-even, and shows how to get the cost of each job run from AWS's own fields. Every figure is computed from AWS list prices read October 28, 2026; we did not run the job.

EMR Serverless bills three meters per worker

AWS's EMR pricing page bills "aggregate vCPU, memory, and storage resources used from the time workers are ready to run your workload until the time they stop, rounded up to the nearest second with a 1-minute minimum." The rates for US East (N. Virginia), from the AWS Price List API, effective October 1, 2026:

EMR Serverless meter, US Eastx86Graviton (arm64)
Per vCPU-hour$0.052624$0.042094
Per GB-hour of memory$0.0057785$0.004628
Per GB-hour of storage$0.000111$0.000111

Three details change the bill more than the rates do:

  1. Storage is free up to 20 GB per worker on standard storage. On shuffle-optimized storage, AWS says "you pay for the entire storage configured per worker, including the first 20 GB."
  2. Worker sizes are fixed steps. A 4 vCPU worker takes 8 to 30 GB in 1 GB increments; an 8 vCPU worker 16 to 60 GB in 4 GB increments, per the worker configuration table.
  3. Custom images start the meter earlier. With a custom image, billing runs "from the time EMR Serverless starts downloading the image until the workers are stopped".

The price list names the meters as usage types such as USE1-EMR-SERVERLESS-vCPUHours, USE1-EMR-SERVERLESS-MemoryGBHours and USE1-EMR-SERVERLESS-ARM-vCPUHours, the names to filter on in billing data. The x86 architecture is the default; AWS's architecture guide says "it costs less to run instances on arm64 architecture than when you run instances of equal size on x86 architecture."

A nightly Spark job costs $229 a month on Serverless, $183 on Graviton

Consider a hypothetical nightly Spark job that runs for one hour, 30 nights a month:

  • one driver worker with 4 vCPU and 16 GB;
  • 20 executor workers with 4 vCPU and 27 GB each (spark.executor.memory=24g plus the default 10% overhead fits inside 27 GB);
  • no extra storage, no pre-initialized capacity, all workers held for the full hour.

That is 84 vCPU and 556 GB for one hour a night.

Per runx86Graviton
vCPU: 84 × rate$4.4204$3.5359
Memory: 556 GB × rate$3.2128$2.5732
Run$7.6333$6.1091
Month (30 runs)$229.00$183.27

Graviton cuts this job's bill by 20.0%, with no other change, if its libraries run on arm64. AWS's Graviton considerations ask you to confirm that third-party packages are compatible first.

The same job on EMR on EC2 and EMR on EKS

On EMR on EC2, the EMR price is added to the EC2 price per instance-hour. The 20 executors pack two per r5.2xlarge: EMR's default YARN setting on that instance gives containers 57,344 MB, per the task configuration table, and two 24g executors with Spark's default 10% overhead factor need about 54,000 MB. Ten core nodes host the executors, an eleventh the driver, and an m5.xlarge is the primary node. Assume, hypothetically, the transient cluster bills 70 minutes a night: the hour of work plus 10 minutes to provision and bootstrap. Measure yours.

Prices from the EMR price list and AWS's EC2 on-demand price data for US East:

InstanceEC2 per hourEMR charge per hour
r5.2xlarge$0.504$0.126
r6g.2xlarge (Graviton)$0.4032$0.1008
m5.xlarge$0.192$0.048
m6g.xlarge (Graviton)$0.154$0.039

On EMR on EKS, the EMR charge is $0.007084 per vCPU-hour and $0.000777875 per GB-hour of pod requests, after the October 2026 cut, on top of the nodes. Assume the same 11 r5.2xlarge nodes for 70 minutes, and pods requesting the same 84 vCPU and 556 GB for the hour.

Month, 30 nightly runsEMR chargeComputeTotal
EMR Serverless, x86bundledbundled$229.00
EMR Serverless, Gravitonbundledbundled$183.27
EMR on EC2, r5 + m5$50.19$200.76$250.95
EMR on EC2, r6g + m6g$40.17$160.62$200.80
EMR on EKS, r5 nodes$30.83$194.04$224.87, plus $73 if the EKS cluster is dedicated

The EKS cluster fee is $0.10 an hour per cluster, $73 over a 730-hour month, and free to this job only if other workloads already pay for the cluster. EBS volumes on the EC2 and EKS nodes are left out, which flatters both.

For this short nightly batch, Serverless beats EMR on EC2 on both architectures at list prices. The EC2 cluster pays for the minutes before work starts and for the capacity the executors do not fill; Serverless pays for neither. EMR on EKS comes in $4.13 under Serverless x86, but only on a cluster other workloads already pay for; a dedicated one adds $73.

The break-even: Serverless costs 26% more per busy hour

Price the same capacity both ways. Eight vCPU and 64 GB for one hour cost 8 × $0.052624 + 64 × $0.0057785 = $0.7908 on Serverless. An r5.2xlarge with EMR on EC2 costs $0.504 + $0.126 = $0.630. Serverless is 25.5% more for an hour of work.

An EC2 cluster is billed whether or not its nodes work, so its cost per hour of work is $0.630 divided by the share of billed node-hours that do work. The two meet at $0.630 / $0.7908 = 79.7%. On Graviton the rates are $0.6329 against $0.504, and the break-even is again 79.6%.

Line chart of the cost of one hour of useful work on 8 vCPU and 64 GB in AWS US East. EMR Serverless is a flat $0.791. EMR on EC2 on an r5.2xlarge is $0.630 divided by the share of billed node-hours in use, rising to $1.575 at 40%. The lines cross at about 80%; below that, Serverless costs less.

If a cluster would be busy more than 80% of what it bills, EMR on EC2 is cheaper; below that, Serverless is. A steady 24/7 cluster that stays full sits on the right of the chart. Nightly batches, ad hoc jobs and clusters sized for a peak sit on the left.

Discounts move the line. EMR on EC2 can run on Spot Instances, and Compute Savings Plans "apply to usage across Amazon EC2, AWS Lambda, and AWS Fargate", a list that does not name EMR Serverless. As a hypothetical, at half the on-demand EC2 price an r5.2xlarge node-hour costs $0.378 and the break-even drops to 47.8%.

Why the EMR Serverless bill grows

Serverless removes idle nodes and bills every vCPU and GB a job asks for. Three settings decide what jobs ask for, and nobody revisits them once a job works.

Executor sizes copied from the last job

Memory is 42% of the x86 run above: $3.21 of $7.63. If profiling showed the job runs as well on 16 GB executor workers, the 20 executors would shed 220 GB, $1.27 a run and $38.14 a month, 16.7% of the bill, with no change to vCPU. AWS's own sizing example sets about 27 GB of executor memory on a 4 vCPU worker, 29.7 GB with overhead, to use the whole worker. That suits a heavy job; copied into a light one, it is paid for every run.

Pre-initialized capacity left warm

Pre-initialized capacity keeps workers ready so jobs start in seconds. AWS is direct about the cost: "You will be paying for provisioned pre-initialized workers even when the application is idle." Applications auto-stop after 15 idle minutes by default, and the setting can be turned off.

AWS's example Spark application pre-initializes 5 drivers at 2 vCPU and 4 GB and 50 executors at 4 vCPU and 8 GB: 210 vCPU and 420 GB. At x86 rates that is $13.48 an hour, $3.37 for each 15-minute idle tail, and $9,838.95 over a 730-hour month if auto-stop is off.

An executor ceiling that is not there

On EMR 6.10.0 and later, spark.dynamicAllocation.maxExecutors defaults to infinity, per the Spark defaults for EMR Serverless. A skewed stage or a bad join can then request workers up to the application's maximum capacity. The same page offers dynamicAllocationOptimization to reuse workers across stages, suggests pairing it with an upper bound through maxExecutors or the application's maximum capacity, and warns it can lengthen jobs that run a large stage, smaller ones, then a large one again.

Get the cost of each job run from AWS's own fields

Each job run carries billedResourceUtilization: the vCPU-hours, memory GB-hours and storage GB-hours "that AWS has billed for the job run", including the 1-minute minimum and storage over 20 GB per worker.

aws emr-serverless get-job-run \
  --application-id "$APP_ID" --job-run-id "$RUN_ID" \
  --query 'jobRun.billedResourceUtilization'
# cost = vCPUHour * 0.052624 + memoryGBHour * 0.0057785 + storageGBHour * 0.000111  (x86, US East)

For the bill itself, AWS added job run level cost allocation on January 9, 2026: tags on each job run, filterable in Cost Explorer and the Cost and Usage Report. It is off by default, does not apply to past runs, and can only be changed while the application is created or stopped. Once on, application-level totals need the same tag on every job run.

The per-job numbers will not add up to the bill when warm pools exist. The API reference says billed resources "do not include usage for idle pre-initialized workers." The gap between the sum of job runs and the application's CUR lines is the warm pool's idle cost; report it as its own line, owned by whoever asked for fast starts. How AWS labels that idle cost in the CUR when job-level allocation is on, the docs do not say; check your own report before relying on it.

The same split between a line that knows the job and one that does not shows up on Databricks classic compute and on EMR on EKS.

The case for Serverless everywhere, and where it stops

The strongest objection: Serverless removes cluster operations, and most EC2 clusters run far below 80% busy, so it should be the default. For bursty and nightly work, the worked bill agrees.

It stops in three places. A cluster that stays busy, on Spot or under a Savings Plan, beats Serverless on price, and the break-even falls as the discount grows. Serverless bills what the job requests, so an oversized job pays in full, every run; on EC2 the same waste can hide inside capacity already paid for. And the engineering time a cluster costs is real but not priced here.

The limits of this post: US East list prices read October 28, 2026; other regions and negotiated rates differ. The job, its sizes, the 10-minute cluster overhead and the Spot discount are hypotheticals. The Serverless figures assume workers are billed at their configured size for the whole hour, the way AWS's own pricing example computes it. S3, CloudWatch and IPv4 address charges apply to every option and are left out.

Where Datapace fits

A Serverless bill grows with what each job requests, and the requests sit in job definitions nobody reopens. Datapace is building one map of your data estate with usage and cost attached, and agents that propose changes as pull requests your team reviews and merges. For the same method applied to every pipeline, read data pipeline cost: how to get the cost per pipeline.

Sources

  1. AWS, Amazon EMR pricing (EMR Serverless billing, storage, worker sizes, pricing examples, EKS cluster fee).
  2. AWS Price List API, Amazon EMR offer, version 20261022223118, read October 28, 2026.
  3. AWS, EC2 on-demand price data for US East Linux, read October 28, 2026.
  4. AWS, EMR Serverless User Guide: application behavior and worker sizes, pre-initialized capacity, Spark job properties, architecture options, job level cost allocation.
  5. AWS, EMR Serverless API Reference, JobRun.
  6. AWS, Amazon EMR Serverless adds support for job run level cost allocation, January 9, 2026.
  7. Apache Spark, Spark configuration.
  8. AWS, EMR Release Guide, task configuration defaults, and EMR Management Guide, instance purchasing options.
  9. AWS, Services eligible for Savings Plans.