Thanks again for the valuable feedback on my previous proposal.

I’ve opened a PR (#914 <https://github.com/apache/tomcat/pull/914>) that
reflects those suggestions.


In this update:


   -

   I removed the SYNC_FLUSH configuration code, as recommended.

   -

   I simply use an anonymous subclass of GZIPOutputStream to configure the
   compression level.



Please let me know if you have any further concerns or suggestions about
this approach.


Best regards,




2025년 10월 31일 (금) 오후 8:45, Christopher Schultz <[email protected]>님이
작성:

> 장성호 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]
>


-- 
*장성호*
Server Platform Developer, Server Platform Team
010-3868-8634 | [email protected]
서울특별시 강남구 테헤란로 142, 4층, 10층, 11층, 12층, 13층, 22층, 23층(역삼동, 아크플레이스) (06236)
[image: Toss BI]

Reply via email to