Overview
snappy wraps libsnappy — Google’s compression library designed for extreme throughput rather than maximum ratio. A single core can compress ~400 MB/s and decompress over 1 GB/s on typical hardware, making Snappy ideal anywhere CPU time matters more than storage savings.
Unlike gzip or zstd, Snappy makes no attempt at entropy coding — it uses a fast LZ77 variant with fixed Huffman-like literals. This gives predictable latency with no configuration knobs. Pass bytes in, get compressed bytes out.
Requires libsnappy-dev. Ubuntu/Debian: sudo apt install libsnappy-dev
Performance
Benchmarks measured on an Intel i7 (64-bit, single thread). Results vary by data compressibility.
| Operation | Throughput | Notes |
|---|---|---|
| Compress | ~250–500 MB/s | Text/JSON data; lower end for highly entropic input |
| Decompress | ~1–2 GB/s | Consistently fast regardless of data type |
| Ratio (text) | ~1.5–2x | HTML/JSON/logs compress well |
| Ratio (binary) | ~1.0–1.3x | Already-compressed data: minimal overhead |
Comparison with other compression libraries
| Library | Speed vs Snappy | Ratio vs Snappy | Best for |
|---|---|---|---|
| snappy | — (baseline) | — (baseline) | High-throughput pipelines, intermediate data |
| lz4 | Similar / slightly faster decompress | Similar | Real-time streaming, network buffers |
| zstd | Much slower | Much better | Long-term storage, network transfer |
| bzip2 | Much slower | Better | Archival, compatibility |
| gzip | 3–5x slower compress, 2–3x slower decompress | ~30% better | Web delivery, compatibility |
| brotli | Much slower | Better | Web assets, text compression |
Quick Start
Compress and decompress a string
uses snappy;
var original := '{"user":"alice","action":"login","ts":1710000000}';
var compressed := Compress(original);
var restored := Decompress(compressed);
WriteLn('Original : ' + IntToStr(Length(original)) + ' bytes');
WriteLn('Compressed: ' + IntToStr(Length(compressed)) + ' bytes');
WriteLn('Restored : ' + restored);
Compress with stats
uses snappy;
var stats := CompressWithStats(payload);
WriteLn('Ratio : ' + FloatToStr(stats.Ratio));
WriteLn('Speed : ' + FloatToStr(stats.SpeedMBps) + ' MB/s');
WriteLn('In : ' + IntToStr(stats.InputSize) + ' bytes');
WriteLn('Out : ' + IntToStr(stats.CompressedSize) + ' bytes');
Validate before decompress
uses snappy;
if IsValidCompressed(blob) then
begin
var expectedSize := GetUncompressedLength(blob);
WriteLn('Will expand to: ' + IntToStr(expectedSize) + ' bytes');
var data := Decompress(blob);
end
else
WriteLn('Not a valid snappy stream');
One-Shot API
These functions operate on an entire buffer in one call. They are the simplest and fastest path for most use cases.
| Function | Description |
|---|---|
| Compress(Data) | Compress Data using Snappy and return the compressed bytes |
| Decompress(Data) | Decompress a Snappy-compressed buffer and return the original bytes |
| CompressWithStats(Data) | Compress and return a TSnappyStats record with size and speed metrics |
uses snappy;
{ Compress a large log batch before writing to Kafka }
var logBatch := BuildLogBatch(events);
var wire := Compress(logBatch);
KafkaProduce(topic, wire);
Validation API
Inspect a compressed buffer without fully decompressing it. Useful for checking untrusted data before allocating output memory.
| Function | Description |
|---|---|
| IsValidCompressed(Data) | Returns True if Data is a well-formed Snappy stream |
| GetUncompressedLength(Data) | Read the uncompressed size header without decompressing. Returns Int64. |
Call GetUncompressedLength first to check the output size before decompressing. Pair with MaxCompressedLength on the compress side for safe buffer pre-allocation.
File API
Compress or decompress entire files directly on disk. The output file is written atomically; SrcPath is not modified.
| Procedure | Description |
|---|---|
| CompressFile(SrcPath, DstPath) | Read SrcPath, compress, write result to DstPath |
| DecompressFile(SrcPath, DstPath) | Read a .snappy file at SrcPath, decompress, write to DstPath |
uses snappy;
{ Compress a TSV export for archival }
CompressFile('/var/data/export.tsv', '/var/data/export.tsv.snappy');
{ Later: restore for processing }
DecompressFile('/var/data/export.tsv.snappy', '/tmp/export.tsv');
Framing Format API
The Snappy framing format wraps raw Snappy blocks in a stream container with checksums. It is the wire format used by Kafka, Hadoop, and other tools. Use these functions when you need interoperability with external systems.
| Function | Description |
|---|---|
| CompressFramed(Data) | Compress using the Snappy framing format (stream identifier + CRC chunks) |
| DecompressFramed(Data) | Decompress framing-format data; verifies chunk checksums |
uses snappy;
{ Produce a Kafka message with Snappy framing compression }
var payload := SerializeAvro(record);
var framed := CompressFramed(payload);
KafkaProduce(topic, framed);
{ Consume and decompress }
var raw := DecompressFramed(KafkaConsume(topic));
Compress/Decompress produce raw Snappy blocks (no checksums, no stream container). CompressFramed/DecompressFramed add the framing envelope required by Kafka, Hadoop Snappy codec, and the snappy CLI tool. Use framing when exchanging data with external systems; use raw when keeping data internal to your PascalAI application.
Utilities API
Helper functions for buffer sizing and ratio measurement.
| Function | Description |
|---|---|
| MaxCompressedLength(InputSize) | Returns the maximum possible compressed size for InputSize input bytes. Use to pre-allocate output buffers. |
| CompressionRatio(Data) | Compress Data and return the ratio compressed / original. Lower is better. 1.0 = no compression. |
| SnappyVersion | Returns the linked libsnappy version string, e.g. '1.1.10' |
uses snappy;
WriteLn('libsnappy ' + SnappyVersion);
var maxOut := MaxCompressedLength(1024 * 1024); { worst-case for 1 MB input }
WriteLn('Max compressed: ' + IntToStr(maxOut) + ' bytes');
var ratio := CompressionRatio(sampleData);
WriteLn('Ratio: ' + FloatToStr(ratio)); { e.g. 0.52 = 52% of original size }
Types Reference
TSnappyStats
Returned by CompressWithStats. Contains size and estimated throughput information for the last compression operation.
type
TSnappyStats = record
InputSize : Int64; { original size in bytes }
CompressedSize : Int64; { compressed size in bytes }
Ratio : Double; { CompressedSize / InputSize — lower is better }
SpeedMBps : Double; { estimated compression speed in MB/s }
end;
Used By
Snappy is embedded inside several major distributed systems as their default or optional compression codec:
| Project | How Snappy is used |
|---|---|
| Apache Kafka | Message log compression; producers set compression.type=snappy |
| LevelDB / RocksDB | Default SST file block compression; used by Chrome, Ethereum, and many databases |
| Apache Cassandra | Optional SSTable compression via SnappyCompressor |
| Hadoop | MapReduce intermediate and output compression (snappy codec) |
| Apache Arrow | IPC file and stream message body compression |
Best Use Cases
Good fit for Snappy
Snappy excels when decompression speed is critical and storage space is not the primary concern:
| Scenario | Why Snappy |
|---|---|
| Message queue payloads (Kafka, NATS) | Near-zero CPU overhead on producers and consumers |
| Database write buffers (RocksDB, LevelDB) | Fast compress on write path; very fast decompress on read path |
| Intermediate pipeline data | Data is transient; speed matters more than ratio |
| Already-compressed data (JPEG, MP4, ZIP) | Minimal overhead on incompressible input; no wasted CPU |
| High-frequency logging | Compress log batches at wire speed before shipping |
Consider an alternative when
Use zstd or lzma when storage savings outweigh CPU cost: long-term archival, large file downloads, or bandwidth-constrained transfers where a 2–3x better ratio justifies slower compression.
Key Concepts
Raw vs framed format
The raw Snappy format is a single compressed block with no checksums. The framing format adds a stream identifier, chunk boundaries, and CRC32C checksums for each chunk. Always use framing when data crosses a system boundary (Kafka, Hadoop, disk) so the receiving end can detect corruption. Use raw only for in-process or in-memory transfers where integrity is guaranteed by the transport.
No compression levels
Unlike zstd or gzip, Snappy has no compression level parameter. There is exactly one algorithm with one speed/ratio trade-off. This makes behavior completely predictable and eliminates configuration mistakes.
Checksums
Raw mode has no checksums. Framed mode adds a masked CRC32C checksum per 65536-byte chunk. If you need data integrity guarantees in raw mode, add an application-level checksum using the crypto package.
Package Info
System Requirements
libsnappy-devUbuntu/Debian:
sudo apt install libsnappy-dev
Performance
250–500 MB/s
1–2 GB/s
1.5–2x
TSnappyStats
.InputSize — original bytes.CompressedSize — output bytes.Ratio — out/in (lower = better).SpeedMBps — estimated MB/s
Functions
- Compress
- Decompress
- CompressWithStats
- IsValidCompressed
- GetUncompressedLength
- CompressFile
- DecompressFile
- CompressFramed
- DecompressFramed
- MaxCompressedLength
- CompressionRatio
- SnappyVersion
See Also
- lz4 (similar speed)
- zstd (better ratio)
- bzip2
- lzma (best ratio)
- compression (pure PAI)
- libarchive
- librdkafka
- crypto