Spring Boot
HTTP Response
Compression
User-Agent
Troubleshooting

Spring boot http response compression doesn't work for some User-Agents

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Spring Boot response compression can appear inconsistent across clients because compression is negotiated, not forced. If some user agents receive compressed responses and others do not, the root cause is usually request headers, content type constraints, minimum-size thresholds, proxy behavior, or container-specific handling. Developers often focus only on server.compression.enabled=true, but reliable troubleshooting requires checking the full request/response path including load balancers and CDNs. This article explains why compression may fail for specific user agents and how to verify and fix it in a Spring Boot application.

Core Sections

1. Verify server-side compression configuration

Start with explicit settings in application.yml:

yaml
1server:
2  compression:
3    enabled: true
4    min-response-size: 1024
5    mime-types: text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json,application/xml

If the payload is below min-response-size, it may be returned uncompressed. Also ensure MIME type is in the allow-list.

2. Confirm client negotiation headers

Compression only occurs when the client advertises support via Accept-Encoding.

bash
curl -I -H 'Accept-Encoding: gzip' https://api.example.com/data

Expected response includes:

  • Content-Encoding: gzip
  • Vary: Accept-Encoding

Some bots or embedded clients omit Accept-Encoding; in that case, the server should correctly send plain content.

3. Investigate user-agent filtering and intermediaries

Older servlet containers and custom filters sometimes disable compression for problematic user agents. Also check reverse proxies (Nginx, Apache, CDN) that may strip or alter encoding headers.

For Nginx in front of Spring Boot, avoid double-compression conflicts. Decide one layer as authoritative (proxy or app), then configure the other accordingly.

4. Validate response types and endpoints

Compression commonly fails on endpoints returning binary streams, already-compressed content (e.g., .zip), or incompatible media types.

java
1@GetMapping(value = "/report", produces = MediaType.APPLICATION_JSON_VALUE)
2public ResponseEntity<String> report() {
3    return ResponseEntity.ok(largeJsonPayload());
4}

If controller methods return application/octet-stream or custom types not listed, Boot may skip compression.

5. Add targeted diagnostics

Use access logs and integration tests to compare requests by user agent and header set.

bash
curl -I -A 'Mozilla/5.0' -H 'Accept-Encoding: gzip' https://api.example.com/data
curl -I -A 'CustomClient/1.0' https://api.example.com/data

This isolates whether behavior differences are expected negotiation outcomes or configuration bugs.

6. Container and version considerations

Spring Boot behavior depends on embedded container (Tomcat/Jetty/Undertow) and version defaults. After upgrades, re-validate compression behavior because defaults or compatibility rules can shift.

Pin your configuration explicitly instead of relying on defaults.

Validation and production readiness

A reliable solution should include explicit validation and observability, not just a working snippet. Add representative test inputs for normal flow, malformed input, and boundary values so behavior is stable under change. Where timing or throughput matters, keep a small benchmark scenario and run it after refactors to catch accidental slowdowns early. If external systems are involved, include retry, timeout, and failure-path tests to verify the system degrades gracefully rather than hanging or failing silently.

Operationally, document assumptions close to the implementation: dependency versions, environment requirements, timezone or locale expectations, and any platform-specific behavior. Add structured logs for key decision points and failures so production incidents are diagnosable without reproducing every condition locally. For teams, define a minimal rollout checklist that covers backward compatibility, monitoring alerts, and rollback steps. These checks reduce incidents caused by integration gaps, which are more common than syntax errors in real deployments.

Common Pitfalls

  • Assuming compression should apply even when client omits Accept-Encoding.
  • Forgetting that small responses below threshold are intentionally uncompressed.
  • Enabling compression in both proxy and app layers without clear ownership.
  • Missing Vary: Accept-Encoding, causing cache correctness issues.
  • Debugging only application code while proxy/CDN rewrites headers downstream.

Summary

When Spring Boot compression appears to fail for certain user agents, the issue is usually negotiation or infrastructure, not random behavior. Validate request headers, MIME type eligibility, minimum-size thresholds, and proxy interactions. Use explicit configuration and header-based tests to isolate each layer. With these checks, compression behavior becomes predictable and consistent across supported clients.


Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track 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.

Practice system design

All Rights Reserved.