ASP.NET Core › File Uploads & Streaming Large Files

How do you stream a large file back to the client as a download response without loading the entire file into memory first?

Intermediate

Answer

Returning a FileStreamResult (via File(stream, contentType) or Results.Stream() in minimal APIs) with an open stream lets ASP.NET Core copy bytes from the stream directly to the response body incrementally as they're read, rather than requiring the entire file's bytes to be loaded into a byte array in memory before the response can begin sending.
[HttpGet("download/{id}")]
public async Task<IActionResult> Download(int id) {
    var stream = await _storageService.OpenReadStreamAsync(id);
    return File(stream, "application/octet-stream", "report.pdf");
}

// Minimal API equivalent
app.MapGet("/download/{id}", async (int id, IStorageService storage) => {
    var stream = await storage.OpenReadStreamAsync(id);
    return Results.Stream(stream, "application/octet-stream", "report.pdf");
});
Real-world example A reporting API serving multi-hundred-megabyte generated PDF reports streams them directly from blob storage to the client response, keeping server memory usage constant regardless of file size instead of loading each report fully into a byte array first.

Common follow-ups: What's the difference between FileStreamResult and FileContentResult in terms of memory usage?;How does this interact with range requests for resumable downloads?