Skip to main content
emnode / learn
Cost

Right-size EFS throughput mode

Provisioned Throughput bills a fixed bandwidth reservation 24/7 whether you use it or not — most file systems are better off on Elastic or Bursting.

13 min·10 sections·AWS

Last reviewed

EFS throughput modes: the basics

Why a file system can cost far more than the data sitting in it

Amazon EFS bills two things separately: the bytes you store, and the throughput mode that governs how fast you can read and write them. There are three throughput modes. Bursting scales available throughput with how much data you've stored and costs nothing extra. Elastic auto-scales to whatever the workload demands and charges only for the throughput you actually drive. Provisioned Throughput lets you reserve a fixed MiB/s — say 200 MiB/s — and you pay for that reservation every hour, on top of storage, whether the workload uses 200 MiB/s or 2.

The check flags Provisioned Throughput file systems whose measured throughput is far below what they've reserved. At roughly $6 per provisioned MiB/s-month (US-East), a 200 MiB/s reservation is about $1,200 a month before a single gigabyte of storage is counted. If the CloudWatch metrics show that file system actually pushing 15 MiB/s at peak, you're paying for 185 MiB/s of bandwidth that sits idle 24 hours a day.

It's flagged because Provisioned Throughput is the mode people reach for once and never revisit. Someone hit a throughput ceiling on a small file system years ago, pinned a generous number to make the problem go away, and that fixed monthly charge has run ever since — long after the workload it was sized for changed shape or moved away entirely.

In this lesson you'll learn the difference between EFS Bursting, Elastic, and Provisioned Throughput, how to read the CloudWatch signals (MeteredIOBytes, PermittedThroughput, PercentIOLimit) that prove a reservation is oversized, and how to switch modes safely. You'll see the AWS CLI calls to pull the utilisation evidence and to change the throughput mode, plus the edge cases that matter — the once-per-24-hours change limit, when Provisioned genuinely wins, and how Bursting credits behave on large versus small file systems.

Fun fact

The 1 TiB tax on a 40 GiB file system

Before Elastic mode existed, Bursting throughput scaled with stored size at a rate of 50 KiB/s per GiB, with a 100 MiB/s floor. A common trick to escape that floor was to write a single 1 TiB dummy file to the file system purely to unlock more burst throughput — paying ~$300/month in storage for a file nobody read, just to dodge a throughput ceiling. Provisioned Throughput was AWS's answer to that hack, and Elastic mode later made both the hack and the reservation unnecessary for the vast majority of workloads.

Right-sizing EFS throughput in action

Marcus runs the FinOps cadence at a genomics startup. The dashboard flags one EFS file system, fs-0a1b2c3d, on Provisioned Throughput at 250 MiB/s — about $1,500 a month in throughput charges on top of $90 of storage for the 1.1 TiB it holds. It's the single most expensive EFS file system in the account.

He pulls 14 days of CloudWatch metrics. PermittedThroughput sits flat at the provisioned 250 MiB/s ceiling. MeteredIOBytes, converted to a rate, peaks at 18 MiB/s during the nightly pipeline run and idles near zero the rest of the day. PercentIOLimit never crosses 9%. The reservation is roughly fourteen times the peak demand.

Marcus doesn't just drop the provisioned number — he switches the file system to Elastic mode, which auto-scales and bills per-use. He checks the workload tolerates the change (it does; the nightly burst is well within Elastic's headroom), runs update-file-system --throughput-mode elastic, and notes that the next mode change can't happen for 24 hours. Projected throughput cost falls from ~$1,500/month to roughly $40 of metered Elastic usage — a $1,460/month saving with no downtime and no application change.

First, pull the throughput you're permitted (the reservation) against the bytes actually metered, so you can see the gap directly.

$ aws cloudwatch get-metric-statistics --namespace AWS/EFS --metric-name PermittedThroughput --dimensions Name=FileSystemId,Value=fs-0a1b2c3d --start-time $(date -u -d '14 days ago' +%FT%TZ) --end-time $(date -u +%FT%TZ) --period 86400 --statistics Average Maximum
{
"Label": "PermittedThroughput",
"Datapoints": [
{ "Timestamp": "2026-05-12T00:00:00Z", "Average": 262144000, "Maximum": 262144000, "Unit": "Bytes/Second" },
{ "Timestamp": "2026-05-13T00:00:00Z", "Average": 262144000, "Maximum": 262144000, "Unit": "Bytes/Second" }
]
}
# Flat 262144000 B/s = 250 MiB/s permitted — the reservation, billed 24/7.

PermittedThroughput pinned flat at 250 MiB/s confirms a fixed Provisioned reservation, not demand-driven headroom.

Confirm the reservation is oversized, then switch to Elastic mode so you pay only for what the workload actually drives.

$ aws efs update-file-system --file-system-id fs-0a1b2c3d --throughput-mode elastic
{
"FileSystemId": "fs-0a1b2c3d",
"ThroughputMode": "elastic",
"ProvisionedThroughputInMibps": null,
"LifeCycleState": "updating",
"SizeInBytes": { "Value": 1181116006400 }
}
# Mode change accepted; next throughput-mode change is locked for 24h.

Switching to Elastic drops the fixed reservation; note the once-per-24-hours change limit before reverting.

EFS throughput modes under the hooddeep dive

EFS storage is priced per GiB-month per storage class — Standard at about $0.30 and Infrequent Access at about $0.016 (rough US-East rates). Throughput is a separate axis. Bursting is included free: you get a baseline of 50 KiB/s per GiB stored plus a burst-credit pool, so a 1 TiB file system bursts to ~100 MiB/s and sustains ~50 MiB/s. Elastic charges per use — roughly $0.03 per GiB read and $0.06 per GiB written, with no fixed component. Provisioned Throughput charges roughly $6.00 per MiB/s-month for whatever you reserve, billed continuously regardless of usage, and you still pay for any throughput driven beyond the included Bursting baseline.

The signals that prove a reservation is oversized live in CloudWatch under the AWS/EFS namespace. PermittedThroughput shows the ceiling currently available (flat at the provisioned value for Provisioned mode). MeteredIOBytes is the billed I/O — divide it by the period to get an actual throughput rate. PercentIOLimit is the percentage of the file system's I/O ceiling being used; if it sits in single digits, you have enormous unused headroom. The diagnostic is simple: peak measured throughput far below PermittedThroughput, and PercentIOLimit never approaching 100%, means the reservation is buying idle bandwidth.

Mode changes are an online operation — the file system stays mounted and available — but AWS rate-limits them to one throughput-mode or provisioned-value change per 24 hours. That matters for rollback: if you switch to Elastic and a workload genuinely needs the reserved level, you can't immediately flip back, so confirm the utilisation evidence first. Provisioned only genuinely wins for small file systems (where the Bursting baseline is too low because little data is stored) that need high, constant throughput — and even then, Elastic usually beats it unless the workload runs near the reserved level around the clock.

# Pull MeteredIOBytes and convert to an average throughput rate over the window.
aws cloudwatch get-metric-statistics \
  --namespace AWS/EFS \
  --metric-name MeteredIOBytes \
  --dimensions Name=FileSystemId,Value=fs-0a1b2c3d \
  --start-time $(date -u -d '14 days ago' +%FT%TZ) \
  --end-time $(date -u +%FT%TZ) \
  --period 3600 --statistics Sum \
  --query 'Datapoints[].{t:Timestamp,MiBps:Sum}' --output table
# Sum bytes / 3600s / 1048576 = MiB/s. Compare the peak hour to PermittedThroughput.

# Check how close you ever get to the I/O ceiling — single digits = huge headroom.
aws cloudwatch get-metric-statistics \
  --namespace AWS/EFS --metric-name PercentIOLimit \
  --dimensions Name=FileSystemId,Value=fs-0a1b2c3d \
  --start-time $(date -u -d '14 days ago' +%FT%TZ) \
  --end-time $(date -u +%FT%TZ) \
  --period 3600 --statistics Maximum

What is the impact of an oversized throughput reservation?

The direct cost is the reservation you don't use. At ~$6 per MiB/s-month, a 100 MiB/s reservation is $600 a month; 250 MiB/s is $1,500; 500 MiB/s is $3,000 — billed every hour regardless of demand. If the workload only drives a small fraction of that, the gap is pure waste, and unlike most variable cloud costs it never falls on its own because it's a fixed reservation, not a usage charge.

There's a structural trap here: the reservation hides inside an "EFS" line that finance reasonably assumes is storage. A 1 TiB file system might hold $90 of data and carry $1,500 of throughput reservation on top — so the bill is 94% bandwidth and 6% bytes, but it reads as a storage cost. Without breaking the line into its storage and throughput components, nobody realises the expensive part isn't the data at all.

The second-order cost is the missed alternative. EFS Elastic mode bills per use with no fixed component and auto-scales to demand, so almost any spiky or unpredictable workload is cheaper on Elastic than on a fixed reservation sized for the peak. Bursting is free and fine for large, steady file systems. Provisioned only wins in a narrow case — a small file system needing high, constant throughput beyond what its Bursting baseline allows — so most Provisioned file systems are simply on the wrong mode.

Finally, an unreviewed reservation is a governance signal. A 250 MiB/s setting against 18 MiB/s of real usage means someone sized for a worst case years ago and nobody has owned the decision since. The same pattern — set-once-and-forget on a pay-for-reserved knob — tends to show up across provisioned IOPS, reserved concurrency, and over-committed Savings Plans. Finding one oversized EFS reservation is often the thread that unravels several.

How do you right-size EFS throughput safely?

Right-sizing throughput is a four-step loop on the FinOps cadence: measure reserved-versus-used, pick the right mode for the workload shape, switch online with the 24-hour limit in mind, and set a default so new file systems don't repeat the mistake.

1. Measure reserved throughput against actual usage

For every Provisioned Throughput file system, pull 14+ days of PermittedThroughput (the reservation), MeteredIOBytes converted to a rate (actual usage), and PercentIOLimit (headroom). Anything where peak measured throughput sits well below the reservation — and PercentIOLimit never nears 100% — is oversized. A reservation more than ~2× the sustained peak is a strong candidate to change.

2. Choose the mode that matches the workload shape

Elastic for spiky, unpredictable, or unknown workloads — it auto-scales and bills per use, and is the right default for almost everything. Bursting (free) for large, steady file systems where the 50 KiB/s-per-GiB baseline already covers demand. Provisioned only for small file systems needing high, constant throughput beyond their Bursting baseline that genuinely run near the reserved level around the clock — and even then, sanity-check Elastic's metered cost first.

3. Switch online, but respect the 24-hour change limit

update-file-system --throughput-mode is a non-disruptive operation — the file system stays mounted. But AWS allows only one throughput-mode (or provisioned-value) change per 24 hours, so you can't quickly flip back if you guessed wrong. Confirm the utilisation evidence before switching, and for workloads with rare but real high-throughput windows, validate that Elastic's headroom covers the peak before dropping the reservation.

4. Default new file systems to Elastic and review reservations

Make Elastic the default for new EFS file systems in your IaC modules, and require a documented justification plus an owner and review date for any Provisioned reservation. Add a CloudWatch alarm or a recurring report on reserved-versus-used throughput so a new oversized reservation surfaces in days, not at the next annual audit. The loop only stays small if new file systems arrive on the right mode.

# Find every Provisioned Throughput file system and its reserved MiB/s in one pass.
aws efs describe-file-systems \
  --query 'FileSystems[?ThroughputMode==`provisioned`].{Id:FileSystemId,Mibps:ProvisionedThroughputInMibps,SizeGiB:SizeInBytes.Value}' \
  --output table

# Switch a confirmed-oversized file system to pay-per-use Elastic mode.
aws efs update-file-system \
  --file-system-id fs-0a1b2c3d \
  --throughput-mode elastic

# If a workload truly needs a reservation, set the smallest that covers sustained peak.
# aws efs update-file-system --file-system-id fs-0a1b2c3d \
#   --throughput-mode provisioned --provisioned-throughput-in-mibps 32

Quick quiz

Question 1 of 5

An EFS file system is on Provisioned Throughput at 250 MiB/s. Over 14 days, peak measured throughput is 18 MiB/s and PercentIOLimit never exceeds 9%. What's the right next move?

You've completed Right-size EFS throughput mode. You now know the three throughput modes, how to read PermittedThroughput, MeteredIOBytes, and PercentIOLimit to prove a reservation is oversized, and how to switch modes online while respecting the once-per-24-hours limit. The next time the wastage report flags a Provisioned Throughput file system, you'll have a defensible path from "flagged" to "resolved" in minutes.

Back to the library