Add optional request and response compression#231
Open
jer-k wants to merge 1 commit intoPNixx:masterfrom
Open
Conversation
Contributor
Author
|
@PNixx I rebased in the streaming work. It appears it will be a decent undertaking to make the response compression work with streaming responses, although ClickHouse does support it. I updated the code and README to have response compression do anything if the streaming is happening. It's a bit clunky, but would appreciate any feedback on the approach. |
PNixx
reviewed
Feb 4, 2026
|
|
||
| require 'spec_helper' | ||
|
|
||
| RSpec.describe ActiveRecord::ConnectionAdapters::Clickhouse::Statement::ResponseProcessor do |
Owner
There was a problem hiding this comment.
rspec will run only single and cluster directories
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
ClickHouse supports request and response compression which is explained in the HTTP Interface - Compression docs.
READMEinformation on how to set up the compression attributes indatabase.ymlActiveRecord::ConnectionAdapters::Clickhouse::Compressionclass to handle the compression and compression use casesActiveRecord::ConnectionAdapters::Clickhouse::Statement::ResponseProcessoris coveredActiveRecord::ConnectionAdapters::Clickhouse::Compressionis coveredActiveRecord::ConnectionAdapters::Clickhouse::SchemaStatements#executetests added for a baseline and compression related.Motivation
We have monkey patched in this functionality to our application and have been using
brotlicompression for a few years now.Real World Testing
All these tests will be executed the same way, querying for a record by opening a Rails console and executing
UserEvent.first. I used mitmproxy to view the request and their headers.This is ensuring the base line and then all the different gems / algorithms are working.
Baseline - No compression
POST http://localhost:8123/?database=clickhouse_testing_ch&password=&user=default200 OK text/plain 600b 84msAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3Content-Encodingheader is presentThese are the
Net::HTTPdefaultsBaseline - Requesting compression without installing the required gems
No additional gem is installed here, but I'm requesting
brcompression. In this case, no compression will actually be added, requests function as normal.POST http://localhost:8123/?database=clickhouse_testing_ch&password=&user=default200 OK text/plain 600b 17msAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3Content-Encodingheader is presentgzip
Note - no additional gem is required for
gzip,Net::HTTPcan do this nativelyPOST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 326b 13msAccept-Encoding: gzipContent-Encoding: gzipContent-Encoding: gzipdeflate
Note - no additional gem is required for
deflate,Net::HTTPcan do this nativelyPOST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 314b 9msAccept-Encoding: deflateContent-Encoding: deflateContent-Encoding: deflatebr
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 315b 8msAccept-Encoding: brContent-Encoding: brContent-Encoding: brzstd
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 362b 8msAccept-Encoding: zstdContent-Encoding: zstdContent-Encoding: zstdlz4
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 415b 14msAccept-Encoding: lz4Content-Encoding: lz4Content-Encoding: lz4bz2
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 355b 9msAccept-Encoding: bz2Content-Encoding: bz2Content-Encoding: bz2snappy
I tried to implement snappy but ran into a couple issues.
First, ClickHouse currently doesn't support the response compression for
snappy. The issue is ClickHouse/ClickHouse#44885Secondly, when trying to compress the request data I got
I didn't want to block this whole implementation on
snappyso I decided to remove it as an option for now.xz
One caveat with
xzis that it does not work on Ruby 4.0.0 currently. This PR needs to be merged first win93/ruby-xz#13. When this is run on 4.0.0, therequirewill fail and no compression will be enabled. The request still works.The test below is on Ruby 3.4.7.
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 384b 25msAccept-Encoding: xzContent-Encoding: xzContent-Encoding: xzMixed br + lz4
POST http://localhost:8123/?database=clickhouse_testing_ch&enable_http_compression=1&password=&user=default200 OK text/plain 415b 22msAccept-Encoding: lz4Content-Encoding: brContent-Encoding: lz4