New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FileStreamResult resulting in significantly more I/O than client is requesting #55606
Comments
This has to do with built in write buffers in the stack. We don't know when the client is going to call Read, we only know they want us to send the file, so as much is sent as possible until all the buffers between the client and the server fill up.
|
Thanks for the quick reply, that makes sense. I see no effect changing the Kestrel Are you aware of any other response buffer settings which can be configured on the web server level (IIS or Kestrel)? We stream a lot of video files and see our disk capacity easily being saturared when users skip around in videos. Causing for example 10MB being read from the |
How much control do you have over the client? Can you have them send |
Most clients are browser based where we do not have much control. Embedding the video in the browser like that: results in the browser issuing an initial request on page load. In the above mentioned request the browser only reads about 130KB of data (for rendering the initial video thumbnail). Often browser clients leave the page after a short time, having the effect about using 20x more disk I/O than necessary. Note that this is getting worse with larger video files, I sometimes see 10MB written to the response body where only about 150KB of data was actually read by the client. |
Thanks, I tried it and verified that this is giving me the same results. The browser client initially sends this range header request:
Getting the following response from the API:
The backend still reads 2.4MB from the disk and writes the file completely to the response body while only 130KB are actually arriving/being read at the browser client. |
Here's an interesting example where you can limit the range: This would require some manual limiting on the filestream, or you could modify the request range header before generating the response. |
Is there an existing issue for this?
Describe the bug
I have troubles understanding why returning a
FileStreamResult
from my API is causing a large amount of bytes being read from the underlyingFileStream
without the client actually starting to read from theHttpResponseMessage
stream.I also observed different results running on Kestrel vs IIS Express.
Running on Kestrel the output is:
Total bytes read: 524288
Running on IIS Express the whole file is read:
Total bytes read: 2498125
Based on the client code below which does not actually read from the stream I would not expect that the server reads the whole file and writes it to the response body.
Is it possible to prevent this scenario and actually only write bytes to the response body which the client requested to read?
(calling
stream.ReadAsync(...)
)Response buffering is not enabled and the default response buffer settings for Kestrel are lower than what I am seeing here.
The problem is that this is causing a lot of unnecessary disk I/O if clients are not going to read the stream or are aborting the request.
Client
Server
Expected Behavior
No response
Steps To Reproduce
No response
Exceptions (if any)
No response
.NET Version
8.0.204
Anything else?
No response
The text was updated successfully, but these errors were encountered: