Skip to content

CONCEPT Cited by 1 source

Client-side query compression

Definition

Client-side query compression is the compression of a database query's request payload (or batch of payloads) by the client before it crosses the network, using a general- purpose byte-compressor (Snappy, gzip, Brotli, LZ4, zstd) applied to the serialised wire message. The server decompresses on receipt. It is a structural property of the transport protocol: the transport must negotiate a compression algorithm up-front (via HTTP's Content-Encoding / Accept-Encoding or gRPC's grpc-encoding header).

Why this concept needs its own page

The MySQL binary protocol has a "compression protocol" option but it applies to the entire connection payload, not per-query — and modern MySQL clients rarely enable it. Practically, the MySQL binary protocol transmits query text and bulk INSERT values uncompressed. HTTP-based database transports (PlanetScale HTTP API, Snowflake REST, Supabase PostgREST) get compression for free from the HTTP ecosystem.

The insert-path asymmetry

The concept becomes load-bearing on the write path:

  • Read path (SELECT result): the server compresses the result set before sending; both MySQL (with compression enabled) and HTTP can do this. Parity.
  • Write path (bulk INSERT ... VALUES (...), (...), ...): the client sends a multi-kilobyte (or multi-megabyte) payload to the server. MySQL clients rarely compress on the client-side; HTTP clients get Content-Encoding: gzip / snappy automatically if the stack is configured for it. This is the structural asymmetry.

Robenolt (PlanetScale, 2023-01-04): "Unlike the SELECT case, this is an opportunity for our HTTP API to use client-side compression, which we cannot do with the MySQL protocol. The effects of this can be drastically seen in the high latency network case since we are uploading a decent amount of data per query." (Source: sources/2026-04-21-planetscale-faster-mysql-with-http3.)

Mechanism (PlanetScale's implementation)

PlanetScale's HTTP API uses Snappy as the wire compressor, chosen for its CPU efficiency at the cost of compression ratio (unlike gzip which optimises for ratio at higher CPU cost). Snappy is applied to the protobuf body encoded by connect-go before the HTTP/2 or HTTP/3 frame is sent.

The typical compressible payload shape is a bulk INSERT: repetitive column names, quoted string values, timestamps — all highly compressible. A ~100 KB bulk INSERT of 250 rows compresses to ~20-30 KB with Snappy; the high-latency transfer time savings dominate the CPU cost at the client.

Contrast with server-side compression

Server-side response compression (MySQL's compression protocol, HTTP's server-driven Content-Encoding) reduces download time on the read path. Client-side request compression reduces upload time on the write path.

Most serverless / edge deployment contexts have asymmetric network links — upstream is slower than downstream (per ISP policy, WAN egress pricing, or cellular-uplink limitations). Client-side compression of writes matters disproportionately to server-side compression of reads in these shapes.

Why this is structural to HTTP

  • HTTP has built-in Content-Encoding negotiation. Clients advertise supported compression in Accept-Encoding; servers respond with the chosen compression in Content-Encoding. The client library handles decompression transparently.
  • Every HTTP client runtime includes compression. Node's http module, Go's net/http, Python's urllib3, Java's HttpClient all handle Content-Encoding out of the box.
  • HTTP/2 and HTTP/3 don't add new compression negotiation. They inherit HTTP/1.1's Content-Encoding; HTTP/2 adds HPACK (a specialised header compression) but body compression stays the same.

Why this is missing from MySQL-protocol clients

  • MySQL's compression protocol is connection-level, not per-query. Once enabled, every packet is compressed; every packet has the compression overhead. For small queries this is net negative.
  • Driver ecosystem: few client libraries enable compression by default (the libmysqlclient flag MYSQL_OPT_COMPRESS is off by default); most ORMs don't expose it. The network-bandwidth saving is invisible to the application layer.
  • No per-query control: you can't compress bulk INSERTs while leaving SELECT 1 uncompressed.

Seen in

Last updated · 550 distilled / 1,221 read