Async timeout downloading a large file using StreamingResponseBody on Spring Boot
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
StreamingResponseBody in Spring Boot writes directly to the OutputStream on a separate thread, allowing large file downloads without loading the entire file into memory. However, Spring's async request timeout (default 30 seconds) can terminate the download before it finishes. The fix is to increase or disable the async timeout via spring.mvc.async.request-timeout or by configuring AsyncSupportConfigurer.
The Problem
After 30 seconds, Spring terminates the async request and the client receives a truncated file or a timeout error.
Fix 1: Application Properties
Fix 2: WebMvcConfigurer
Fix 3: Per-Endpoint Timeout with Callable
For different timeouts on different endpoints:
Configure the timeout on the WebAsyncTask wrapper:
Complete Download Endpoint with Progress
Embedded Tomcat Connection Timeout
Besides Spring's async timeout, Tomcat has its own connection timeout:
Using Resource Instead of StreamingResponseBody
For simple file downloads, Resource may be simpler:
Resource-based responses are handled by Spring's built-in ResourceHttpMessageConverter, which streams efficiently. However, StreamingResponseBody gives you more control over the writing process (progress tracking, transformation, etc.).
Common Pitfalls
- Not setting
Content-Length: Without theContent-Lengthheader, browsers cannot show download progress. Set it with.contentLength(fileSize)or.header(HttpHeaders.CONTENT_LENGTH, String.valueOf(fileSize))when the size is known. - Forgetting about reverse proxy timeouts: Nginx, Apache, and cloud load balancers have their own timeout settings. Even if Spring is configured for 10 minutes, Nginx's default
proxy_read_timeoutof 60 seconds will kill the connection. Setproxy_read_timeout 600s;in the Nginx config. - Not flushing the output stream: Without
outputStream.flush()inside the write loop, the servlet container buffers the response. This delays the start of the download and uses more memory. Flush after each write or every few kilobytes. - Using
StreamingResponseBodyfor small files: For files under a few megabytes,StreamingResponseBodyadds unnecessary complexity. UseResourceorbyte[]responses instead — they are simpler and handle the response in one pass. - Thread pool exhaustion: Each
StreamingResponseBodyrequest occupies a thread for the entire download duration. With many concurrent downloads, the thread pool can be exhausted. Configure a dedicatedTaskExecutorwith enough threads, or use reactive WebFlux for truly non-blocking streaming.
Summary
StreamingResponseBodystreams large files without loading them into memory- Spring's async timeout (default 30s) kills long-running downloads — set
spring.mvc.async.request-timeout=-1or a higher value - Also configure Tomcat's
connection-timeoutand any reverse proxy timeouts (Nginx, ALB) - Set
Content-Lengthheader so browsers can show download progress - Flush the output stream regularly during writes to avoid buffering
- Use a dedicated thread pool for download endpoints to prevent thread exhaustion
Related reading
- async trio way to solve Hettinger's example
- Async two-way communication with Windows Named Pipes .Net
- Async update of array in Angular
- Async urlfetch on App Engine
- AsyncContext response does not match original incoming request?
- Asynchronous event triggers in a distributed system? (java)
- async void, await, and exceptions - why do exceptions thrown after ''await'' from the GUI thread require AsyncVoidMethodBuilder for marshaling?
- Async waterfall equivalent with Q

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.