erlang_qpack

QPACK header compression for HTTP/3 (RFC 9204) in pure Erlang.

Features

Installation

Add to your rebar.config:

{deps, [
    {qpack, {git, "https://github.com/benoitc/erlang_qpack.git", {tag, "0.1.0"}}}
]}.

Quick Start

Stateless API (static table only)

%% Encode headers
Headers = [{<<":method">>, <<"GET">>}, {<<":path">>, <<"/">>}],
Encoded = qpack:encode(Headers).

%% Decode headers
{ok, Decoded} = qpack:decode(Encoded).

Stateful API (with dynamic table)

%% Create state with dynamic table
State0 = qpack:new(#{max_dynamic_size => 4096}),

%% Encode with state
{Encoded, State1} = qpack:encode(Headers, State0),

%% Decode with state
{{ok, Decoded}, State2} = qpack:decode(Encoded, State1).

HTTP/3 Stream Integration

%% Process encoder instructions from peer
{ok, State1} = qpack:process_encoder_instructions(Data, State0),

%% Get encoder instructions to send to peer
Instructions = qpack:get_encoder_instructions(State1),

%% Process decoder instructions from peer
{ok, State2} = qpack:process_decoder_instructions(AckData, State1).

API Reference

See Usage Guide for detailed documentation.

Benchmarks

Performance on Apple M3 Pro (Erlang/OTP 28):

Operation Time Throughput
Encode simple request (4 headers, static) 0.45 us 2.2M ops/s
Encode typical request (8 headers) 1.25 us 800K ops/s
Encode large (50 custom headers) 7.23 us 138K ops/s
Decode simple request (4 headers) 0.14 us 7.0M ops/s
Decode typical request (8 headers) 0.43 us 2.3M ops/s
Huffman encode (15 bytes) 0.15 us 6.5M ops/s
Huffman decode (15 bytes) 0.15 us 6.7M ops/s
Process encoder instruction 0.07 us 14.9M ops/s

Run benchmarks:

rebar3 eunit && erl -pa _build/test/lib/qpack/ebin -pa _build/test/lib/qpack/test \
  -noshell -eval "qpack_bench:run(), halt()."

Development

Clone with submodules for interop test data:

git clone --recurse-submodules https://github.com/benoitc/erlang_qpack.git

Or initialize submodules after cloning:

git submodule update --init --recursive

Run tests:

rebar3 eunit           # Unit tests
rebar3 ct              # Common Test (includes interop tests)

Interoperability Testing

The test/qifs submodule contains QPACK Interop Files (QIFs) from the qpackers/qifs repository. These are used to verify compatibility with other QPACK implementations.

The interop test suite (qpack_interop_SUITE) tests:

Run interop tests specifically:

rebar3 ct --suite=qpack_interop_SUITE

QIF files are tab-separated header blocks. Encoded files use the format:

Build documentation:

rebar3 ex_doc

License

Apache License 2.0