Set an in-memory decode ceiling for WebClient payloads and stream large responses instead of merely lifting the limit.
Spring WebFlux codec memory budget: distinguish aggregation from streaming
Aggregation has a ceiling
A WebClient call that decodes one JSON receipt document may buffer bytes before producing an object. The codec maxInMemorySize setting places a cap on that aggregation. When a partner sends a much larger body, raising the cap to match its biggest possible response multiplies memory exposure by concurrent requests. Decide whether that body is legitimate; if so, change the processing shape to a stream or file transfer rather than silently accepting an unbounded object. Response ownership still matters when handling status branches.
Size the limit from a contract
Measure a normal receipt response, allow bounded headroom and configure the client that calls that partner. The example caps in-memory decoding at 384 KiB for one client. A separate client for genuinely large exports may use a different strategy. This setting does not cap every byte travelling through the network and does not replace a proxy request-size limit. A stream can still accumulate unbounded data if downstream code calls collectList or joins all buffers.
Probe failure and recovery
Return a payload just below the limit, one above it, and a chunked response that never ends. Verify a predictable failure for the oversized aggregate, a response deadline for the endless stream, and no retained connection after cancellation. Repeated oversize failures should not exhaust the connection pool. Reactive demand governs downstream consumption, while cancellation governs stopped work.
Implementation contract
@Bean
WebClient receiptPartnerClient(WebClient.Builder managedBuilder) {
return managedBuilder
.codecs(codecs -> codecs.defaultCodecs()
.maxInMemorySize(384 * 1024))
.build();
}Cost and verification
The limit bounds memory per aggregated response, not the number of concurrent responses. At 384 KiB each, 47 simultaneous decodes can still reserve substantial heap before object allocation and application processing.
Common Mistakes
- Do not solve every DataBufferLimitException by setting a very large global cap.
- Do not collect an entire stream into a list and call it streaming.
- Do not treat codec memory limits as request or response deadlines.
Read next
Spring WebClient exchangeToMono: decode the response inside its callback, Spring reactive foundations: request values and cancel a subscription, Spring WebFlux cancellation: observe downstream cleanup without undoing work, Spring RestClient read timeout: reject a server that accepts but stalls, Spring Boot tracing across RestClient: construct the client from Boot's builder.
