Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/next-release/enhancement-s3-32921.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"type": "enhancement",
"category": "``s3``",
"description": "Expose S3 transfer config's ``io_chunksize`` in shared config file"
}
5 changes: 4 additions & 1 deletion awscli/customizations/s3/transferconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'max_bandwidth': None,
'preferred_transfer_client': constants.AUTO_RESOLVE_TRANSFER_CLIENT,
'target_bandwidth': None,
'io_chunksize': 256 * 1024,
}


Expand All @@ -45,8 +46,9 @@ class RuntimeConfig:
'max_queue_size',
'max_bandwidth',
'target_bandwidth',
'io_chunksize',
]
HUMAN_READABLE_SIZES = ['multipart_chunksize', 'multipart_threshold']
HUMAN_READABLE_SIZES = ['multipart_chunksize', 'multipart_threshold', 'io_chunksize']
HUMAN_READABLE_RATES = ['max_bandwidth', 'target_bandwidth']
SUPPORTED_CHOICES = {
'preferred_transfer_client': [
Expand Down Expand Up @@ -206,6 +208,7 @@ def create_transfer_config_from_runtime_config(runtime_config):
'multipart_threshold': 'multipart_threshold',
'multipart_chunksize': 'multipart_chunksize',
'max_bandwidth': 'max_bandwidth',
'io_chunksize': 'io_chunksize',
}
kwargs = {}
for key, value in runtime_config.items():
Expand Down
22 changes: 22 additions & 0 deletions awscli/topics/s3-config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ command set:
size that the CLI uses for multipart transfers of individual files.
* ``max_bandwidth`` - The maximum bandwidth that will be consumed for uploading
and downloading data to and from Amazon S3.
* ``io_chunksize`` - The maximum size of read parts that can be queued in-memory
to be written for a download.

For experimental ``s3`` configuration values, see the the
`Experimental Configuration Values <#experimental-configuration-values>`__
Expand Down Expand Up @@ -208,6 +210,26 @@ threads having to wait unnecessarily which can lead to excess resource
consumption and connection timeouts.


io_chunksize
------------

**Default** - ``256KB``
Copy link
Member

@kdaily kdaily Aug 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is the default set? I see we have some defaults configured as well, should it be added there?
https://github.com/aws/aws-cli/pull/9678/files#diff-280c24f20aa46551fbfd53f1910ece8ac396fae5de0956cf3555015592d45161L25

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default is set here:

io_chunksize=256 * KB,

We don't need to add it there since it's an optional param with a default value

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I'm missing something, since I don't see the RuntimeConfig object gets used anywhere else, but there is a docstring that was munged during lint/format changes that specifies the use of DEFAULTS:

# If the user does not specify any overrides,
# these are the default values we use for the s3 transfer
# commands.

https://github.com/aws/aws-cli/pull/9678/files#diff-280c24f20aa46551fbfd53f1910ece8ac396fae5de0956cf3555015592d45161L13-L15

The rest of the parameters respected from the s3 sub-section in the config file are also set in DEFAULTS.
There is a unit test for RuntimeConfig that checks if the object created matches what is in DEFAULTS. As is, io_chunksize won't be set when creating the RuntimeConfig object, though, only when creating the TransferConfig, like here:

runtime_config = self._get_runtime_config()

If this object has a new member, shouldn't that test reflect it?

assert runtime_config == transferconfig.DEFAULTS

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm not sure I understand what the problem is when the TransferConfig object's initializer has an explicit default value for io_chunksize. This is the behavior it uses today, ie AWS CLI will always set io_chunksize to 256KB. It's possible the CLI-specific defaults are there from v1, before botocore was vended just in case botocore decided to change its defaults. But I can just add it to our defaults if it'll make it easier


When a GET request is called for downloads, the response contains a file-like
object that streams data fetched from S3. Chunks are read from the stream and
queued in-memory for writes. ``io_chunksize`` configures the maximum size of
elements in the IO queue. This value can be specified using the same semantics
as ``multipart_threshold``, that is either as the number of bytes as an
integer, or using a size suffix.

Increasing this value may result in higher overall throughput by preventing
blocking in cases where large objects are downloaded in environments where
network speed exceeds disk write speed. It is recommended to only configure
``io_chunksize`` if overall download throughput is constrained by writes.
In cases where network IO is the bottleneck, it is recommended to configure
``max_concurrent_requests`` instead.


use_accelerate_endpoint
-----------------------

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/customizations/s3/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ def test_proxies_transfer_config_to_default_transfer_manager(self):
max_concurrent_requests=20,
max_queue_size=5000,
max_bandwidth=10 * MB,
io_chunksize=1 * MB,
)
transfer_manager = self.factory.create_transfer_manager(
self.params, self.runtime_config
Expand All @@ -240,6 +241,7 @@ def test_proxies_transfer_config_to_default_transfer_manager(self):
self.assertEqual(transfer_manager.config.max_request_concurrency, 20)
self.assertEqual(transfer_manager.config.max_request_queue_size, 5000)
self.assertEqual(transfer_manager.config.max_bandwidth, 10 * MB)
self.assertEqual(transfer_manager.config.io_chunksize, 1 * MB)
# These configurations are hardcoded and not configurable but
# we just want to make sure they are being set by the factory.
self.assertEqual(
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/customizations/s3/test_transferconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ def test_convert(self):
'max_bandwidth': 1024 * 1024,
'addressing_style': 'path',
'use_accelerate_endpoint': True,
'io_chunksize': 1024 * 1024,
# This is a TransferConfig only option, it should
# just be ignored if it's in the ~/.aws/config for now.
'max_in_memory_upload_chunks': 1000,
Expand All @@ -161,4 +162,5 @@ def test_convert(self):
assert result.max_request_concurrency == 3
assert result.max_request_queue_size == 4
assert result.max_bandwidth == 1024 * 1024
assert result.io_chunksize == 1024 * 1024
assert result.max_in_memory_upload_chunks != 1000
Loading