Amazon EFS (Elastic File System) is a fully-managed, elastic, shared file system that speaks NFS — you mount it like a network drive and many machines read and write the same files at once, across Availability Zones, with no servers to run and no capacity to provision. That one sentence hides three ideas that make EFS distinctive: it is a file system (a POSIX tree of directories and files, not raw blocks or opaque objects), it is shared (hundreds of clients mount it concurrently), and it is elastic (it grows and shrinks automatically and you pay only for what you store). Those strengths come with a personality: NFS latency is higher than a local disk, and the default Bursting throughput mode hides a credit system that throttles small file systems in ways that catch teams off guard. This piece walks the whole model — where EFS sits among EBS and S3, how mounting and multi-AZ access work, the capacity and performance and throughput models, storage-class tiering, security, cost, and — with an interactive lab — exactly why a tiny file system can suddenly run slow.

What a managed NFS actually is

Before EFS, running shared file storage on AWS meant standing up your own NFS server: an EC2 instance with a big EBS volume, an NFS daemon, failover you built yourself, and the standing dread of that one box filling up or falling over. EFS replaces that entire operation with a service. You create a file system, it hands you an endpoint, and your instances mount it over standard NFSv4.1 exactly as they would mount any network share. There is no server to patch, no volume to size, no RAID to plan, and no single machine whose death takes the share down.

The word that matters is managed. AWS runs the storage fleet, spreads your data redundantly across multiple Availability Zones in the Region, handles durability and availability, and grows the backing capacity as you write. What you keep is the familiar file-system contract: a hierarchical namespace of directories and files, POSIX permissions and ownership, byte-range locking, rename and append semantics — the things applications assume when they open a path and expect a real filesystem underneath. EFS is that filesystem, delivered as an elastic, multi-AZ, pay-for-use utility rather than a box you babysit.

Advertisement

File vs block vs object: EFS, EBS, and S3

AWS has three storage shapes, and confusing them is the root of most bad architecture decisions. Block storage (EBS) gives you a raw virtual disk attached to one instance; the OS puts a filesystem on it. Object storage (S3) gives you a flat key-to-blob store reached over HTTP with its own API — no directories, no partial in-place writes, no mount. File storage (EFS) gives you a shared POSIX tree that many machines mount at once.

DimensionEBS (block)EFS (file)S3 (object)
Access modelRaw disk, one instanceNFS mount, many clientsHTTP API, key/value
Shared accessNo (single-attach; io2 multi-attach is niche)Yes, concurrent across AZsYes, via API
InterfaceFilesystem you createPOSIX filesystemGET/PUT objects
CapacityProvisioned, fixed sizeElastic, automaticEffectively unlimited
LatencySub-millisecondLow single-digit msTens of ms
Best forBoot disks, databasesShared app data, home dirsBackups, media, data lakes

The rule of thumb writes itself. Reach for EBS when one instance needs a fast local disk — a database’s data files, a boot volume. Reach for S3 when you have large, immutable-ish blobs accessed over an API and you do not need filesystem semantics. Reach for EFS precisely when the defining requirement is many machines sharing a real filesystem at the same time — the gap the other two cannot fill.

Shared access across instances, containers, and Lambda

The headline capability of EFS is concurrent shared access. A single EBS volume attaches to one instance; an EFS file system can be mounted by hundreds or thousands of clients simultaneously, and they can live in different Availability Zones. Every client sees the same directory tree, and a file written by one is visible to the others with close-to-open consistency — the model NFS applications are built around.

That shared surface shows up everywhere in modern architectures. A fleet of web servers behind a load balancer can share a common content or upload directory so any node serves any request. ECS and EKS containers mount EFS as a persistent volume that survives task restarts and follows the workload as it reschedules onto different hosts. AWS Lambda functions can mount an EFS file system directly, giving otherwise-ephemeral functions a large shared read/write space for model files, caches, or datasets far beyond the small /tmp they ship with. In every case the point is the same: the filesystem is a shared substrate independent of any one compute instance’s lifecycle, so compute can scale, restart, and move without the data moving with it. That decoupling is why EFS pairs so naturally with elastic and containerized workloads.

Mount targets: one ENI per AZ

Clients do not talk to EFS over the public internet; they reach it through a mount target inside your VPC. A mount target is an elastic network interface (ENI) with an IP address, and you create one per Availability Zone that needs access. An instance in us-east-1a mounts through the 1a mount target; an instance in us-east-1b mounts through the 1b one. Keeping clients on the mount target in their own AZ matters for both latency and cost, because cross-AZ traffic adds a hop and data-transfer charges.

Because a mount target is just an ENI in a subnet, it lives behind a security group, and that security group is the gate that lets NFS through. The single most common EFS setup failure is a mount that hangs forever: almost always the mount target’s security group does not allow inbound TCP 2049 (NFS) from the client instances’ security group. Clients mount using the EFS mount helper (amazon-efs-utils) or a standard NFSv4.1 mount command against the file system’s DNS name, which resolves to the right mount target IP for the caller’s AZ. Get the subnet placement and the security-group rule right and the mount is boring; get either wrong and you get silence.

The elastic capacity model

The ‘elastic’ in the name is not marketing. With EBS you choose a size up front — 100 GB, 2 TB — and you pay for that provisioned capacity whether or not you fill it, and you must actively grow it when it runs low. EFS has no provisioned size at all. You never declare how big it is. It starts effectively empty, grows automatically as you write files, and shrinks automatically as you delete them, scaling to petabytes without any operator action.

The billing follows the same shape: you pay for the number of gigabytes you are actually storing, metered and averaged over the month, not for a reserved ceiling. This removes an entire category of operational toil — no capacity planning, no ‘the volume is 90% full’ pages, no resize-and-grow-the-filesystem dance, no over-provisioning ‘just in case.’ It also reshapes the trade-off you make elsewhere: because you only pay for what you store, leaving cold data on EFS is not free, which is exactly what the storage-class and lifecycle machinery (covered below) exists to optimize. Elasticity buys you freedom from capacity management; it does not buy you freedom from thinking about what your bytes cost where they sit.

Performance modes and throughput modes

EFS exposes two orthogonal knobs, and people constantly conflate them. The first is the performance mode, chosen at creation and about latency-versus-parallelism. General Purpose is the default and the right answer for almost everyone: lowest per-operation latency, ample aggregate IOPS. Max I/O is a legacy mode that trades higher per-op latency for higher total parallelism at extreme scale; on modern EFS it is rarely the right choice and AWS steers you to General Purpose.

The second knob, the one that actually drives most surprises, is the throughput mode:

Throughput modeHow throughput is setFits
BurstingScales with stored size; burst credits allow spikes above baselineDefault; spiky, size-correlated workloads
ElasticAuto-scales up and down to demand; pay per data transferredUnpredictable or bursty traffic; simplest to reason about
ProvisionedYou dial in a fixed MB/s independent of sizeHigh, steady throughput on a small dataset

The key insight is that on Bursting, throughput is a function of how much you store, not of what you need — which is fine until they diverge. Elastic removes that coupling by scaling throughput to demand and charging for what you move, and it is now the pragmatic default for most new workloads. Provisioned exists for the specific case of needing steady high throughput on a small file system, where Bursting’s size-linked baseline would starve you. The next section digs into the credit mechanic that makes Bursting the sharpest edge of the three.

Burst credits: the number-one operational gotcha

This is the single most misunderstood thing about EFS, and it causes real incidents. On Bursting throughput, a file system has a baseline throughput that scales with its size — roughly 50 KB/s per GB stored. A 1 TB file system gets about 50 MB/s of baseline; a 10 GB file system gets about 0.5 MB/s. To let small file systems still handle spikes, EFS grants burst credits: whenever you drive throughput below baseline, you bank credits, and whenever you burst above baseline, you spend them, bursting up to a much higher ceiling (on the order of 100 MB/s per TB).

The trap is straightforward once you see it: a small file system has a tiny baseline and a shallow credit balance, so a sustained workload burns through its credits and then throttles hard to baseline — which for a few gigabytes might be a fraction of a megabyte per second. The symptom is a job that was fast for twenty minutes and then fell off a cliff, with nothing in the application to explain it. The fixes all follow from the model: store more data (a bigger baseline and deeper credit well), switch to Elastic or Provisioned throughput so throughput stops being hostage to size, or reshape the workload to stay under baseline on average. The lab below lets you drain the credit balance yourself and watch the throttle engage, which is the fastest way to internalize why ‘just a small EFS’ can be dangerously slow.

Storage classes and lifecycle management

Not every byte on EFS is hot, and paying hot-storage prices for files nobody has touched in months is pure waste. EFS offers multiple storage classes: Standard for frequently accessed data, Infrequent Access (IA) for data read rarely, and Archive for data touched only a few times a year. Each colder tier costs dramatically less per GB to store but adds a per-GB retrieval charge and higher first-byte latency when you do read it — the classic storage cost/latency trade.

You do not sort files by hand. Lifecycle management (and EFS Intelligent-Tiering) moves files between classes automatically based on access patterns: a policy such as ‘move to IA after 30 days without access’ demotes cold files, and a file that gets read again can be promoted back to Standard. Intelligent-Tiering automates the whole decision so you get the savings without guessing at policy windows. The economics are compelling for the common real-world shape — a large corpus where a small slice is active and the long tail is cold — because IA and Archive can cut the storage bill by an order of magnitude for that tail. The one thing to keep in mind is the retrieval fee: for data that is cold but read in bulk periodically, the read charges can outweigh the storage savings, so tiering rewards genuinely cold data, not merely large data.

Advertisement

NFS semantics and latency

EFS is a network filesystem, and physics does not exempt it. Every file operation is a network round trip to the storage fleet, so per-operation latency is low single-digit milliseconds rather than the sub-millisecond or microsecond latency of a local NVMe or an EBS volume. For throughput-oriented workloads — streaming large files, sequential reads and writes — that overhead is amortized and EFS performs beautifully. The pain appears in the opposite regime.

The workloads that punish EFS are small-file and metadata-heavy ones: unpacking a tarball of ten thousand tiny files, a git operation walking a huge tree, an npm install touching a deep node_modules, or any code that does stat on thousands of paths. Each of those is a separate round trip, and thousands of round trips at a few milliseconds each add up to seconds or minutes that would be instant on a local disk. The way to think about it: EFS trades a little latency on every operation for sharing, elasticity, and durability. If your workload does a modest number of operations on larger files, that trade is invisible; if it does an enormous number of tiny operations, batch them, cache locally, keep the latency-critical hot set on EBS, and reserve EFS for the shared data that genuinely needs to be shared.

Where EFS shines: real use cases

EFS earns its place wherever the requirement is a real shared filesystem that outlives and spans compute. The strongest cases:

Container persistent volumes. On EKS and ECS, EFS is the natural persistent, shared volume: a pod or task can be rescheduled onto any node in any AZ and still see the same files, and many replicas can share one volume — something a single-attach EBS volume cannot do. CMS and web workloads such as WordPress fit perfectly: a scaled-out fleet shares one uploads/plugins/themes directory, so any server serves any request and a new node is instantly consistent. Lift-and-shift NFS applications — legacy apps that assume a shared network drive — move to AWS with their storage assumption intact and nothing to re-architect. Shared datasets and home directories for teams and for ML: many training jobs or notebooks read the same large dataset, and researchers get shared home and scratch space, without copying terabytes onto each instance. The common thread is concurrency and persistence across a changing set of machines — exactly the niche EBS and S3 leave open.

Security: encryption, IAM, and Access Points

EFS is built to satisfy serious security requirements without bolt-ons. Encryption at rest uses AWS KMS; you can use an AWS-managed key or your own customer-managed key for full control over rotation and access policy, and it is transparent to clients. Encryption in transit wraps the NFS traffic in TLS, enabled through the EFS mount helper, so data is protected on the wire between instance and mount target as well as on disk.

Authorization works at two levels. Classic POSIX permissions — user and group ownership, mode bits — still govern who can read and write which files, exactly as on any Unix filesystem. On top of that, IAM can authorize the mount itself, so you control which principals may connect at all, and file-system policies can enforce, for example, TLS-only access. The piece that ties it together is EFS Access Points: an access point is an application-specific entry into the file system that enforces a fixed POSIX user/group and a root directory for anyone who connects through it. That lets you give each application or each tenant its own jailed view — app A enters at /app-a as UID 1001 and literally cannot see /app-b — which is how you multi-tenant a single file system safely and how container platforms hand each workload a clean, constrained mount.

See it: the burst-credit lab

Burst credits are the part of EFS that surprises people in production, so make them tangible. Below is a live Bursting-mode file system. The workload slider sets how hard you drive it in MB/s; the size slider sets how many gigabytes it stores, which in turn sets the baseline throughput (roughly 50 KB/s per GB) and the depth of the credit well. Press Start and watch the credit balance accrue while you sit at or below baseline and drain the moment you burst above it. Flip the toggle to Elastic to watch the credit mechanic disappear entirely.

The lesson the simulator makes obvious: on Bursting throughput, a small file system has a small baseline and a shallow credit well, so a sustained workload drains it and throttles hard — the classic ‘my EFS got slow and I have no idea why’ incident. Grow the file system and the baseline and well both grow with it; switch to Elastic and the whole credit economy evaporates because you simply pay for the throughput you use. That single toggle is the most important throughput decision you will make on EFS, and the lab lets you feel the difference before it bites you at 3 a.m.

The cost model

EFS pricing has two moving parts, and understanding both is how you avoid a surprising bill. The first is storage, charged per GB-month and varying sharply by storage class: Standard is the most expensive, Infrequent Access and Archive are far cheaper to store but add per-GB retrieval fees when read. The second, and the one people forget, is throughput, whose cost depends entirely on the throughput mode you chose.

On Bursting, throughput is bundled with storage — you pay for GB and get baseline-plus-credits ‘for free,’ which is cheapest right up until the credit throttle hurts you. On Elastic, you pay per GB of data actually read and written, which is beautifully simple and cheap for spiky or light-throughput workloads but can get expensive for a sustained high-throughput firehose. On Provisioned, you pay for the MB/s you reserve whether or not you use it, which wins only when you need steady high throughput on a dataset too small for Bursting to serve. The decision rule: use Elastic by default for unpredictable or bursty access; switch to Provisioned when you have measured a steady, high throughput need that Elastic’s per-GB charge would make more expensive; and keep Bursting only when your throughput genuinely tracks your stored size. Layer the storage classes underneath and the two axes — what you store and how you move it — are both optimized.

A decision framework: EFS vs EBS vs FSx vs S3

Strip away the specifics and choosing EFS is really choosing it against three neighbors. The honest questions:

If you need…Reach for…
A shared POSIX filesystem across many Linux clients and AZsEFS
A fast disk for one instance (database, boot volume)EBS
Cheap, massive, API-accessed blobs (backups, media, data lake)S3
Windows/SMB shares, or high-performance Lustre for HPC/MLFSx (for Windows / for Lustre)
Lowest possible per-op latency on shared dataEBS + app-level sharing, or FSx Lustre

EFS is the answer to one specific, common question — ‘how do many Linux machines share a real, elastic, durable filesystem without me running an NFS server?’ — and it answers it superbly. It is not trying to be the fastest single-instance disk (that is EBS), the cheapest bulk store (that is S3), a Windows file share or a Lustre speed demon (that is FSx). Know its personality: embrace the sharing, elasticity, and zero operational burden; respect the NFS latency on tiny-file workloads; and above all choose the throughput mode deliberately so the burst-credit gotcha never becomes your incident. Used for what it is — managed, elastic, shared file storage — EFS removes an entire class of undifferentiated heavy lifting from your architecture.

Amazon EFS is fully-managed, elastic, shared file storage that speaks NFS: many EC2 instances, containers, and Lambda functions mount the same POSIX tree concurrently across Availability Zones, capacity grows and shrinks automatically, and you pay only for what you store. It fills the gap between EBS (a fast disk for one instance) and S3 (API-accessed blobs) — the case where the defining need is a real, shared, durable filesystem. Its personality is the price of admission: NFS adds low-single-digit-millisecond latency that punishes metadata-heavy, tiny-file workloads, and the default Bursting throughput mode hides a burst-credit system where baseline scales with size, so a small file system throttles hard once its credits drain — the lab makes that failure mode visible. Choose the throughput mode deliberately (Elastic for most, Provisioned for steady high throughput on small data), tier cold files to IA and Archive, lock it down with KMS, TLS, IAM, and Access Points, and reserve EFS for the shared data that genuinely needs to be shared.