Skip to content

introduce zstd for compression - #4185

Open
gipeshka wants to merge 4 commits into
zio:mainfrom
LiveIntent:introduce-zstd-for-compression
Open

introduce zstd for compression#4185
gipeshka wants to merge 4 commits into
zio:mainfrom
LiveIntent:introduce-zstd-for-compression

Conversation

@gipeshka

Copy link
Copy Markdown

Addressing #4184.

Not including zstd jni, to use this I assume one would have to manually enable it (just like one has to do it now for zio-http to start accepting zstd content-encoding)

Copilot AI review requested due to automatic review settings June 24, 2026 14:52
@CLAassistant

CLAassistant commented Jun 24, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@netlify

netlify Bot commented Jun 24, 2026

Copy link
Copy Markdown

Deploy Preview for zio-http ready!

Name Link
🔨 Latest commit 2ce45f2
🔍 Latest deploy log https://app.netlify.com/projects/zio-http/deploys/6a3bef29ffdf390008d2e85f
😎 Deploy Preview https://deploy-preview-4185--zio-http.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds server-side zstd response compression support (Accept-Encoding negotiation via Netty HttpContentCompressor), aligning with the existing ability to accept Content-Encoding: zstd when users provide the JNI dependency.

Changes:

  • Introduces CompressionOptions.Zstd plus ZstdConfig and a CompressionOptions.zstd(...) constructor.
  • Extends CompressionOptions.config parsing to recognize "type" = "zstd" and read zstd-specific parameters.
  • Adds Netty conversion support for zstd via StandardCompressionOptions.zstd(...).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
zio-http/shared/src/main/scala/zio/http/Server.scala Adds zstd compression option/config and updates config parsing to support selecting zstd.
zio-http/jvm/src/main/scala/zio/http/netty/model/Conversions.scala Maps the new zstd compression option into Netty StandardCompressionOptions.zstd(...).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 429 to 447
@@ -414,12 +434,15 @@ object Server extends ServerPlatformSpecific {
zio.Config.int("quantity").withDefault(BrotliConfig.DefaultQuality) ++
zio.Config.int("lgwin").withDefault(BrotliConfig.DefaultLgwin) ++
zio.Config.string("mode").map(Mode.fromString).withDefault(BrotliConfig.DefaultMode) ++
zio.Config.string("type")
).map { case (level, bits, mem, quantity, lgwin, mode, typ) =>
zio.Config.string("type") ++
zio.Config.int("block").withDefault(ZstdConfig.DefaultBlockSize) ++
zio.Config.int("maxencode").withDefault(ZstdConfig.DefaultMaxEncodeSize)
).map { case (level, bits, mem, quantity, lgwin, mode, typ, block, maxencode) =>
typ.toLowerCase match {
case "gzip" => gzip(level, bits, mem)
case "deflate" => deflate(level, bits, mem)
case "brotli" => brotli(quantity, lgwin, mode)
case "zstd" => zstd(level, block, maxencode)
}
}
Comment thread zio-http/shared/src/main/scala/zio/http/Server.scala Outdated
@netlify

netlify Bot commented Jun 24, 2026

Copy link
Copy Markdown

Deploy Preview for zio-http ready!

Name Link
🔨 Latest commit fdbbd4c
🔍 Latest deploy log https://app.netlify.com/projects/zio-http/deploys/6a9ad92fafa12100090f5b01
😎 Deploy Preview https://deploy-preview-4185--zio-http.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@987Nabil

Copy link
Copy Markdown
Contributor

@gipeshka Please fix the build. Rebase might just do it

@gipeshka
gipeshka force-pushed the introduce-zstd-for-compression branch from 348ecb6 to dfcbdf6 Compare July 1, 2026 16:21
@gipeshka

gipeshka commented Jul 1, 2026

Copy link
Copy Markdown
Author

@987Nabil thanks for letting me know, it's fixed now

@987Nabil 987Nabil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a functional bug in the zstd defaults — see inline comment. The blockSize/maxEncodeSize defaults are swapped relative to Netty's actual ZstdConstants. With the current values, CompressionOptions.zstd() (no args) sets maxEncodeSize = 65536, so any response body that compresses to more than 64 KB will throw (maxEncodeSize bounds the largest compressible object), while blockSize = Integer.MAX_VALUE is backwards too. Everything else (Conversions.scala mapping, param order into StandardCompressionOptions.zstd(level, blockSize, maxEncodeSize), config parsing wiring, CI/Mima) checks out — this is the one blocking issue.

Comment thread zio-http/shared/src/main/scala/zio/http/Server.scala Outdated
@gipeshka
gipeshka force-pushed the introduce-zstd-for-compression branch from 19bf52c to 31d500d Compare July 6, 2026 09:08
@gipeshka
gipeshka requested review from 987Nabil and Copilot July 6, 2026 09:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +441 to +445
typ.toLowerCase match {
case "gzip" => gzip(level, bits, mem)
case "deflate" => deflate(level, bits, mem)
case "brotli" => brotli(quantity, lgwin, mode)
case "zstd" => zstd(level, block, maxencode)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gipeshka this seems to be a legit concern

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. @987Nabil what would be the preferred way of solving it? Would isolating level for zstd under a dedicated config prefix like zstdlevel work?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@987Nabil I've adjusted it via optional. Please have a look

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (3)

zio-http/shared/src/main/scala/zio/http/Server.scala:422

  • All sibling public compression factories document that their defaults correspond to Netty's default option object, but the newly added zstd factory omits that API documentation. Document the same default relationship here so callers can understand the three otherwise non-obvious tuning parameters.
      def zstd(

zio-http/shared/src/main/scala/zio/http/Server.scala:321

  • The new supported encoding is not represented by the typed header API. Header.AcceptEncoding still exposes zstd only as Unknown, and Header.ContentEncoding.parse drops zstd, so a response compressed by this option cannot be observed through response.header(Header.ContentEncoding). Add Zstd variants to both header algebras, update their parsers/rendering, and cover them in HeaderSpec.
      final case class Zstd(cfg: ZstdConfig)       extends CompressionOptions { val name = "zstd"    }

zio-http/jvm/src/main/scala/zio/http/netty/model/Conversions.scala:174

  • This new conversion branch has no end-to-end coverage, although ResponseCompressionSpec verifies the existing response codecs. Add a test-scoped zstd-jni dependency and an integration test that enables only this option, requests Accept-Encoding: zstd, verifies Content-Encoding: zstd, and decompresses the body; a test-scoped dependency would not impose JNI on library consumers.
      case CompressionOptions.Zstd(cfg)    =>
        StandardCompressionOptions.zstd(cfg.level, cfg.blockSize, cfg.maxEncodeSize)

gipeshka and others added 4 commits September 4, 2026 16:43
@gipeshka
gipeshka force-pushed the introduce-zstd-for-compression branch from 141aaa5 to fdbbd4c Compare September 4, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants