EFS is the line item nobody audits. There is no instance to stop, no cluster to pause, no obvious dial to turn — the file system just sits there, mounted by something, growing a little every month. And unlike most things on your bill, the fix is not "delete what nobody uses." Most EFS waste sits on file systems that are genuinely in use; you are simply paying the premium rate for data nothing has touched in a year.
Here is where the money goes, and the one configuration trap that makes teams think they already fixed it.
Why is EFS so expensive?
Because EFS Standard is priced as premium shared storage, and premium is a big multiplier when it is applied to every byte you have ever written.
| What you are storing | Rate per GB-month (us-east-1) | Relative to EFS Standard |
|---|---|---|
| EFS Standard | $0.30 | 1× |
| EFS One Zone | $0.16 | 0.53× |
| EFS Standard-IA | $0.025 | 0.08× |
| EFS One Zone-IA | $0.0133 | 0.04× |
| EFS Archive | $0.008 | 0.03× |
| EBS gp3 | $0.08 | 0.27× |
| S3 Standard | $0.023 | 0.08× |
Read the first and last rows together: EFS Standard costs about thirteen times S3 Standard, and roughly four times a gp3 volume. That is not a pricing error — you are paying for a managed NFS file system that many clients can mount at once, replicated across availability zones, that grows and shrinks with no provisioning. For the working set your application actually reads, that is a fair trade.
The problem is that a file system does not distinguish between the working set and everything else. Both are billed at $0.30. A 2 TB file system where 80% of the data has not been opened since the migration that created it is a $614/month line item, of which roughly $490 buys nothing but availability nobody uses.
Two costs sit outside the per-GB rate and surprise people. Provisioned Throughput bills whether or not there is any I/O, at $6.00 per MB/s-month — a file system provisioned at 50 MB/s costs $300 a month before a single byte of storage. And Elastic Throughput bills per GB of data moved ($0.03 read, $0.06 written) in exchange for dropping retrieval fees on the cold classes.
Is EFS more expensive than S3?
Per gigabyte, yes, by a wide margin — but the comparison only applies to part of your data.
If an application needs POSIX semantics — file locking, partial writes, atomic rename(), several instances writing to one directory — S3 does not do those things, and re-architecting around them costs more engineering time than the storage difference is worth. Keep that data on EFS.
It does apply to the cold tail, and that is where the savings are. Old build artifacts, exported reports, per-customer archives, the last four migrations' worth of dumps: none of it needs POSIX, all of it is billed at $0.30. For what stays on EFS, the lever is the storage class — which brings us to the setting most teams have already enabled and are getting nothing from.
What does EFS Infrequent Access actually cost?
Standard-IA is $0.025 per GB-month against Standard's $0.30 — a 92% reduction on whatever moves. Archive is $0.008, cheaper again, aimed at data measured in months rather than days.
The catch is retrieval, and it depends on your throughput mode. On Bursting or Provisioned throughput, reading from IA costs $0.01 per GB retrieved and Archive $0.03 per GB, and those reads consume your throughput budget too. On Elastic throughput there is no separate IA or Archive retrieval fee and IA storage drops to $0.016 per GB-month — you pay per GB of data access instead, on every class.
So: for data you genuinely never read, IA and Archive are close to free money on any throughput mode. For data you read occasionally in bulk — a quarterly job that scans the whole archive — a Bursting file system hands back a real slice of the saving in retrieval fees. Check ThroughputMode before you model anything.
These are us-east-1 rates verified against the AWS Price List API in August 2026. Storage and
retrieval pricing varies by region, and AWS changes it. Confirm on the
EFS pricing page before anyone signs off on a number.
Why didn't enabling lifecycle management lower my bill?
EFS lifecycle management transitions files on last access time, not last modified time. A file moves to Infrequent Access after your chosen window — 1, 7, 14, 30, 60, or 90 days — without being read. Every read resets the clock to zero.
Which means anything that walks the file system and opens files keeps all of it permanently hot. The usual culprits are a backup agent on an EC2 instance reading every file over the NFS mount each night, antivirus scanning scheduled against mounted volumes, checksum or integrity jobs (rsync -c, find -exec md5sum) that verify content instead of comparing size and timestamp, and search indexers pointed at the mount.
Teams enable a 30-day policy, wait a month, see the bill unchanged, and conclude lifecycle management does not work. It works fine. Something reset every timer every night.
The distinction that matters when you go hunting: metadata operations do not count as access. Listing a directory, stat, or a find that only matches on names touches nothing. It is reading file contents that resets the clock. So ls -lR in a monitoring script is harmless; the nightly tar of the same directory is not.
To find out whether this is happening to you, compare access times against modification times on a sample of old files from any Linux client that has the file system mounted:
find /mnt/efs -type f -mtime +180 -printf '%A+ %T+ %p\n' | head -20
Two ancient timestamps per row is a file system where lifecycle management will work. A recent access time next to a two-year-old modification time, repeated down the list, is your answer: something read every file recently, and nothing transitions until you stop it.
The fix is to change the job, not the policy. Move whole-file-system backups to AWS Backup's EFS integration, which operates against the file system rather than reading it through a mount. Scope antivirus and indexers to the directories that need them, switch verification jobs to size-and-mtime comparison, then re-check the storage split in a month.
One more reason a policy can produce less than expected: files smaller than 128 KB do not transition to Infrequent Access, and IA storage is metered in 128 KB increments. A file system holding millions of small config files, source files, or per-user documents will see very little move regardless of how cold it is.
How do I check what EFS is actually costing me?
Three calls. First, whether a policy exists at all — an empty LifecyclePolicies array is the finding:
aws efs describe-lifecycle-configuration --file-system-id fs-0123456789abcdef0
Then the split across storage classes, plus the throughput mode that determines your retrieval exposure:
aws efs describe-file-systems --file-system-id fs-0123456789abcdef0 \
--query 'FileSystems[].{Mode:ThroughputMode,Standard:SizeInBytes.ValueInStandard,IA:SizeInBytes.ValueInIA,Archive:SizeInBytes.ValueInArchive}'
Those sizes are metered rather than live and can lag by hours. For the trend — the thing that proves a policy is working — use the CloudWatch StorageBytes metric with the StorageClass dimension set to Standard, IA, or Archive. Standard falling while IA rises is the only confirmation worth trusting.
Finally, whether the file system is used at all:
aws cloudwatch get-metric-statistics --namespace AWS/EFS \
--metric-name DataReadIOBytes \
--dimensions Name=FileSystemId,Value=fs-0123456789abcdef0 \
--start-time 2026-07-12T00:00:00Z --end-time 2026-08-11T00:00:00Z \
--period 86400 --statistics Sum
Repeat for DataWriteIOBytes and add the daily sums. Under about 10 MB across a full month is effectively nothing — a single directory sync would exceed it — and puts you in delete-or-archive territory rather than lifecycle territory.
How do I reduce EFS cost, in order?
Enable lifecycle management everywhere, then verify it moved something. Pair TransitionToIA with TransitionToPrimaryStorageClass set to AFTER_1_ACCESS, so a cold file that gets read returns to Standard speed and price automatically. That combination bounds the latency risk to the first read of each file. Start at 30 or 90 days, watch the class split for a month, then tighten.
Work the example. A 2 TB file system, all Standard, costs 2,048 × $0.30 = $614.40/month. If 80% of it is cold, a policy moving 1,638 GB to IA leaves 410 GB Standard at $123.00 plus 1,638 GB IA at $40.95 — $163.95/month, a 73% cut. Reading all of it back once in a month on Bursting throughput would cost $16.38 in retrieval, which barely dents the saving. Push the coldest slice to Archive and the IA half falls again by roughly two thirds.
Move the cold tail off EFS entirely where POSIX is not required. At 13× S3 Standard, data that could live in a bucket is the most expensive way AWS offers to store it.
Check for file systems nothing mounts, and check ThroughputMode while you are there. A file system with no mount targets is outright waste; one that is idle and on Provisioned Throughput costs $6.00 per MB/s-month more than its storage suggests.
delete-file-system is final — the only route back is an AWS Backup recovery point, and a restore
creates a new file system with a new ID, so mount commands, task definitions, and access points
all need updating. Mount targets must be deleted first, and removing one cuts NFS access instantly
for every client in that subnet. NFS hard mounts do not fail cleanly when the server disappears;
processes block in uninterruptible I/O and can wedge an instance badly enough to need a reboot.
Take the backup, confirm nothing has it mounted, then delete. If you are not confident, enable a
lifecycle policy instead — it captures much of the saving and deletes nothing.
What else should I check while you are in here?
Cold data billed at hot prices is a storage-defaults problem rather than an EFS problem, and the same shape is almost certainly on your S3 bill — objects written once and never migrated, plus the incomplete multipart uploads that are invisible in the console and billed anyway. S3 lifecycle rules for cold data covers the storage-class tradeoffs and the rule that fixes both.
A file system with near-zero I/O is also a hint about the compute that used to mount it. EFS outlives the instances it was attached to — the file system survives a terminated instance perfectly happily — so an abandoned share is often the tail end of an environment that was never fully torn down, with the EC2 side of it still running. How to find idle EC2 instances covers proving that half, and the compute is usually the larger number of the two.
If EFS is the first thing you have looked at, it is probably not the biggest. A full pass over an AWS account goes in order of savings-per-minute, and deleting things nobody uses generally beats tiering things people do.
How do I keep EFS cost from creeping back?
Auditing one file system is half an hour. Doing it for every file system in every region — whether a lifecycle policy exists, whether it actually moved anything, whether the storage split is drifting back toward Standard, and whether a quiet file system is merely quiet or genuinely abandoned — is the part that never happens twice. That is what a scan is for. Parsivex checks each region, flags file systems with no lifecycle policy and file systems with near-zero I/O, and then keeps watching, so the next file system created without a policy gets caught in weeks rather than whenever somebody next reads the bill closely.
For what these findings mean once they appear in your report, including the thresholds behind them, see Idle EFS file system and EFS file system missing lifecycle policy.