Skip to content

Read request bodies lazily, fix wsgi performance regressions#63

Merged
posborne merged 1 commit into
mainfrom
posborne/fix-wsgi-performance-regression
Mar 23, 2026
Merged

Read request bodies lazily, fix wsgi performance regressions#63
posborne merged 1 commit into
mainfrom
posborne/fix-wsgi-performance-regression

Conversation

@posborne
Copy link
Copy Markdown
Member

With a large maximum (4GB) specified for http_body.read, we ended up with a very large allocation taking place in the host. In the case of this hostcall, at least, we do need to read the body in chunks for reasonable performance.

This change fixes that by ensuring that we perform reads in chunks; additionally, we now use a BufferedReader over our own RawIOBase which allows us to lazily read the bodies until later in execution (or not at all if the request body isn't read by the handler).

With a large maximum (4GB) specified for http_body.read,
we ended up with a very large allocation taking place in the
host.  In the case of this hostcall, at least, we do need to read the
body in chunks for reasonable performance.

This change fixes that by ensuring that we perform reads in chunks;
additionally, we now use a BufferedReader over our own RawIOBase
which allows us to lazily read the bodies until later in execution
(or not at all if the request body isn't read by the handler).
@posborne posborne requested a review from erikrose March 23, 2026 18:12
Copy link
Copy Markdown
Member

@erikrose erikrose left a comment

Choose a reason for hiding this comment

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

Looks great. Back to full speed (≈31fps) on my box. Thank you! :-D

Comment thread fastly_compute/utils.py
"""
return not self._closed

def readinto(self, b) -> int:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I couldn't come up with a type for b either. :-)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah, I was following a snippet that didn't have type annotations. Seems like maybe https://docs.python.org/3/library/collections.abc.html#collections.abc.Buffer might be the correct type for the protocol. I'm inclined to just leave it as this matches the definition provided by cpython internally (well, at least in https://github.com/python/cpython/blob/main/Lib/_pyio.py#L636).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Best not to prod the dragons. ;-) Buffer was my first choice as well, but it's not len()-able.

@posborne posborne merged commit 17bbee6 into main Mar 23, 2026
4 checks passed
@posborne posborne deleted the posborne/fix-wsgi-performance-regression branch March 23, 2026 22:03
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