Conclusion first: the one-client speed limit, scaling with client count, and a monthly cost order that flips with usage
Amazon S3 Files lets you open, read, and write the data in S3 like an ordinary folder. With plain S3, a program has to call S3-specific APIs. With S3 Files, tools built to open files can work on your S3 data as they are.
This post is a measurement record for people who do not run storage performance tests as a routine job, to help decide whether S3 Files belongs in a design. I built the environment myself in ap-northeast-1 and measured speed on 2026-10-10. The monthly cost is arithmetic from list prices read on 2026-08-09.
Three things came out of it.
- One server has a read speed limit. On a c5n.9xlarge (a 36 vCPU server) it was about 1.1 GB per second (1,104.9 MB/s). It stops when the relay program running on the server (efs-proxy) uses up one CPU core (96.8 to 97.9%). One run.
- Adding servers raises the total. Going from 1 to 8 c5n.2xlarge servers raised the total from 784.4 MB/s to 6,282.6 MB/s (8.01x). All servers read the same 600 GiB file.
- The monthly cost order against FSx for ONTAP flips with usage. Amazon FSx for NetApp ONTAP is an AWS managed service that provides NFS and SMB shared folders, and with S3 Access Points attached it also serves the same data through the S3 API. For 20 TiB stored and 4 MiB objects read 10 times a month (ap-northeast-1), S3 Files comes to $514.88 a month and FSx for ONTAP to $1,052.53 (excluding request charges). This is price x quantity arithmetic, not a measurement.
The takeaways: when one server is not fast enough, add servers (confirmed up to 8). The monthly cost order reversed between an example that reads large objects and an example that writes many small objects. The second example is in the chapter "Differences between FSx for ONTAP and S3 Files, tiering, and billing".
How to read this post by goal
- You only want the conclusion: this chapter is enough.
- You want to know whether it works in your setup: "The value of S3 Files and four prerequisites"
- You want the cost: "Differences between FSx for ONTAP and S3 Files, tiering, and billing"
- You want the measurement conditions and limits: "The single-mount ceiling", "An aggregate that scales with client count", "What I have not measured"
- You want to reproduce it: "Reproducing it yourself"
Introduction
There are times when you want to handle S3 data as files: an existing script that opens the files in a folder one by one, or a business tool built around a shared folder. Amazon S3 Files became generally available in April 2026, and it lets you mount an S3 bucket as an NFS file system (the network shared-folder mechanism of Linux) without migrating data.
Before using it, I think you wonder about three things.
- What is it good for, in the end?
- How fast is it, and what does it cost?
- How does it differ from a file-server type of service (FSx for ONTAP)?
This post answers the second and third by measuring in my own environment. I do not cover the first, the introduction. The Classmethod article (Japanese) compares I/O performance and sync lag with Amazon EFS, and the Serverworks article (Japanese) sorts out five services, including Mountpoint for Amazon S3.
In the previous post (S3 Burst Part 2: "The throughput ceilings of three paths") I compared three paths, S3 Files among them, side by side and asked where each one tops out. This time I narrow down to S3 Files alone. Last time the question was which path tops out where. This time it is how S3 Files behaves as a file system.
The mount failed before I could measure anything, so I recorded the cause first. Someone else will hit the same wall. After reading, you can decide with numbers whether S3 Files is a candidate, how far the number of servers can carry your speed, and which of S3 Files and FSx for ONTAP with S3 Access Points fits better. S3 Access Points here means the S3 API entry point that you attach to an FSx for ONTAP volume.
What I cover / do not cover
Covered
- The prerequisites of S3 Files and the value AWS states for it. Prerequisites decide first whether you can use it at all.
- Why the mount failed. It was missing permissions, not the network, and knowing in advance avoids it.
- The single-mount ceiling (c5n.9xlarge). The per-client ceiling is the starting point of capacity planning.
- Aggregate growth with client count (c5n.2xlarge, 1 to 8 clients). It shows how far clients can carry you past one mount's limit.
- Differences from FSx for ONTAP, tiering, and billing. Both give you the same data through files and the S3 API, but the monthly cost comes out differently.
- How my warm / cold comparison failed. Warm means reading data that sits in S3 Files' high-performance storage; cold means reading straight from the bucket. Someone repeating the measurement can fall into the same trap.
- Which of the four values AWS states I could confirm, and which I could not. It separates what is safe to base an adoption on.
- What I have not measured. It lets you judge where the numbers apply.
Not covered
- An introduction to S3 Files, and how it differs from Mountpoint for Amazon S3 and Amazon EFS. Articles already cover that, and it is outside this post's subject, measured speed and monthly cost.
- Which configuration is faster. The paths were measured in different environments (NFS version, instance type, configuration), so no same-conditions winner exists.
- The details of consistency semantics. The window of about 60 seconds between writing a file and reading it through the S3 API appears as two rows in the comparison table of "Differences between FSx for ONTAP and S3 Files, tiering, and billing". The conditions of that window are in another verification record (Japanese). It is outside this post's subject, which is throughput and client count.
- A correct same-conditions measurement of the warm / cold difference. The first comparison was invalid and I have not re-measured.
- Multi-AZ configurations, clients outside AWS, and tiering differences inside a VPC. I measured in a single-AZ environment in ap-northeast-1. The chapter "What I have not measured" lists the scope in a table.
Terms used in this post
Each term is explained at first use in the text. This table is an index for rereading.
| Term | Meaning | Where it appears |
|---|---|---|
| S3 Files | A service that mounts an S3 bucket as an NFS file system. Built on Amazon EFS; the bucket remains the source of truth | All chapters |
| High-performance storage | The low-latency layer inside the S3 Files file system. It holds the data and metadata of files in active use, and you pay storage charges for what it holds | "The value of S3 Files and four prerequisites", "Differences between FSx for ONTAP and S3 Files, tiering, and billing", "An invalid warm / cold comparison" |
| efs-proxy | A local proxy that runs on the mounting client's EC2 instance. The mount target is 127.0.0.1, and in the verification records this one process handles TLS termination and NFS translation | "The value of S3 Files and four prerequisites", "A hung mount", "The single-mount ceiling", "An aggregate that scales with client count", "Differences between FSx for ONTAP and S3 Files, tiering, and billing" |
| Mount target | The NFS endpoint of the file system that you create in a VPC (port 2049). One per AZ at most | "The value of S3 Files and four prerequisites", "A hung mount" |
| nconnect | A Linux NFS mount option that opens several TCP connections to one server. S3 Files does not support it, and specifying it hung the mount | "The value of S3 Files and four prerequisites", "The single-mount ceiling" |
| warm / cold | In this post, used only for S3 Files reads. Warm is a read of data held in high-performance storage; cold is a read straight from the bucket. For FSx for ONTAP I write "on SSD" and "on the capacity pool" | "An invalid warm / cold comparison", "Status of the four stated values", "What I have not measured" |
| Capacity pool | The tier where FSx for ONTAP keeps data that does not fit on SSD. Its storage price is lower than SSD (Single-AZ, ap-northeast-1: $0.0238 vs. $0.15 per GB-month, read 2026-08-09) | "Differences between FSx for ONTAP and S3 Files, tiering, and billing", "What I have not measured" |
| Tiering All | One of the tiering policies of an FSx for ONTAP volume. It places the data on the capacity pool | "Differences between FSx for ONTAP and S3 Files, tiering, and billing" |
| FlexCache / Origin | FlexCache is an ONTAP feature in which a Cache volume holds only the data read from the Origin volume that owns the original data. This post uses it only to say that the FSx for ONTAP propagation measurement read the Origin volume directly | "Differences between FSx for ONTAP and S3 Files, tiering, and billing" |
| S3 Access Points | In this post, the S3 API entry point attached to an FSx for ONTAP volume. The same data can be read and written over NFS / SMB and the S3 API | "Differences between FSx for ONTAP and S3 Files, tiering, and billing" |
| VDBENCH | A tool that generates storage I/O load (distributed by Oracle). The S3 Files measurements here used 5.04.07 | "The single-mount ceiling", "An aggregate that scales with client count" |
| o_direct | A setting that reads and writes without the OS page cache. In VDBENCH it is openflag=o_direct | "The single-mount ceiling", "An aggregate that scales with client count" |
| disjoint / same | Disjoint: each client reads a non-overlapping range. Same: all clients read the same file | "An aggregate that scales with client count" |
| shared epoch | All clients wait until the same UNIX time (90 seconds after launch) and start measuring together | "An aggregate that scales with client count" |
The value of S3 Files and four prerequisites
S3 Files lets Linux compute mount a bucket as an NFS file system and read and write it while the bucket stays the source of truth. It is built on Amazon EFS and became generally available in 34 regions in April 2026 (What's New). Four prerequisites decide first whether you can use it.
Four prerequisites
| Prerequisite | Detail | Source |
|---|---|---|
| Bucket versioning | Required. Encryption is SSE-S3 or SSE-KMS | Prerequisites for S3 Files |
| Client compute | Linux on AWS (EC2 / Lambda / ECS / EKS / Fargate / Batch). I could not find documentation for mounting from outside AWS | S3 Files product page |
| Protocol | NFSv4.1 and NFSv4.2 only. NFSv3 and SMB are not listed as supported. nconnect (a Linux mount option that opens several TCP connections to one server) is unsupported; in my verification, specifying it timed out the mount after 90 seconds (one observation, c5n.2xlarge, 2026-09-02) | Unsupported features, limits, and quotas, verification record |
| File-to-bucket propagation | After you change a file, S3 Files waits about 60 seconds before copying it to the bucket | Performance specifications |
How the mount works
When you mount, efs-proxy (the local proxy mentioned in the summary) starts on the client's EC2 instance. Your application mounts 127.0.0.1, and efs-proxy connects to the mount target in the VPC. The mount target is the NFS endpoint of the file system (port 2049), with a limit of one per AZ. In the verification records, this efs-proxy handles TLS termination and NFS translation in one process (verification record, Japanese). This structure sets the single-mount ceiling measured in a later chapter.
Reads take one of two paths. Small files (under 128 KiB by default) are imported asynchronously into high-performance storage, the low-latency layer inside the file system, on first access, and later reads are fast. Reads of 1 MiB or more go straight to the bucket even when the data sits in high-performance storage. The source is Performance specifications.
Values AWS states
The following four points are AWS's statements. I could get numbers for the second point, propagation time between files and the S3 API, and for the fourth point, single-mount throughput and aggregate growth with client count (up to 8). I did not measure the first, and the comparison for the third was invalid.
- Existing file-based tools work as they are. The product page says "No code changes, no custom connectors, and no new APIs to learn" (product page).
- The same data is usable from both files and the S3 API at the same time. The product page's wording is "nothing to reconcile between two separate systems", meaning you do not have to reconcile two systems.
- Only frequently read data sits in high-performance storage, and you pay for what it holds. Reads of 1 MiB or more cost only the standard S3 GET price (product page).
- Many clients can use it at once. The limit is 25,000 connections per file system, and the aggregate read throughput is "up to terabytes per second" in the AWS pages' wording (quotas, Performance specifications).
If your requirements include NFSv3 or fixed SMB devices, Windows workflows, or clients outside AWS, S3 Files drops out at the prerequisites table. If none of those apply, read the following chapters on the mount failure, the single-mount ceiling, and client scaling, and use them for capacity planning.
A hung mount: missing CloudWatch permissions on the client's IAM role
mount -t s3files timed out every 15 seconds. The cause was not the network or DNS. The IAM role on the client EC2 instance lacked logs:CreateLogGroup and cloudwatch:PutMetricData. Adding the permissions let the mount complete.
The environment was a c5n.9xlarge (Amazon Linux 2023, amazon-efs-utils 3.3.2) in a dedicated measurement VPC in ap-northeast-1 (a public subnet with an internet gateway). It happened while I prepared the measurement, and my troubleshooting notes carry no date. The throughput measurements in the same environment ran on 2026-10-10.
Symptom: timeouts every 15 seconds with a healthy network
- efs-proxy: running, with a TCP connection to port 2049 on the mount target (ESTAB in
ss) - Reachability: both S3 on 443 and the service endpoint on 2049 were reachable
- Mount:
mount.nfs4 127.0.0.1:/still did not finish
Cause: efs-proxy restarting over and over because log creation failed
The efs-proxy log contained these lines.
WARN cw_publisher Failed to create log group: AccessDeniedException ... logs:CreateLogGroup ERROR nfs::nfs_reader Error sending message batch to dispatcher DispatchingFailure INFO controller Proxy incarnation restarted, restart_count=3 Before establishing the NFS connection, the mount helper tries to create a CloudWatch Logs log group (/aws/efs/utils). When that call fails for lack of permissions, efs-proxy keeps restarting and the mount never finishes. An AWS article names the same behavior as the root cause when a mount hangs forever without an obvious reason (Mounting S3 Files on EC2 in private subnets).
My subnet has an internet gateway, so CloudWatch Logs was reachable. Permissions were the blocker, not reachability. In a private subnet with no CloudWatch Logs VPC endpoint, unreachability produces the same symptom.
Original record: Mount pitfalls (causes and fixes) (Japanese)
Fixes: any of three options works
| # | Fix | Fits when |
|---|---|---|
| 1 | Grant the IAM role logs:CreateLogGroup, logs:CreateLogStream, logs:PutLogEvents, and cloudwatch:PutMetricData | You have an internet gateway or CloudWatch endpoints and also want CloudWatch metrics. I used this one |
| 2 | Disable CloudWatch logging in the mount helper (/etc/amazon/efs/s3files-utils.conf) | You do not want to add permissions or endpoints |
| 3 | Create a CloudWatch Logs VPC endpoint (com.amazonaws.<region>.logs) | A private subnet with neither an internet gateway nor a NAT |
I did not pick option 2 because the next chapter's measurement uses efs-proxy's CloudWatch metrics (connectivity and byte counts) to isolate the cause of the ceiling.
Pre-mount checks: three items
- IAM role: it carries the permissions from fix 1.
- botocore: installed with
dnf install python3-botocore(pip3does not work). Without it, the mount either stopped withaccess denied by server while mounting, or went through but CloudWatch metrics were unavailable. The two verification records show different symptoms, and neither records the condition that decides which one you get. - Mount target: it is in the same AZ as the client, and the security group allows 2049 from the client.
Check these three items before you mount, and decide beforehand whether to grant the CloudWatch permissions or disable logging.
The single-mount ceiling: one efs-proxy core saturated
A single mount stopped at 1,104.9 MB/s for 1 MiB sequential reads (c5n.9xlarge, one run). The limiter was the efs-proxy process's CPU: one core of 36 vCPU was full (96.8 to 97.9%). As noted in the prerequisites chapter, S3 Files does not support nconnect, so no mount option can add connections to efs-proxy and move this ceiling.
Measurement conditions
- Environment: ap-northeast-1, 2026-10-10 (UTC), single AZ, c5n.9xlarge (36 vCPU), Amazon Linux 2023
- Mount:
nfs4 vers=4.2,rsize=wsize=1048576,hard. The server is127.0.0.1(through efs-proxy, TLS and IAM authentication always on) - Load: VDBENCH 5.04.07 (an I/O load generator distributed by Oracle), 512 threads,
o_direct(bypasses the OS page cache) - Data: a single uncompressible 600 GiB file. 60 seconds of warmup, then 300 seconds measured
Results: four workloads
| Workload | Throughput | IOPS |
|---|---|---|
| 1 MiB sequential read | 1,104.9 MB/s | 1,105 |
| 1 MiB sequential write | 852.0 MB/s | 852 |
| 4 KiB random read | 61.9 MB/s | 15,839 |
| 4 KiB random write | 14.4 MB/s | 3,688 |
Each row is one run; I did not repeat any condition. Source of this table: Results (S-1 + S-2) (Japanese)
Isolating the cause: efs-proxy CPU saturated at one core
I re-measured 1 MiB sequential reads for 60 seconds and sampled CPU three times.
| Sample | efs-proxy CPU | VDBENCH and java CPU |
|---|---|---|
| 1 | 96.8% | near 0 |
| 2 | 97.4% | near 0 |
| 3 | 97.9% | near 0 |
The re-measured throughput was 1,109.4 MB/s, 0.4% away from the main run's 1,104.9 MB/s. The mount target is a local proxy at 127.0.0.1, and efs-proxy handles TLS termination and NFS translation in one process, so one mount tops out at one core of that process. Source of this table: Ceiling confirmation (Japanese)
Differences by instance type: three values under different conditions
Even on the same c5n.2xlarge the value changes with how I measured, so here are three side by side.
| Measurement | Instance | Conditions | Read | Date |
|---|---|---|---|---|
| Stream-count sweep | c5n.2xlarge | 8 streams, 1 GiB per stream, O_DIRECT | 451.3 MB/s | 2026-09-02 |
| One client in the client-count test | c5n.2xlarge | VDBENCH, 64 threads, 1 MiB sequential, 600 GiB file | 784.4 MB/s | 2026-10-10 |
| Single-mount test | c5n.9xlarge | VDBENCH, 512 threads, 1 MiB sequential, 600 GiB file | 1,104.9 MB/s | 2026-10-10 |
The three differ in conditions, so this is not a comparison that changes only the instance type. I have no measurement that varies only the instance type under the same conditions. I also did not isolate whether efs-proxy CPU or the client's network bandwidth sets the roughly 785 MB/s per c5n.2xlarge. Source of this table: Stream-count measurement (Japanese)
When one mount is not enough bandwidth, design for adding clients (the next chapter).
An aggregate that scales with client count: 8.01x at 8 clients
Going from 1 to 8 c5n.2xlarge clients raised the aggregate read from 784.4 MB/s to 6,282.6 MB/s (8.01x). Per client it stayed roughly constant at 784.4 to 802.2 MB/s. That fits the structure in which each client has its own efs-proxy.
Measurement conditions
- Environment: ap-northeast-1, single AZ, 2026-10-10 (UTC), up to 8 c5n.2xlarge, Amazon Linux 2023
- Mount: each client mounts S3 Files on its own (one efs-proxy per client)
- Load: VDBENCH, 1 MiB sequential read,
o_direct, fixed at 64 threads per client (only the client count changes) - Simultaneous start: shared epoch. All clients wait until the same UNIX time (90 seconds after launch) and start measuring together. 60 seconds of warmup, then 180 seconds measured
- Range read: two patterns, same (all clients read the same 600 GiB file) and disjoint (each client reads a non-overlapping range)
Results: all clients read the same file
| Clients | Aggregate | Per client | Ratio to 1 client |
|---|---|---|---|
| 1 | 784.4 MB/s | 784.4 MB/s | — |
| 2 | 1,604.5 MB/s | 802.2 MB/s | 2.05x |
| 4 | 3,148.4 MB/s | 787.1 MB/s | 4.01x |
| 8 | 6,282.6 MB/s | 785.3 MB/s | 8.01x |
Source of this table: Client-count measurement (same) (Japanese)
Results: each client reads a non-overlapping range
I measured disjoint at 8 clients only. The aggregate was 7,210.0 MB/s, and per client 901.3 MB/s (a spread of 770 to 1,332), higher than the 8-client same result of 6,282.6 MB/s. Each client reads different data, so sharing and fanning out one read cannot explain the number. I did not measure disjoint at 1, 2, or 4 clients, so the shape of disjoint scaling is unconfirmed.
Source of this table: Client-count measurement (disjoint) (Japanese)
Measurement limit: client-side totals only
The numbers are the sum of what the clients reported. I could not reconcile them with CloudWatch DataReadBytes: on the day, metrics arrived sparsely and did not land in the measurement window. The record also has no spread across repeated runs for each client count.
Figure 1: The internals of S3 Files. Each client has its own efs-proxy. A single mount tops out at one efs-proxy core, while the aggregate grows in proportion to client count (measured up to 8). The figure says the same thing as the tables above.
For capacity planning up to 8 clients, multiply roughly 785 MB/s per client (785.3 MB/s at 8 clients; c5n.2xlarge, all clients reading the same file) by the client count. I have not measured 9 or more, so check the conditions in the chapter "What I have not measured" before relying on that range.
Differences between FSx for ONTAP and S3 Files, tiering, and billing
Both S3 Files and FSx for ONTAP with S3 Access Points let you use the same data through a file mount and the S3 API. What differs is the source of truth: an S3 bucket for S3 Files, an ONTAP volume for FSx for ONTAP. That difference changes how the bill comes out. From list prices, storing 20 TiB and reading 4 MiB objects 10 times a month costs $514.88 a month via S3 Files and $1,052.53 on FSx for ONTAP. Writing 300 million 64 KiB objects a month costs $10,756.38 via S3 Files and $2,088.02 on FSx for ONTAP, so the order reverses.
The two setups compared in this chapter are as follows.
- S3 Files: attach S3 Files to an S3 bucket and mount it over NFS from EC2. The S3 API reaches the bucket directly.
- FSx for ONTAP: use an ONTAP volume over NFS / SMB and attach S3 Access Points (the S3 API entry point attached to the volume) to the same volume. Data that does not fit on SSD can sit on the capacity pool, a tier with a lower storage price. Tiering All, one of the volume's tiering policies, places the data on the capacity pool.
Comparing the two ways to use the same data through two entry points: the source of truth differs
The table below lines up the two setups by aspect. I wrote "not measured" where I did not measure. Measured values come from different environments, so each cell carries its environment.
| Aspect | S3 Files (S3 bucket first) | FSx for ONTAP + S3 Access Points (file system first) | Source |
|---|---|---|---|
| Source of truth | The S3 bucket. Objects and files point at the same bucket | The ONTAP volume | Design differences |
| File-side entry | NFSv4.1 / 4.2 only, through a per-client efs-proxy. nconnect is unsupported | ONTAP serves NFS (v3, v4.0 to 4.2) and SMB directly | Protocol comparison, S3 Files quotas |
| S3 API-side entry | The bucket itself | An S3 Access Point attached to the volume | Design differences |
| Propagation: write as a file, read with the S3 API | p50 63,769.3 ms (a window of about 60 seconds). t3.small, NFSv4.2, 64 B, concurrency 1, n=30, 2026-09-01 | p50 44 ms. NFSv3, 128 MBps Single-AZ, 64 B, concurrency 1, n=30, 2026-08-09 | S3 Files measurement, FSx for ONTAP measurement |
| Propagation: write with the S3 API, read as a file | p50 1,533.1 ms (same environment as above) | p50 3 ms. A direct NFS read of the Origin volume that received the write (it does not go through a FlexCache Cache volume; same environment as above) | Same as above |
| Conflict and locking | When the same key is changed from the file side and the S3 API side, the S3 bucket side became the source of truth (3/3 converged on the S3 content). The file-side version was moved to .s3files-lost+found-<fs-id>. Only conflicts inside the window (5 seconds later) were measured | FlexCache duality and attaching an S3 Access Point are separate mechanisms, and this row uses neither. I did not measure ONTAP-side file locking against this comparison | Conflict behavior (Japanese) |
| Supported APIs, conditional writes, copy scope | The S3 bucket API. I did not measure conditional writes or copy scope in this post | Presigned URLs through S3 Access Points (PutObject / HeadObject / GetObject) are verified (2026-08-19, n=30x4, succeeded under both SigV4 and SigV2). The official support table also lists Presign as Supported (confirmed 2026-10-08, documented). Uploads are single PutObject 5 GiB and whole object 50 GiB, with the limit judged at CompleteMultipartUpload. The read side is asymmetric: a GET of 50 GiB + 1 byte succeeded (537 seconds, 2026-09-11) | Verification status (Japanese) |
| Versioning / Object Lock / Lifecycle | Bucket versioning is required. I did not measure Object Lock or Lifecycle in this post | On the S3 Access Points side, S3 event notifications, lifecycle, and versioning are not supported (documented). ONTAP-side data protection (SnapLock and the like) is a separate mechanism; do not equate it with S3 Object Lock | Design differences (Japanese) |
| IAM vs. file-side permissions | An object written through the S3 API appears as root:root on the file system (file 0644, directory 0755). A client mapped to non-root at the access point cannot write into a directory the S3 API created (reads go through). I could not find this in the public documentation | ONTAP NFS / SMB file permissions and the IAM on the S3 Access Points side are separate paths. I did not run a reconciling measurement in this post | Owner of S3-API writes (Japanese) |
| Where unread data sits | The S3 bucket. Reads of 1 MiB or more go to the bucket even when the data is in high-performance storage | SSD. Depending on the tiering policy, the capacity pool (Tiering All places everything there) | Performance specifications, Billing items table |
| Read billing items | S3 GET plus 4 KiB metadata reads ($0.04 / GB). Small files held in high-performance storage also incur a data read charge ($0.04 / GB) | GET through S3 Access Points ($0.000029 / 1,000). Data on the capacity pool can incur a read request charge ($0.00037 / 1,000). Requests per GetObject: not measured | Billing items table |
| Latency of reading data that is not held in the fast tier | Not confirmed. 64 KiB p50 was 5.33 ms from high-performance storage and 4.05 ms straight from the bucket (c5n.9xlarge, n=30, one run, 2026-10-10). A separate t3.small record shows 10.8 ms vs. 55.0 ms (2026-09-01), which did not reproduce on c5n.9xlarge | Not measured. There is one observation of +5.3 to +15.4 ms against the SSD side, but the reads did not reach the capacity pool, so it cannot be read as that delay | Three reads, Reads by tier |
| Adding clients: file path | 1 to 8 clients: 784.4 to 6,282.6 MB/s (8.01x). c5n.2xlarge, all clients read the same file, 2026-10-10. 9 or more: not measured | 1 to 8 clients: 2,664.58 to 11,916.29 MB/s (4.47x, all clients read the same file). With non-overlapping regions it does not grow, from 2,299.05 MB/s at 2 clients to 2,173.37 MB/s at 8. c5n.2xlarge, nconnect=16, second generation, 2,048 MBps, 2026-09-05 | S3 Files client count, FSx for ONTAP client count |
| Adding clients: S3 API path | The S3 API reaches the bucket directly. Reads from Amazon S3 went from 495.4 to 2,030.5 MB/s at 1 to 4 clients (4.10x, c5n.2xlarge, 2026-09-01 to 02). Not measured on a bucket with S3 Files attached | At 1 to 4 clients, writes went 129.4 to 131.0 MB/s (1.01x) and reads 480.9 to 612.3 MB/s (1.27x). 128 MBps configuration, nearly flat from 2 clients. Clients share the purchased throughput capacity | Measurement record of the previous post |
| Published limits | 25,000 connections per file system, 3 GiB/s read per client. Aggregate read is "up to terabytes per second" in AWS's wording | You buy throughput capacity. The minimum for Single-AZ first generation is 128 MBps | quotas, Performance specifications, Fixed-cost floor |
| Fixed cost | None. S3 storage plus what you use | Floor of $269.57 a month for Single-AZ first generation (SSD 1,024 GiB + 128 MBps, prices read 2026-08-09) | Fixed-cost floor |
| Prerequisites and constraints | Bucket versioning required. Clients are Linux on AWS. NFSv4.1 / 4.2 only. About 60 seconds from file to bucket | On the S3 Access Points side, S3 event notifications, lifecycle, and versioning are not supported. Capacity pool read charges. Clients share the throughput capacity | Design differences, Performance specifications |
The propagation rows are not a same-conditions comparison, because the NFS version, client, and configuration differ. The client-count rows differ too: S3 Files used VDBENCH with 64 threads per client, and FSx for ONTAP used a second-generation 2,048 MBps configuration with nconnect=16. I read the two AWS documents in full on 2026-10-15.
Source of this table: Design differences table. For the measured rows, the sources are the links in the "Source" column.
The four stages of file-to-bucket propagation, and how to treat the maximum reflection time
The "window of about 60 seconds" in the propagation rows is not one wait but four stages. The measured p50 of 63,769.3 ms is the whole span from (a) to (d).
| Stage | Definition | Category |
|---|---|---|
| (a) File write complete and persisted | The moment the write to NFS finishes through efs-proxy. Separate from propagation to S3 | NFS semantics |
| (b) No-write wait | The wait counted from when writes to the same file stop. The official Synchronization page states the "60 seconds with no writes" condition | Documented |
| (c) Export start | The moment a file that satisfies the wait condition becomes an export target. The official Performance page states the roughly 60-second aggregation | Documented |
| (d) Visible through the S3 API | After the export completes. The measured p50 of 63,769.3 ms is this whole (a) to (d) | Measured (t3.small, 64 B, concurrency 1, n=30, 2026-09-01) |
The export side agrees across two sources. Against the client-side max of 66.33 seconds, the CloudWatch ExportAge peak was 66.06 seconds, a 0.27-second difference (all 30 runs fell in 63.8 to 66.3 seconds).
The maximum reflection time cannot be used as a guaranteed value. On the import side (S3 to file), the client-side max of 14.36 seconds and the CloudWatch ImportAge peak of 62.80 seconds do not agree. I could not find a maximum reflection time in the official documentation, so I do not treat it as an upper bound, and I write the representative value as the client-side p50. I do not write "reflected within 60 seconds", "reflected every minute even under continuous updates", or "never synchronized" either, because none has grounds. This explanatory model (wait, then aggregate, then export) is not an SLA.
Three notes. In a conflict (the same key changed from the file side and the S3 API side), the S3 bucket side became the source of truth (3/3 converged on the S3 content), and the file-side version was moved to .s3files-lost+found-<fs-id> (matching the CloudWatch LostAndFoundFiles peak of 3.00). That directory is not created on conflict; it is present from the start (0700 root:root), and what happens on conflict is the eviction event. Whether an evicted version is outside asynchronous propagation is something I did not measure. For large rename / move operations, the file-side completion and the S3-side completion may not coincide, but I did not measure that separately.
Measurements that separate the propagation conditions (long continuous appends, after updates stop, while another file is being updated, concurrent updates) are deferred to a separate verification plan (a plan, not a new measurement).
Example 1: reading large objects, S3 Files costs 0.49x of FSx for ONTAP per month
Reading 4 MiB objects 10 times a month costs $514.88 a month via S3 Files and $1,052.53 on FSx for ONTAP. S3 storage is 99.4% of the S3 Files total, while fixed capacity and bandwidth make up nearly all of FSx for ONTAP. I use the conditions the FinOps comparison in the GitHub repository already uses.
| Assumption | Value |
|---|---|
| Region, client side | ap-northeast-1. Reading from EC2 in the same region (data transfer $0.00) |
| Dataset | 20,480 GiB (20 TiB) |
| Frequently read range | 2,048 GiB (10% of the dataset). 524,288 objects of 4 MiB |
| Reads | 10 a month. 524,288 objects x 10 = 5,242,880 reads |
| S3 Files threshold | Default 128 KiB. 4 MiB is above it, so data is not held in high-performance storage and is read straight from the bucket |
| FSx for ONTAP configuration | Single-AZ first generation, 128 MBps. SSD 4,424 GiB, capacity pool 11,469 GiB. Assumes 70% of the data on the capacity pool, 40% storage efficiency on the SSD tier, half of that on the capacity pool tier, and 20% headroom on SSD (model assumptions, not measurements) |
| Prices | ap-northeast-1, on-demand, excluding tax. The repository's price table was read on 2026-08-09; I confirmed the same values with the Price List API (read-only) on 2026-10-15 |
Source of this table: Example assumptions (I changed only the read count to 10), Price table
Monthly cost via S3 Files (S3 bucket first)
Unit price x quantity = monthly cost. This is list-price arithmetic, not an invoice. I multiply the GiB figure as the GB-month quantity as is, the same as the repository's model.
| Item | Unit price | Quantity | Monthly cost |
|---|---|---|---|
| S3 Standard storage | $0.025 / GB-month | 20,480 GiB | $512.00 |
| S3 GET | $0.00037 / 1,000 requests | 5,242,880 requests | $1.94 |
| S3 Files metadata reads | $0.04 / GB | 5,242,880 reads x 4 KiB = 20 GiB | $0.80 |
| S3 Files metadata import | $0.07 / GB | 524,288 objects x 4 KiB = 2 GiB | $0.14 |
| S3 Files high-performance storage | $0.36 / GB-month | 0 GiB (above the threshold, not held) | $0.00 |
| Data transfer (same region) | — | — | $0.00 |
| Total | $514.88 |
Reading with the S3 API alone costs $513.94 for storage and GET ($512.00 + $1.94). Attaching S3 Files adds $0.94.

