Skip to main content
unbound mongodb at scale

Network Compression and End-to-End Payload Optimization

4 min read Chapter 45 of 72

Network Compression and End-to-End Payload Optimization

The Symptom

The telemetry platform’s application servers are in a different availability zone from the MongoDB servers. Network monitoring shows 450 Mbps of traffic between the application and database tiers during peak load. The inter-AZ bandwidth limit is 5 Gbps, but the 450 Mbps contributes $1,800/month in data transfer costs. Additionally, the network latency between AZs is 1.5ms, and larger payloads take proportionally longer to transfer.

The Cause

The MongoDB wire protocol sends BSON documents uncompressed by default. Each query response with 100 documents at 340 bytes each sends 34 KB of uncompressed BSON. At 1,000 queries/sec, that is 34 MB/sec of query responses alone. Add write acknowledgments, cursor batches, and keepalives: 450 Mbps total.

The Benchmark

Test network compression with different compressors:

// Configure driver with network compression
MongoClientSettings snappySettings = MongoClientSettings.builder()
    .applyConnectionString(connString)
    .compressorList(List.of(
        MongoCompressor.createSnappyCompressor()
    ))
    .build();

MongoClientSettings zstdSettings = MongoClientSettings.builder()
    .applyConnectionString(connString)
    .compressorList(List.of(
        MongoCompressor.createZstdCompressor()
    ))
    .build();

MongoClientSettings zlibSettings = MongoClientSettings.builder()
    .applyConnectionString(connString)
    .compressorList(List.of(
        MongoCompressor.createZlibCompressor()
            .withProperty(MongoCompressor.LEVEL, 6)
    ))
    .build();

Results for 100-document query response (34 KB uncompressed):

CompressorCompressed sizeRatioCompression timeDecompression time
None34 KB1.0x00
Snappy15.3 KB2.2x0.02ms0.01ms
Zstd8.9 KB3.8x0.08ms0.02ms
Zlib-69.5 KB3.6x0.15ms0.05ms

End-to-end query latency (same AZ, 0.2ms RTT):

Benchmark                           Mode  Cnt    Score    Error  Units
NetworkCompressionBench.noCompression  avgt  5  310.000 ± 12.000  us/op
NetworkCompressionBench.snappy        avgt    5  295.000 ± 10.000  us/op
NetworkCompressionBench.zstd          avgt    5  285.000 ± 11.000  us/op
NetworkCompressionBench.zlib          avgt    5  305.000 ± 14.000  us/op

Same AZ: negligible difference. The payload is small and network transit time is minimal.

End-to-end query latency (cross-AZ, 1.5ms RTT):

Compressorp50p95p99
None5.2ms8.5ms15ms
Snappy4.5ms7.2ms12ms
Zstd4.0ms6.5ms10ms
Zlib4.2ms7.0ms11ms

Cross-AZ: Zstd reduces p99 by 33%. The smaller payload transfers faster across the 1.5ms RTT link.

The Fix

Enable Zstd network compression in the MongoDB driver:

// FAST: Enable Zstd network compression
MongoClientSettings settings = MongoClientSettings.builder()
    .applyConnectionString(connString)
    .compressorList(List.of(
        MongoCompressor.createZstdCompressor(),
        MongoCompressor.createSnappyCompressor()  // Fallback
    ))
    .applyToConnectionPoolSettings(builder -> builder
        .maxSize(200)
        .minSize(20)
    )
    .build();

The driver negotiates compression with the server during the handshake. The first compressor in the list is preferred. If the server does not support Zstd (pre-4.2), it falls back to Snappy.

Enable on the server side:

# mongod.conf
net:
  compression:
    compressors: zstd,snappy

The Proof

After enabling Zstd network compression:

MetricNo compressionZstd compression
Network bandwidth (peak)450 Mbps140 Mbps
Monthly data transfer cost$1,800$560
Cross-AZ query p9915ms10ms
Driver CPU overheadbaseline+3%
Server CPU overheadbaseline+2%

The Trade-off

Network compression adds CPU overhead on both the driver (compression) and the server (decompression for incoming requests, compression for outgoing responses). The 5% total CPU increase is negligible on modern multi-core servers.

For same-datacenter deployments with sub-millisecond RTT, network compression provides minimal latency improvement. The CPU cost may outweigh the benefit. Enable it only if storage bandwidth is constrained or data transfer costs are significant.

For cross-region deployments (10-100ms RTT), network compression provides substantial latency improvement by reducing the bytes on the wire. The compression/decompression time (0.02-0.08ms) is dwarfed by the RTT savings.

The compressor list is negotiated per connection, not per operation. All operations on a connection use the same compressor. You cannot compress specific queries and leave others uncompressed. If compression overhead matters for specific operations, consider using separate MongoClient instances: one with compression for batch operations and one without for latency-sensitive operations.