How To Stream Chunked Response With Spring Boot RestController
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
If you want a Spring Boot controller to send data progressively instead of buffering the entire response first, you need a streaming response type. In Spring MVC, the usual choices are StreamingResponseBody, ResponseBodyEmitter, or SseEmitter, depending on the protocol and payload style. For ordinary chunked HTTP output, StreamingResponseBody is often the clearest starting point.
Why Chunked Streaming Helps
Chunked responses are useful when:
- the response is large
- data becomes available incrementally
- the client should start processing before the full payload exists
- you want to avoid holding the whole response body in memory
This is common for report export, log streaming, generated text, and long-running downloads.
Basic StreamingResponseBody Example
StreamingResponseBody lets you write directly to the response output stream.
Each flush gives the client a chance to receive the next chunk immediately instead of waiting for the whole loop to finish.
ResponseBodyEmitter for Higher-Level Emission
If you prefer sending serializable objects or text chunks through a higher-level API, use ResponseBodyEmitter.
This is convenient, but you still need to think about executor management and error handling.
When to Use SseEmitter Instead
If the client expects Server-Sent Events rather than generic chunked text, use SseEmitter. That gives you the text/event-stream protocol and event semantics.
Use SseEmitter for browser event streams. Use StreamingResponseBody or ResponseBodyEmitter for generic chunked responses.
Buffering Can Defeat Streaming
A common surprise is that the code flushes, but the client still receives everything at once. That can happen because of:
- reverse proxies buffering the response
- servlet container buffering
- the client reading only after connection close
- response compression changing the behavior
So successful server code is only part of the story. The whole HTTP path has to allow streaming.
Keep the Work Off the Request Thread if Necessary
If each chunk depends on slow work, consider asynchronous execution or a dedicated executor. Blocking the request thread for a long stream may be acceptable in small systems, but it becomes a capacity problem under load.
The right design depends on expected concurrency and response duration.
Common Pitfalls
- Returning a normal object or
Stringand expecting Spring to send it as progressive chunks automatically. - Forgetting to flush the output stream, which can delay chunk delivery.
- Choosing
SseEmitterwhen the client really wants generic chunked HTTP, not event-stream semantics. - Testing only locally and missing buffering introduced by proxies or production infrastructure.
- Starting background threads manually without thinking about thread management and error handling.
Summary
- Use a streaming response type when you want to send data incrementally from a Spring controller.
- '
StreamingResponseBodyis the simplest option for generic chunked output.' - '
ResponseBodyEmitteris useful when you want higher-level chunk emission.' - '
SseEmitteris for Server-Sent Events, not generic streaming.' - Successful streaming depends on the full request path, including proxies and client behavior.
Related reading
- How to synchronously load a csv file into memory before handling HTTP requests
- How to terminate a thread blocking on socket IO operation instantly?
- How to train and evaluate simultaneously in Object Detection API ?
- How to trigger message send of Fastapi websocket outside of Fastapi app
- How to subtract X day from a Date object in Java?
- How to subtract X days from a date using Java calendar?
- How to turn off or handle camelCasing in JSON response ASP.NET Core?
- How to turn on front flash light programmatically in Android?

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.