Mountpoint for Amazon S3 Has Added Memory Usage Control, So I Checked How Many Files Can Be Opened Simultaneously for Writing

Mountpoint for Amazon S3 Has Added Memory Usage Control, So I Checked How Many Files Can Be Opened Simultaneously for Writing

Mountpoint for Amazon S3 now lets you set a memory target. I mounted it on EC2 with different --memory-target values and checked the startup log's limit on concurrently open files for writing, and what happens beyond it.
2026.08.30

This page has been translated by machine translation. View original

Introduction

On August 26, 2026, Mountpoint for Amazon S3 added --memory-target, which lets you specify a target value for the memory usage of the entire process in MiB.

https://aws.amazon.com/about-aws/whats-new/2026/08/mountpoint-for-S3-adds-memory-usage-controls

https://dev.classmethod.jp/articles/mountpoint-for-S3-adds-memory-usage-controls/

https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md

The What's New post describes the previous behavior as follows.

Previously, Mountpoint's memory usage could expand over time based on usage patterns, potentially causing performance or stability issues when competing with other memory-intensive applications.

Item Before Now
Target value for memory usage of the entire process Could not be specified Can be specified in MiB with --memory-target (minimum 512 MiB)
Behavior when not specified Could increase over time depending on usage patterns 95% of installed memory or the cgroup limit is applied as the target value (512 MiB if 95% is below 512 MiB)
Upper limit on the number of files that can be open for writing at the same time No upper limit based on the memory target Determined by the target value and the read/write part sizes, and output in the startup log (added in v1.24.0)
Behavior under memory pressure Not confirmed in the official documentation Slows down I/O, reclaims unneeded buffers, and reduces prefetching

What changed is not only that you can now specify a value. Even when you don't specify one, a target value determined from the installed memory or the cgroup limit is applied. The official documentation also describes how the target value is determined from the cgroup limit, but what I tested this time is the case where the target value is determined from the installed memory.

The behavior under memory pressure is described in the CHANGELOG as follows.

This target is not a guaranteed limit but Mountpoint manages the memory available for data buffers to stay within the target: under memory pressure it slows down I/O, reclaims buffers it no longer needs and reduces prefetching.

--memory-target was added in v1.24.0 (released on August 24, 2026), and this verification was also done on the same version. The upper limit on the number of files that can be open for writing at the same time is classified in the CHANGELOG not as a new feature but under Breaking changes. Because the limit applies regardless of whether --memory-target is specified, the behavior changes as soon as you upgrade the version.

Mountpoint now limits how many files can be open for writing at the same time, derived from --memory-target and --write-part-size. Once the limit is reached, opening a file for writing fails with ENOMEM until an existing write file handle is closed.

In this article, I checked the upper limit on the "number of files that can be open for writing at the same time" (hereafter, the limit count), which is determined for each target value, and the behavior when the limit count is exceeded.

Verification details

I checked two things: remounting with different target values, and using Python to keep opening files for writing without closing them.

Verification environment

In v1.24.0, the limit count is calculated from the target value, the read part size, and the write part size. In the verification environment, no cgroup memory limit is applied, so the target value when unspecified is determined from the installed memory.

  • EC2 t3.medium (total in free -m is 3835 MiB), Amazon Linux 2023
  • Mountpoint is version 1.24.0 from the RPM package
  • Region is ap-northeast-1, and the mount target is one general purpose bucket
  • The default values of both --read-part-size and --write-part-size are 8388608 bytes (8 MiB)

Here is the relevant part of mount-s3 --help.

      --memory-target <MiB>
          Target for Mountpoint's total memory usage, in MiB.

          Mountpoint manages the memory used to buffer reads and writes to stay within this target but it is
          not a guaranteed limit. Lowering it may reduce throughput and increase latency.

      --read-part-size <SIZE>
          Part size for GET in bytes [default: 8388608]

      --write-part-size <SIZE>
          Part size for multi-part PUT in bytes [default: 8388608]

Limit count for each target value

I repeated the operation of mounting with a different target value, checking the startup log, and then unmounting, four times. I mounted with the following command and retrieved the log.

mount-s3 amzn-s3-demo-bucket /mnt/s3 --memory-target 512
journalctl -e SYSLOG_IDENTIFIER=mount-s3 --no-pager -o cat | grep write_handle_limiter

From the output of the four patterns, I extracted only the mount success lines and the relevant log lines.

===== memory-target=512 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 47 (memory target 512 MiB, write part size 8 MiB)
===== memory-target=1024 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 111 (memory target 1024 MiB, write part size 8 MiB)
===== memory-target=2048 =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 223 (memory target 2048 MiB, write part size 8 MiB)
===== memory-target=none =====
bucket amzn-s3-demo-bucket is mounted at /mnt/s3
[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 397 (memory target 3644 MiB, write part size 8 MiB)
--memory-target Target value in log Limit count
512 512 MiB 47
1024 1024 MiB 111
2048 2048 MiB 223
Not specified 3644 MiB 397

The target value of 3644 MiB when unspecified is about 95% of the installed memory of 3835 MiB. This matched the statement in the official documentation, "95% of total memory or the cgroup limit."

The limit count for all four patterns followed the formula in the official documentation. The formula is described in "Maximum number of files open for writing" in CONFIGURATION.md.

https://github.com/awslabs/mountpoint-s3/blob/main/doc/CONFIGURATION.md

cap = (memory_target − max(128 MiB, memory_target / 8) − read_part_size) / write_part_size

When the target value is 512 MiB, Mountpoint reserves 128 MiB for overhead and 8 MiB for reads. 376 MiB is available for writes, and the limit was (512 − 128 − 8) / 8 = 47 files. Fractions resulting from the calculation are rounded down.

Even if you double the target value, the limit count does not double. The overhead and read portions are subtracted first. Furthermore, when the target value exceeds 1024 MiB, the overhead calculation switches to memory_target / 8, so the amount subtracted increases (256 MiB for 2048 MiB).

The denominator of the formula is the write part size, so reducing --write-part-size increases the limit count. However, multipart uploads have a maximum of 10,000 parts, so the maximum size of a single object also becomes smaller. I did not change the write part size this time, so please check separately if you change it.

Failure to open beyond the limit

I mounted with a target value of 512 MiB (limit of 47 files), and to make sure the limit was exceeded, I used Python to open files for writing and increased the count to 60 files without closing them.

[INFO] ThreadId(01) mountpoint_s3_fs::memory::write_handle_limiter: max files concurrently open for write: 47 (memory target 512 MiB, write part size 8 MiB)
opened successfully: 47
failed at file #48: errno=12 (ENOMEM) Cannot allocate memory

As per the limit count shown in the startup log, opens up to the 47th succeeded, and the 48th open failed with ENOMEM (Cannot allocate memory).

Next, I closed one of the open handles and then tried to open again.

opened=47, next open failed: errno=12 (ENOMEM)
after closing 1 handle, waited 0s cumulative: open failed errno=12 (ENOMEM)
after closing 1 handle, waited 1s cumulative: open SUCCESS

In this environment, reopening immediately after closing the handle failed, and a retry one second later succeeded. The CHANGELOG says that opens for writing fail until an existing write file handle is closed. However, a slot does not necessarily become available immediately after closing.

When the limit count is reached, open() fails rather than becoming slower. For applications whose number of simultaneous opens may reach the limit count, you need to control the number of files opened or handle ENOMEM. If you implement retries, consider adding a wait rather than repeating immediate retries.

Summary

Previously, Mountpoint's memory usage could grow over time, but with this update, control has been introduced to keep memory usage within the target value. Even if you don't specify a target value, one is determined from the installed memory or the cgroup limit. The target value is applied just by upgrading the version. If you have been troubled by memory shortages or OOM while using Mountpoint, try upgrading the version and adjusting --memory-target.

On the other hand, there is a trade-off: the limit count is determined from the target value, and once the limit count is reached, subsequent opens fail with ENOMEM. First, check the limit count for your own environment in the startup log. The limit count increases if you raise the target value, but since a buffer of the part size is allocated for each file being written, memory proportional to the number of simultaneous opens is required. If you keep responding only by increasing infrastructure memory, the memory allocated to EC2 or Fargate grows, and operational effort and AWS usage costs also increase. As application-side measures, consider limiting the number of files opened simultaneously, or performing writes with the AWS SDK or AWS CLI.

Share this article

AWSのお困り事はクラスメソッドへ