# Zstd Compression Strategies: A Complete Guide to the ZSTD_strategy Enum

> Explore zstd compression strategies with the ZSTD_strategy enum. Discover seven algorithms from ZSTD_fast to ZSTD_btoptimal balancing speed, memory, and compression ratio for your needs.

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

---

**The `ZSTD_strategy` enumeration in facebook/zstd defines seven distinct compression algorithms—from `ZSTD_fast` for real-time streaming to `ZSTD_btoptimal` for archival storage—that trade speed, memory, and compression ratio through different match-finding algorithms.**

The facebook/zstd library exposes granular control over compression behavior through the `ZSTD_strategy` enum declared in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h). These strategies determine how aggressively the compressor searches for repeating patterns, directly impacting CPU usage, memory consumption, and final compression ratios.

## Overview of the ZSTD_strategy Enumeration

The complete `ZSTD_strategy` enumeration is defined in [[`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h)](https://github.com/facebook/zstd/blob/dev/lib/zstd.h) (lines 347-360):

```c
typedef enum {
    ZSTD_fast = 1,
    ZSTD_greedy,
    ZSTD_lazy,
    ZSTD_lazy2,
    ZSTD_huffOnly,
    ZSTD_btultra,
    ZSTD_btoptimal,
    ZSTD_default = ZSTD_fast
} ZSTD_strategy;

```

Each value represents a specific trade-off between compression speed, ratio, and memory usage.

### Fast Strategy (ZSTD_fast)

**ZSTD_fast** performs minimal search using only a hash table. This is the fastest mode with the lowest compression ratio, designed for real-time streaming and low-latency network transmission. As defined by `ZSTD_default = ZSTD_fast`, this strategy applies when no explicit strategy is set.

### Greedy Strategy (ZSTD_greedy)

**ZSTD_greedy** searches for the best match only at the current position before emitting a literal. It offers slightly better compression than `ZSTD_fast` while maintaining very high throughput, making it suitable for general-purpose compression where speed remains a priority.

### Lazy Strategies (ZSTD_lazy and ZSTD_lazy2)

**ZSTD_lazy** performs a single lazy search, looking ahead one byte position before committing to a match. This improves compression ratio with modest speed loss compared to greedy mode. **ZSTD_lazy2** extends this to a two-step look-ahead, providing even better compression at higher CPU cost. These are ideal for batch jobs where compression quality matters more than real-time latency.

### Huffman-Only Strategy (ZSTD_huffOnly)

**ZSTD_huffOnly** disables match searching entirely, applying only Huffman entropy coding. This is extremely fast but provides low compression ratios, useful when processing already-compressed or highly random data (such as encrypted payloads or JPEG images) where dictionary matching provides no benefit.

### Binary Tree Strategies (ZSTD_btultra and ZSTD_btoptimal)

**ZSTD_btultra** implements a full binary-tree search with "ultra" settings, delivering the deepest searches, highest compression ratios, and highest memory usage—optimal for long-term archival storage. **ZSTD_btoptimal** uses binary-tree search with optimal parsing to balance compression ratio and speed more finely than `btultra`, offering near-maximum compression without the absolute worst-case performance penalties.

## Setting Compression Strategies via the API

To configure a strategy, call `ZSTD_CCtx_setParameter()` with the `ZSTD_c_strategy` parameter on a valid compression context:

```c
#include <zstd.h>

int compress_with_strategy(const void* src, size_t srcSize,
                           void* dst, size_t dstCapacity,
                           ZSTD_strategy strategy)
{
    ZSTD_CCtx* const cctx = ZSTD_createCCtx();
    if (!cctx) return -1;
    
    /* Apply the chosen compression strategy */
    ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, (int)strategy);
    
    /* Optional: tune other parameters independently */
    ZSTD_CCtx_setParameter(cctx, ZSTD_c_compressionLevel, 5);
    
    const size_t compSize = ZSTD_compressCCtx(cctx,
                                               dst, dstCapacity,
                                               src, srcSize);
    ZSTD_freeCCtx(cctx);
    
    if (ZSTD_isError(compSize)) {
        fprintf(stderr, "Compression error: %s\n",
                ZSTD_getErrorName(compSize));
        return -1;
    }
    return (int)compSize;
}

```

## Internal Implementation Details

According to the facebook/zstd source code, the compressor delegates to specific block compressor implementations based on the selected strategy. The function `ZSTD_selectBlockCompressor()` in [[`lib/compress/zstd_compress_internal.h`](https://github.com/facebook/zstd/blob/main/lib/compress/zstd_compress_internal.h)](https://github.com/facebook/zstd/blob/dev/lib/compress/zstd_compress_internal.h) (around line 603) maps each `ZSTD_strategy` value to its concrete match-finding algorithm, ranging from simple hash-table lookup for `ZSTD_fast` to full binary-tree optimal parsing for `ZSTD_btoptimal`.

Each strategy directly influences three core characteristics:

- **Match-finder depth**: How far ahead the algorithm searches for longer repeating sequences
- **Memory allocation**: BT-based strategies allocate significantly larger auxiliary structures than hash-based strategies
- **CPU cycles per byte**: Deeper searches require more processing time to evaluate potential matches

## Choosing the Right Strategy for Your Workload

| Strategy | Speed | Compression | Memory | Best Use Case |
|----------|-------|-------------|--------|---------------|
| `ZSTD_fast` | Fastest | Lowest | Minimal | Real-time streaming, network I/O |
| `ZSTD_greedy` | Very Fast | Low | Low | General-purpose logging |
| `ZSTD_lazy` | Fast | Good | Moderate | Default choice for most applications |
| `ZSTD_lazy2` | Moderate | Better | Moderate | Batch file processing |
| `ZSTD_huffOnly` | Extremely Fast | Very Low | Minimal | Pre-compressed or encrypted data |
| `ZSTD_btultra` | Slow | Highest | High | Long-term archival storage |
| `ZSTD_btoptimal` | Slow | Very High | High | Maximum compression with balanced speed |

## Summary

- The `ZSTD_strategy` enum in [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h) defines seven compression algorithms ranging from `ZSTD_fast` (hash-table only) to `ZSTD_btoptimal` (binary-tree optimal parsing).
- **ZSTD_fast** serves as the default strategy (`ZSTD_default`), ensuring conservative resource usage and consistent speed across platforms.
- Configure strategies programmatically using `ZSTD_CCtx_setParameter()` with the `ZSTD_c_strategy` parameter.
- Binary-tree strategies (`ZSTD_btultra`, `ZSTD_btoptimal`) consume significantly more memory but achieve superior compression ratios compared to hash-based approaches.
- **ZSTD_huffOnly** bypasses match-finding entirely, ideal for incompressible data streams where entropy coding alone suffices.

## Frequently Asked Questions

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

The default strategy is `ZSTD_fast`, explicitly assigned to `ZSTD_default` in the enum definition within [`lib/zstd.h`](https://github.com/facebook/zstd/blob/main/lib/zstd.h). This conservative default ensures reasonable compression speed across all hardware platforms while still delivering usable compression ratios for general workloads.

### How does ZSTD_btoptimal differ from ZSTD_btultra?

`ZSTD_btoptimal` employs binary-tree search with optimal parsing to achieve high compression ratios while maintaining better speed than `ZSTD_btultra`, which uses "ultra" settings with deeper searches and significantly higher memory consumption to squeeze out the absolute maximum compression ratio at the cost of compression speed.

### Can I change compression strategies dynamically for each block?

Yes, you can modify the strategy between compression calls by calling `ZSTD_CCtx_setParameter(cctx, ZSTD_c_strategy, newStrategy)` on the same `ZSTD_CCtx` instance. This allows adaptive compression pipelines where you might apply `ZSTD_fast` for latency-sensitive header data and `ZSTD_btoptimal` for archival payload sections.

### When should I use ZSTD_huffOnly?

Use `ZSTD_huffOnly` when processing data that is already highly compressed, encrypted, or inherently random—such as JPEG images, encrypted payloads, or already-compressed archives. In these cases, match-finding algorithms waste CPU cycles without improving ratios, making pure Huffman coding the efficient choice.