장성호 and Mark,
On 10/31/25 4:42 AM, Mark Thomas wrote:
On 31/10/2025 02:34, 장성호 wrote:
Hi Tomcat developers,
I would like to propose adding configurable gzip compression
parameters to
Tomcat's HTTP compression implementation. This enhancement would give
users
fine-grained control over compression behavior to optimize for their
specific
use cases.
---
Problem Statement
Currently, Tomcat's `GzipOutputFilter` uses hardcoded values for gzip
compression:
- Compression level: Always uses `Deflater.DEFAULT_COMPRESSION` (-1)
I see this being set in GZIPOutputStream and not in GzipOutputFilter.
- Buffer size: Fixed at 512 bytes
- Sync flush: Hardcoded to `true`
This limitation prevents users from:
1. Tuning compression level for speed vs. compression ratio trade-offs
2. Adjusting buffer sizes for different response patterns (streaming
vs. bulk)
3. Controlling sync flush behavior for different latency requirements
Users have raised this issue before (e.g., [Spring Boot issue #25748]),
where the Spring Boot team noted that Tomcat doesn't expose these
configuration options.
---
Proposed Solution
Add three new configurable properties to `AbstractHttp11Protocol`
and HTTP/2’s compression logic:
1. gzipLevel (int, default: -1)
- Valid range: -1 (default), 0 (no compression), 1–9
- Maps directly to `java.util.zip.Deflater` compression levels
>>>> 2. gzipBufferSize (int, default: 512)
- Internal buffer size for `GZIPOutputStream`
- Must be positive
3. gzipSyncFlush (boolean, default: true)
- Controls whether flush() calls invoke the deflater’s SYNC_FLUSH
- Important for streaming scenarios
---
Implementation Details
The implementation requires small changes in the following files:
1. GzipOutputFilter.java
- Add three private fields with getters/setters
- Use configurable values instead of hardcoded ones
I don't see a way to change the compression level on a GZIPOutputStream.
I think you will need to subclass GZIPOutputStream in order to customize
it. It's doable, but does require some additional work in
GzipOutputFilter (by adding a new GZIPOutputStream subclass).
2. CompressionConfig.java
- Add new fields and validation logic
- Validate compression level (-1 to 9) and buffer size (>0)
3. AbstractHttp11Protocol.java
- Expose new properties delegating to CompressionConfig
- Enables configuration via `server.xml` or programmatic API
4. Http11Processor.java and StreamProcessor.java - Pass configured
values to `GzipOutputFilter` instances
---
Configuration Examples
server.xml
```xml
<Connector port="8080" protocol="HTTP/1.1"
compression="on"
gzipLevel="6"
gzipBufferSize="8192"
gzipSyncFlush="true" />
```
Benefits
Performance tuning: Balance CPU vs. bandwidth by adjusting compression
level
Streaming optimization: Control buffer size and sync flush for
real-time responses
Framework integration: Enables frameworks (Spring Boot, Quarkus, etc.)
to expose these settings
Consistency: Aligns with configuration practices in Jetty and Undertow
Target Versions
This enhancement can be safely applied to:
Tomcat 11.0.x (main)
Tomcat 10.1.x
Tomcat 9.0.x
It is non-breaking and low-risk, as it only adds configuration hooks.
Patch Availability
A working implementation is available locally.
If the community is interested, I can open a Bugzilla enhancement ticket
and submit patches for Tomcat 9 → 11 along with test cases
and documentation updates.
Would the Tomcat community be interested in reviewing this enhancement?
I would. If you can provide a PR for review, that would be great.
I do have concerns about using SYNC_FLUSH==false. There is a high risk
that that will break things as the expectation when the output is
flushed is that all the data written to the output is passed to the
client. If data remains in the compression buffer than is going to cause
problems. If there are use cases where this configuration makes sense,
it needs to come with a very strong health warning.
+1
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]