Quick start guide
This guide will walk you through creating your first compression and decompression program using the Zstandard C library.
Prerequisites
Before starting, make sure you have:
Zstandard library installed (see Installation )
A C compiler (gcc, clang, or equivalent)
Basic familiarity with C programming
Simple compression example
Let’s create a simple program that compresses a file. This example is based on the official simple_compression.c from the Zstandard repository.
Create the compression program
Create a file named compress.c with the following code: #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zstd.h>
static void compress_file ( const char * input_file , const char * output_file )
{
// Read input file
FILE * fin = fopen (input_file, "rb" );
if ( ! fin) {
fprintf (stderr, "Failed to open input file \n " );
exit ( 1 );
}
fseek (fin, 0 , SEEK_END);
size_t fSize = ftell (fin);
fseek (fin, 0 , SEEK_SET);
void * fBuff = malloc (fSize);
if ( ! fBuff) {
fprintf (stderr, "Memory allocation failed \n " );
exit ( 1 );
}
fread (fBuff, 1 , fSize, fin);
fclose (fin);
// Compress the data
size_t const cBuffSize = ZSTD_compressBound (fSize);
void * const cBuff = malloc (cBuffSize);
if ( ! cBuff) {
fprintf (stderr, "Memory allocation failed \n " );
exit ( 1 );
}
size_t const cSize = ZSTD_compress (cBuff, cBuffSize, fBuff, fSize, 1 );
if ( ZSTD_isError (cSize)) {
fprintf (stderr, "Compression error: %s \n " , ZSTD_getErrorName (cSize));
exit ( 1 );
}
// Write compressed data to output file
FILE * fout = fopen (output_file, "wb" );
if ( ! fout) {
fprintf (stderr, "Failed to open output file \n " );
exit ( 1 );
}
fwrite (cBuff, 1 , cSize, fout);
fclose (fout);
printf ( " %s : %zu -> %zu bytes ( %.2f%% compression) \n " ,
input_file, fSize, cSize,
( 1.0 - ( double )cSize / fSize) * 100 );
free (fBuff);
free (cBuff);
}
int main ( int argc , char ** argv )
{
if (argc != 3 ) {
printf ( "Usage: %s INPUT_FILE OUTPUT_FILE \n " , argv [ 0 ]);
return 1 ;
}
compress_file ( argv [ 1 ], argv [ 2 ]);
return 0 ;
}
Create the decompression program
Create a file named decompress.c: #include <stdio.h>
#include <stdlib.h>
#include <zstd.h>
static void decompress_file ( const char * input_file , const char * output_file )
{
// Read compressed file
FILE * fin = fopen (input_file, "rb" );
if ( ! fin) {
fprintf (stderr, "Failed to open input file \n " );
exit ( 1 );
}
fseek (fin, 0 , SEEK_END);
size_t cSize = ftell (fin);
fseek (fin, 0 , SEEK_SET);
void * cBuff = malloc (cSize);
if ( ! cBuff) {
fprintf (stderr, "Memory allocation failed \n " );
exit ( 1 );
}
fread (cBuff, 1 , cSize, fin);
fclose (fin);
// Get the decompressed size from the frame header
unsigned long long const rSize = ZSTD_getFrameContentSize (cBuff, cSize);
if (rSize == ZSTD_CONTENTSIZE_ERROR) {
fprintf (stderr, " %s : not compressed by zstd! \n " , input_file);
exit ( 1 );
}
if (rSize == ZSTD_CONTENTSIZE_UNKNOWN) {
fprintf (stderr, " %s : original size unknown! \n " , input_file);
exit ( 1 );
}
void * const rBuff = malloc (( size_t )rSize);
if ( ! rBuff) {
fprintf (stderr, "Memory allocation failed \n " );
exit ( 1 );
}
// Decompress
size_t const dSize = ZSTD_decompress (rBuff, rSize, cBuff, cSize);
if ( ZSTD_isError (dSize)) {
fprintf (stderr, "Decompression error: %s \n " , ZSTD_getErrorName (dSize));
exit ( 1 );
}
// Write decompressed data to output file
FILE * fout = fopen (output_file, "wb" );
if ( ! fout) {
fprintf (stderr, "Failed to open output file \n " );
exit ( 1 );
}
fwrite (rBuff, 1 , dSize, fout);
fclose (fout);
printf ( " %s : %zu -> %zu bytes \n " , input_file, cSize, ( size_t )rSize);
printf ( " %s correctly decompressed to %s \n " , input_file, output_file);
free (cBuff);
free (rBuff);
}
int main ( int argc , char ** argv )
{
if (argc != 3 ) {
printf ( "Usage: %s COMPRESSED_FILE OUTPUT_FILE \n " , argv [ 0 ]);
return 1 ;
}
decompress_file ( argv [ 1 ], argv [ 2 ]);
return 0 ;
}
Compile the programs
Compile both programs with the Zstandard library: # Compile compression program
gcc -o compress compress.c -lzstd
# Compile decompression program
gcc -o decompress decompress.c -lzstd
If you installed Zstandard in a custom location, you may need to specify the include and library paths: gcc -o compress compress.c -I/path/to/include -L/path/to/lib -lzstd
Test the programs
Create a test file and compress it: # Create a test file
echo "Hello, Zstandard! This is a test file." > test.txt
# Compress the file
./compress test.txt test.txt.zst
# Decompress the file
./decompress test.txt.zst test_restored.txt
# Verify the output
cat test_restored.txt
Expected output
When you run the compression program, you should see output like:
test.txt : 40 -> 28 bytes (30.00% compression)
When you run the decompression program:
test.txt.zst : 28 -> 40 bytes
test.txt.zst correctly decompressed to test_restored.txt
Understanding the API
The examples above use the Simple Core API, which is perfect for single-step compression:
Key functions
ZSTD_compressBound()
Calculates the maximum compressed size for a given input size. This guarantees that the destination buffer is large enough:
size_t const cBuffSize = ZSTD_compressBound (fSize);
ZSTD_compress()
Compresses source content as a single zstd compressed frame:
size_t ZSTD_compress ( void * dst , size_t dstCapacity ,
const void * src , size_t srcSize ,
int compressionLevel );
dst : Destination buffer for compressed data
dstCapacity : Size of destination buffer
src : Source data to compress
srcSize : Size of source data
compressionLevel : Compression level (1-22, or negative for fast mode)
ZSTD_getFrameContentSize()
Returns the decompressed content size stored in the frame header:
unsigned long long const rSize = ZSTD_getFrameContentSize (cBuff, cSize);
Always check for ZSTD_CONTENTSIZE_ERROR and ZSTD_CONTENTSIZE_UNKNOWN when calling this function.
ZSTD_decompress()
Decompresses a zstd compressed frame:
size_t ZSTD_decompress ( void * dst , size_t dstCapacity ,
const void * src , size_t compressedSize );
Error handling
Always check if operations failed using ZSTD_isError() and get error messages with ZSTD_getErrorName():
if ( ZSTD_isError (cSize)) {
fprintf (stderr, "Error: %s \n " , ZSTD_getErrorName (cSize));
}
Compression levels
Experiment with different compression levels to find the right balance for your use case:
Fast compression (negative levels)
Default compression
Maximum compression
Ultra compression
// Faster compression, lower ratio
ZSTD_compress (dst, dstSize, src, srcSize, - 5 );
Decompression speed remains roughly the same regardless of the compression level used.
Reuse contexts for multiple compressions to avoid malloc/free overhead (see ZSTD_compressCCtx())
Use streaming APIs for large files that don’t fit in memory (see ZSTD_compressStream())
Train dictionaries for small data compression to dramatically improve ratios
Choose appropriate compression levels based on your speed/ratio requirements
Next steps
Now that you have a working example, explore more advanced features:
Streaming compression Learn how to compress data that doesn’t fit in memory using streaming APIs
Dictionary compression Improve compression ratios for small data by training custom dictionaries
Context reuse Optimize performance when compressing multiple files by reusing contexts
API reference Explore the complete Zstandard API documentation
Complete example source
The complete, production-ready examples used as the basis for this guide can be found in the official Zstandard repository: