# Zstd Compression Levels Explained: Complete Guide to Speed and Ratio Settings

> Explore zstd compression levels 1-22 and fast negative levels to optimize speed and ratio. Discover the default level 3 and ultra settings for maximum compression.

- Repository: [Meta/zstd](https://github.com/facebook/zstd)
- Tags: deep-dive
- Published: 2026-09-09

---

**Zstd provides 22 regular compression levels (1-22) plus negative "fast" levels for ultra-fast compression, with level 3 as the default and levels 20-22 requiring the `--ultra` flag for maximum compression ratio.**

The `facebook/zstd` library offers a wide spectrum of compression levels designed to balance speed, memory usage, and compression ratio. These levels are defined in the source code with concrete parameter tables that adjust strategy, window size, and chain length based on input size. Whether you are optimizing for real-time streaming or maximum archive density, understanding the available compression levels in zstd is essential for optimal performance.

## Understanding Zstd Compression Level Ranges

### Regular Levels (1-22)

Zstd supports **22 standard compression levels** that provide progressively better compression ratios at the cost of speed and memory. According to [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h), the constant `ZSTD_MAX_CLEVEL` is defined as 22, while `ZSTD_CLEVEL_DEFAULT` is set to 3.

The concrete compression parameters for each level reside in [`lib/compress/clevels.h`](https://github.com/facebook/zstd/blob/main/lib/compress/clevels.h). This file contains four distinct static parameter tables optimized for different source size regimes: large sources, ≤256 KB, ≤128 KB, and ≤16 KB. Higher regular levels (particularly 20-22) are classified as "ultra" modes that consume significantly more memory but achieve the strongest compression ratios.

### Negative Fast Levels (--fast)

For scenarios prioritizing speed over ratio, zstd provides **negative compression levels** accessible via the `--fast=#` CLI flag. These levels use the `ZSTD_fast` strategy and are represented internally as negative values (e.g., `-1`, `-2`). 

In [`clevels.h`](https://github.com/facebook/zstd/blob/main/clevels.h), the base configuration for these negative levels establishes the foundation for ultra-fast modes. When using the command line, omitting the number (`--fast`) defaults to level 1 fast mode, while explicit values like `--fast=4` select progressively faster (but less compressive) settings.

### Level 0 (Default Handler)

**Level 0** serves as a special sentinel value meaning "use the default level." When specified in the API or CLI, it maps to `ZSTD_CLEVEL_DEFAULT` (level 3). This behavior is documented in [`programs/zstd.1.md`](https://github.com/facebook/zstd/blob/main/programs/zstd.1.md) and implemented throughout the compression pipeline as a fallback to the built-in default parameters.

## How to Specify Compression Levels in Zstd CLI

The command-line interface provides intuitive flags for accessing the full range of compression levels. Note that the CLI uses specific flags for different level ranges:

```bash

# Default compression (level 3)

zstd file.txt

# Fast mode - level 1 (ultra-fast)

zstd --fast=1 file.txt

# Fast mode - level 4 (faster, lower ratio)

zstd --fast=4 file.txt

# Regular level 10 (note: -9 selects level 10 due to 0-based indexing)

zstd -9 file.txt

# Maximum compression level 22 (requires --ultra flag)

zstd --ultra -22 file.txt

```

The `--ultra` or `--max` flag is required to enable levels 20-22, as these ultra-high modes allocate substantial memory resources during compression.

## Working with Compression Levels in the C API

When integrating zstd programmatically, use the `ZSTD_compress()` function with an integer compression level parameter. You can query the maximum available level using `ZSTD_maxCLevel()`:

```c
#include <zstd.h>
#include <stdlib.h>
#include <stdio.h>

int main() {
    /* Retrieve maximum supported level (22) */
    int maxLevel = ZSTD_maxCLevel();
    printf("Maximum compression level: %d\n", maxLevel);
    
    const void* src = "Example data to compress";
    size_t srcSize = 24;
    
    /* Allocate destination buffer */
    size_t dstCapacity = ZSTD_compressBound(srcSize);
    void* dst = malloc(dstCapacity);
    
    /* Compress using level 15 (regular high compression) */
    int cLevel = 15;  /* Valid range: negative fast levels to 22 */
    size_t const compressedSize = ZSTD_compress(dst, dstCapacity, 
                                                src, srcSize, cLevel);
    
    if (ZSTD_isError(compressedSize)) {
        fprintf(stderr, "Compression error: %s\n", 
                ZSTD_getErrorName(compressedSize));
        return 1;
    }
    
    printf("Compressed from %zu to %zu bytes\n", srcSize, compressedSize);
    free(dst);
    return 0;
}

```

The `ZSTD_maxCLevel()` function is implemented in [`lib/compress/zstd_compress.c`](https://github.com/facebook/zstd/blob/main/lib/compress/zstd_compress.c) at line 8204 and returns `ZSTD_MAX_CLEVEL` (22).

## Implementation Details in the Source Code

According to the `facebook/zstd` source code, compression levels are implemented through parameterized strategy tables rather than simple numeric presets. The file [`lib/compress/clevels.h`](https://github.com/facebook/zstd/blob/main/lib/compress/clevels.h) defines these configurations across source-size-specific tables to ensure optimal performance for small, medium, and large inputs.

Key implementation constants include:
- **`ZSTD_MAX_CLEVEL`** (22): Defined in [`clevels.h`](https://github.com/facebook/zstd/blob/main/clevels.h) as the highest regular level
- **`ZSTD_CLEVEL_DEFAULT`** (3): Defined in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h) as the library default
- **Parameter tables**: Located in [`clevels.h`](https://github.com/facebook/zstd/blob/main/clevels.h) lines 25-50, containing compression parameters for levels 1-22 across four size categories
- **API boundary**: `ZSTD_maxCLevel()` in [`zstd_compress.c`](https://github.com/facebook/zstd/blob/main/zstd_compress.c) exposes the maximum level to applications

Levels 20-22 share the same parameter tables but trigger ultra-mode memory allocation strategies that significantly increase the compression window and search depth.

## Summary

- Zstd supports **22 regular compression levels** (1-22) with level 3 as the default, defined in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h) as `ZSTD_CLEVEL_DEFAULT`.
- **Negative levels** provide ultra-fast compression via the `--fast` flag, internally using the `ZSTD_fast` strategy defined in [`lib/compress/clevels.h`](https://github.com/facebook/zstd/blob/main/lib/compress/clevels.h).
- **Levels 20-22** require the `--ultra` CLI flag and consume significantly more memory for maximum compression ratios.
- **Level 0** is a special value that maps to the default level 3.
- The maximum level constant `ZSTD_MAX_CLEVEL` (22) and the query function `ZSTD_maxCLevel()` are implemented in [`lib/compress/zstd_compress.c`](https://github.com/facebook/zstd/blob/main/lib/compress/zstd_compress.c).

## Frequently Asked Questions

### What is the default compression level in zstd?

The default compression level in zstd is **3**, defined as `ZSTD_CLEVEL_DEFAULT` in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h). When you specify level 0 in the API or run the `zstd` command without flags, the library automatically uses level 3, which provides a balanced trade-off between compression speed and ratio for general-purpose use.

### How do I use ultra-high compression levels in zstd?

Levels 20 through 22 are considered "ultra" modes and require explicit enabling. Use the `--ultra` or `--max` flag with the command-line tool (e.g., `zstd --ultra -22 file.txt`). These levels utilize the parameter tables in [`lib/compress/clevels.h`](https://github.com/facebook/zstd/blob/main/lib/compress/clevels.h) but require substantially more memory for compression, making them suitable only for offline batch processing or maximum density archives.

### What are negative compression levels in zstd?

Negative compression levels represent ultra-fast modes that prioritize compression and decompression speed over ratio. Accessible via `--fast=#` on the CLI or negative integers in the API (e.g., `-1`, `-5`), these levels use the `ZSTD_fast` strategy. According to [`clevels.h`](https://github.com/facebook/zstd/blob/main/clevels.h), these are defined as extensions from a base negative level configuration, with default fast mode being level 1 when the number is omitted.

### How can I programmatically check the maximum compression level?

Call the `ZSTD_maxCLevel()` function declared in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h) and implemented in [`lib/compress/zstd_compress.c`](https://github.com/facebook/zstd/blob/main/lib/compress/zstd_compress.c). This function returns `ZSTD_MAX_CLEVEL` (currently 22), allowing applications to dynamically adapt to the capabilities of the linked zstd library version without hardcoding level limits.