Skip to content

Conversation

@jonathan343
Copy link
Contributor

@jonathan343 jonathan343 commented Oct 14, 2025

Summary

This PR integrates with the new aync CRT APIs introduced in awslabs/aws-crt-python#658 with the goal of addressing the high CPU usage reported in awslabs/aws-sdk-python#11.

The changes in this PR have been tested and successfully reduce CPU usage for examples such as the bidirectional nova_sonic.py. This change will be available in a new versions of smithy-http and aws-sdk-bedrock-runtime with no changes to the user experience.

Testing

  1. Checkout this PR locally
    • gh pr checkout 573
  2. Create a activate a Python virtual environment
    • uv venv && source .venv/bin/activate
  3. Install workspace dependencies
    • make install
  4. Install bedrock runtime sdk client
    • uv pip install aws-sdk-bedrock-runtime psutil pyaudio rx
  5. Download the monitor_cpu.py and bidirection.py test scripts.
  6. Run python monitor_cpu.py bidirection.py

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

[project.optional-dependencies]
awscrt = [
"awscrt>=0.23.10",
"awscrt~=0.28.2",
Copy link
Contributor Author

@jonathan343 jonathan343 Oct 16, 2025

Choose a reason for hiding this comment

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

Note

Setting awscrt v0.28.2 is necessary since we need the change added in awslabs/aws-crt-python#688. Also, this was previously unbounded which has been fine for now, but constraining it to ~=0.28.2 is much safer for customers

@jonathan343 jonathan343 marked this pull request as ready for review October 16, 2025 19:49
@jonathan343 jonathan343 requested a review from a team as a code owner October 16, 2025 19:49
JordonPhillips
JordonPhillips previously approved these changes Oct 17, 2025
):
# AsyncByteStream has async read method but is not iterable
while True:
chunk = await body.read(65536) # Read in 64KB chunks
Copy link
Contributor

Choose a reason for hiding this comment

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

Why this number in particular?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was a common buffer size I'd come across, however, I do see our default value is -1 which will read all available data at once.

@runtime_checkable
class AsyncByteStream(Protocol):
"""A file-like object with an async read method."""
async def read(self, size: int = -1) -> bytes: ...

Do you prefer going with the default?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to use the default in 02e3e20. Let me know what you think

Copy link
Contributor

Choose a reason for hiding this comment

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

The default is for the protocol - when you call .read on a file-like object, for instance, it just reads everything. We should read in chunks, i was just wondering why that size in particular. Just make it a constant or something that's configurable on the crt client and we'll be good.

Copy link
Contributor

@JordonPhillips JordonPhillips left a comment

Choose a reason for hiding this comment

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

See response to other comment - we should still limit how much we read at a time from a file-like object, I just wanted to know why that number.

@jonathan343 jonathan343 merged commit c0176d2 into develop Oct 21, 2025
6 checks passed
@jonathan343 jonathan343 deleted the high-cpu-fix branch October 21, 2025 14:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants