Skip to content

Commit b7fe2ac

Browse files
committed
compress: Add configurable compression levels
- Add support for configurable compression levels per host: * gzip-compression-level (1-9, default 6) * brotli-compression-level (0-11, default 6) * brotli-lgwin (10-24, default 16) * zstd-compression-level (1-22, default 12) This enables fine-tuning compression performance vs. speed trade-offs on a per-host basis
1 parent 4ef3d05 commit b7fe2ac

File tree

9 files changed

+202
-27
lines changed

9 files changed

+202
-27
lines changed

doc/admin-guide/plugins/compress.en.rst

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,41 @@ be considered, if it is ``2``, only br or gzip will be considered, if it is ``4`
192192
only zstd, br, or gzip will be considered, and if it is ``5``, all combinations
193193
of zstd, br, and gzip will be considered.
194194

195+
gzip-compression-level
196+
-----------------------
197+
198+
Sets the compression level for gzip compression. Valid values are 1-9, where
199+
1 is fastest compression (lowest compression ratio) and 9 is slowest compression
200+
(highest compression ratio). The default is 6, which provides a good balance
201+
between compression speed and ratio.
202+
203+
brotli-compression-level
204+
-------------------------
205+
206+
Sets the compression level for Brotli compression. Valid values are 0-11, where
207+
0 is fastest compression (lowest compression ratio) and 11 is slowest compression
208+
(highest compression ratio). The default is 6, which provides a good balance
209+
between compression speed and ratio.
210+
211+
brotli-lgwin
212+
------------
213+
214+
Sets the window size for Brotli compression. Valid values are 10-24, where
215+
larger values provide better compression but use more memory. The default is 16.
216+
This parameter controls the sliding window size used during compression:
217+
218+
- 10: 1KB window (fastest, least memory)
219+
- 16: 64KB window (default, good balance)
220+
- 24: 16MB window (slowest, most memory, best compression)
221+
222+
zstd-compression-level
223+
----------------------
224+
225+
Sets the compression level for Zstandard compression. Valid values are 1-22, where
226+
1 is fastest compression (lowest compression ratio) and 22 is slowest compression
227+
(highest compression ratio). The default is 12, which provides an excellent
228+
balance between compression speed and ratio for web content.
229+
195230
Examples
196231
========
197232

@@ -207,6 +242,10 @@ might create a configuration with the following options::
207242
compressible-status-code 200, 206
208243
minimum-content-length 860
209244
flush false
245+
gzip-compression-level 6
246+
brotli-compression-level 6
247+
brotli-lgwin 16
248+
zstd-compression-level 12
210249

211250
# Now set a configuration for www.example.com
212251
[www.example.com]
@@ -224,13 +263,15 @@ might create a configuration with the following options::
224263
flush true
225264
supported-algorithms gzip,deflate
226265

227-
# Supports brotli compression
266+
# Supports brotli compression with custom settings
228267
[brotli.compress.com]
229268
enabled true
230269
compressible-content-type text/*
231270
compressible-content-type application/json
232271
flush true
233272
supported-algorithms br,gzip
273+
brotli-compression-level 8
274+
brotli-lgwin 20
234275

235276
# Supports zstd compression for high efficiency
236277
[zstd.compress.com]
@@ -240,14 +281,19 @@ might create a configuration with the following options::
240281
compressible-content-type application/javascript
241282
flush true
242283
supported-algorithms zstd,gzip
284+
zstd-compression-level 15
243285

244-
# Supports all compression algorithms
286+
# Supports all compression algorithms with optimized settings
245287
[all.compress.com]
246288
enabled true
247289
compressible-content-type text/*
248290
compressible-content-type application/json
249291
flush true
250292
supported-algorithms zstd,br,gzip,deflate
293+
gzip-compression-level 7
294+
brotli-compression-level 9
295+
brotli-lgwin 18
296+
zstd-compression-level 10
251297

252298
# This origin does it all
253299
[bar.example.com]

plugins/compress/README

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ compress.so <path-to-config>/sample.compress.config
2424
After modifying plugin.config, restart traffic server (sudo traffic_ctl server restart)
2525
the configuration is re-read when a management update is given (sudo traffic_ctl config reload)
2626

27-
See sample.config.compress for an example configuration and the options that are available
27+
See sample.compress.config for an example configuration and the options that are available

plugins/compress/compress.cc

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,7 @@ namespace compress_ns
6262
DbgCtl dbg_ctl{TAG};
6363
}
6464

65-
const int ZLIB_COMPRESSION_LEVEL = 6;
66-
const char *dictionary = nullptr;
67-
68-
// brotli compression quality 1-11. Testing proved level '6'
69-
#if HAVE_BROTLI_ENCODE_H
70-
const int BROTLI_COMPRESSION_LEVEL = 6;
71-
const int BROTLI_LGW = 16;
72-
#endif
73-
74-
#if HAVE_ZSTD_H
75-
const int ZSTD_COMPRESSION_LEVEL = 12;
76-
#endif
65+
const char *dictionary = nullptr;
7766

7867
static const char *global_hidden_header_name = nullptr;
7968

@@ -90,7 +79,7 @@ static void zstd_compress_finish(Data *data);
9079
static void zstd_compress_one(Data *data, const char *upstream_buffer, int64_t upstream_length);
9180
#endif
9281
static Data *
93-
data_alloc(int compression_type, int compression_algorithms)
82+
data_alloc(int compression_type, int compression_algorithms, HostConfiguration *hc)
9483
{
9584
Data *data;
9685
int err;
@@ -103,6 +92,7 @@ data_alloc(int compression_type, int compression_algorithms)
10392
data->state = transform_state_initialized;
10493
data->compression_type = compression_type;
10594
data->compression_algorithms = compression_algorithms;
95+
data->hc = hc;
10696
data->zstrm.next_in = Z_NULL;
10797
data->zstrm.avail_in = 0;
10898
data->zstrm.total_in = 0;
@@ -119,7 +109,7 @@ data_alloc(int compression_type, int compression_algorithms)
119109
window_bits = WINDOW_BITS_DEFLATE;
120110
}
121111

122-
err = deflateInit2(&data->zstrm, ZLIB_COMPRESSION_LEVEL, Z_DEFLATED, window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
112+
err = deflateInit2(&data->zstrm, data->hc->zlib_compression_level(), Z_DEFLATED, window_bits, ZLIB_MEMLEVEL, Z_DEFAULT_STRATEGY);
123113

124114
if (err != Z_OK) {
125115
fatal("gzip-transform: ERROR: deflateInit (%d)!", err);
@@ -139,8 +129,8 @@ data_alloc(int compression_type, int compression_algorithms)
139129
if (!data->bstrm.br) {
140130
fatal("Brotli Encoder Instance Failed");
141131
}
142-
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, BROTLI_COMPRESSION_LEVEL);
143-
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, BROTLI_LGW);
132+
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_QUALITY, data->hc->brotli_compression_level());
133+
BrotliEncoderSetParameter(data->bstrm.br, BROTLI_PARAM_LGWIN, data->hc->brotli_lgw_size());
144134
data->bstrm.next_in = nullptr;
145135
data->bstrm.avail_in = 0;
146136
data->bstrm.total_in = 0;
@@ -462,7 +452,7 @@ zstd_compress_init(Data *data)
462452
}
463453

464454
// Set compression level
465-
size_t result = ZSTD_CCtx_setParameter(data->zstrm_zstd.cctx, ZSTD_c_compressionLevel, ZSTD_COMPRESSION_LEVEL);
455+
size_t result = ZSTD_CCtx_setParameter(data->zstrm_zstd.cctx, ZSTD_c_compressionLevel, data->hc->zstd_compression_level());
466456
if (ZSTD_isError(result)) {
467457
error("Failed to set Zstd compression level: %s", ZSTD_getErrorName(result));
468458
return;
@@ -475,7 +465,7 @@ zstd_compress_init(Data *data)
475465
return;
476466
}
477467

478-
debug("zstd compression context initialized with level %d", ZSTD_COMPRESSION_LEVEL);
468+
debug("zstd compression context initialized with level %d", data->hc->zstd_compression_level());
479469
}
480470

481471
static void
@@ -981,9 +971,8 @@ compress_transform_add(TSHttpTxn txnp, HostConfiguration *hc, int compress_type,
981971
}
982972

983973
connp = TSTransformCreate(compress_transform, txnp);
984-
data = data_alloc(compress_type, algorithms);
974+
data = data_alloc(compress_type, algorithms, hc);
985975
data->txn = txnp;
986-
data->hc = hc;
987976

988977
TSContDataSet(connp, data);
989978
TSHttpTxnHookAdd(txnp, TS_HTTP_RESPONSE_TRANSFORM_HOOK, connp);

plugins/compress/configuration.cc

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ enum ParserState {
108108
kParseRangeRequest,
109109
kParseFlush,
110110
kParseAllow,
111-
kParseMinimumContentLength
111+
kParseMinimumContentLength,
112+
kParseGzipCompressionLevel,
113+
kPaseBrotliCompressionLevel,
114+
kParseBrotliLGWSize,
115+
kParseZstdCompressionLevel,
112116
};
113117

114118
void
@@ -368,6 +372,14 @@ Configuration::Parse(const char *path)
368372
state = kParseStart;
369373
} else if (token == "minimum-content-length") {
370374
state = kParseMinimumContentLength;
375+
} else if (token == "gzip-compression-level") {
376+
state = kParseGzipCompressionLevel;
377+
} else if (token == "brotli-compression-level") {
378+
state = kPaseBrotliCompressionLevel;
379+
} else if (token == "brotli-lgwin") {
380+
state = kParseBrotliLGWSize;
381+
} else if (token == "zstd-compression-level") {
382+
state = kParseZstdCompressionLevel;
371383
} else {
372384
warning("failed to interpret \"%s\" at line %zu", token.c_str(), lineno);
373385
}
@@ -404,6 +416,46 @@ Configuration::Parse(const char *path)
404416
current_host_configuration->set_minimum_content_length(strtoul(token.c_str(), nullptr, 10));
405417
state = kParseStart;
406418
break;
419+
case kParseGzipCompressionLevel: {
420+
int level = strtol(token.c_str(), nullptr, 10);
421+
if (level < 1 || level > 9) {
422+
error("gzip-compression-level must be between 1 and 9, got %d", level);
423+
} else {
424+
current_host_configuration->set_gzip_compression_level(level);
425+
}
426+
state = kParseStart;
427+
break;
428+
}
429+
case kPaseBrotliCompressionLevel: {
430+
int level = strtol(token.c_str(), nullptr, 10);
431+
if (level < 0 || level > 11) {
432+
error("brotli-compression-level must be between 0 and 11, got %d", level);
433+
} else {
434+
current_host_configuration->set_brotli_compression_level(level);
435+
}
436+
state = kParseStart;
437+
break;
438+
}
439+
case kParseBrotliLGWSize: {
440+
int lgw = strtol(token.c_str(), nullptr, 10);
441+
if (lgw < 10 || lgw > 24) {
442+
error("brotli-lgwin must be between 10 and 24, got %d", lgw);
443+
} else {
444+
current_host_configuration->set_brotli_lgw_size(lgw);
445+
}
446+
state = kParseStart;
447+
break;
448+
}
449+
case kParseZstdCompressionLevel: {
450+
int level = strtol(token.c_str(), nullptr, 10);
451+
if (level < 1 || level > 22) {
452+
error("zstd-compression-level must be between 1 and 22, got %d", level);
453+
} else {
454+
current_host_configuration->set_zstd_compression_level(level);
455+
}
456+
state = kParseStart;
457+
break;
458+
}
407459
}
408460
}
409461
}

plugins/compress/configuration.h

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ class HostConfiguration : private atscppapi::noncopyable
5353
remove_accept_encoding_(false),
5454
flush_(false),
5555
compression_algorithms_(ALGORITHM_GZIP),
56-
minimum_content_length_(1024)
56+
minimum_content_length_(1024),
57+
zlib_compression_level_(6),
58+
brotli_compression_level_(6),
59+
brotli_lgw_size_(16),
60+
zstd_compression_level_(12)
5761
{
5862
}
5963

@@ -129,6 +133,51 @@ class HostConfiguration : private atscppapi::noncopyable
129133
minimum_content_length_ = x;
130134
}
131135

136+
unsigned int
137+
zlib_compression_level() const
138+
{
139+
return zlib_compression_level_;
140+
}
141+
142+
void
143+
set_gzip_compression_level(int level)
144+
{
145+
zlib_compression_level_ = level;
146+
}
147+
148+
unsigned int
149+
brotli_compression_level() const
150+
{
151+
return brotli_compression_level_;
152+
}
153+
void
154+
set_brotli_compression_level(int level)
155+
{
156+
brotli_compression_level_ = level;
157+
}
158+
159+
unsigned int
160+
brotli_lgw_size() const
161+
{
162+
return brotli_lgw_size_;
163+
}
164+
void
165+
set_brotli_lgw_size(unsigned int lgw)
166+
{
167+
brotli_lgw_size_ = lgw;
168+
}
169+
170+
int
171+
zstd_compression_level() const
172+
{
173+
return zstd_compression_level_;
174+
}
175+
void
176+
set_zstd_compression_level(int level)
177+
{
178+
zstd_compression_level_ = level;
179+
}
180+
132181
void update_defaults();
133182
void add_allow(const std::string &allow);
134183
void add_compressible_content_type(const std::string &content_type);
@@ -148,6 +197,10 @@ class HostConfiguration : private atscppapi::noncopyable
148197
bool flush_;
149198
int compression_algorithms_;
150199
unsigned int minimum_content_length_;
200+
unsigned int zlib_compression_level_;
201+
unsigned int brotli_compression_level_;
202+
unsigned int brotli_lgw_size_;
203+
int zstd_compression_level_;
151204

152205
StringContainer compressible_content_types_;
153206
StringContainer allows_;

plugins/compress/sample.compress.config

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@
3737
# minimum-content-length: minimum content length for compression to be enabled (in bytes)
3838
# - this setting only applies if the origin response has a Content-Length header
3939
#
40+
# gzip-compression-level: compression level for gzip (1-9, default 6)
41+
# - 1 is fastest compression (lowest compression ratio)
42+
# - 9 is slowest compression (highest compression ratio)
43+
#
44+
# brotli-compression-level: compression level for brotli (0-11, default 6)
45+
# - 0 is fastest compression (lowest compression ratio)
46+
# - 11 is slowest compression (highest compression ratio)
47+
#
48+
# brotli-lgwin: window size for brotli compression (10-24, default 16)
49+
# - larger values provide better compression but use more memory
50+
# - 10: 1KB window, 16: 64KB window, 24: 16MB window
51+
#
52+
# zstd-compression-level: compression level for zstandard (1-22, default 12)
53+
# - 1 is fastest compression (lowest compression ratio)
54+
# - 22 is slowest compression (highest compression ratio)
55+
#
4056
######################################################################
4157

4258
#first, we configure the default/global plugin behaviour
@@ -58,6 +74,12 @@ minimum-content-length 1024
5874
#supported algorithms
5975
supported-algorithms br,gzip,zstd
6076

77+
# Compression level settings (optional)
78+
gzip-compression-level 6
79+
brotli-compression-level 6
80+
brotli-lgwin 16
81+
zstd-compression-level 12
82+
6183
#override the global configuration for a host.
6284
#www.foo.nl does NOT inherit anything
6385
[www.foo.nl]
@@ -68,6 +90,12 @@ compressible-content-type text/*
6890
compressible-status-code 200,206,409
6991
minimum-content-length 1024
7092

93+
# Custom compression settings for this host
94+
gzip-compression-level 8
95+
brotli-compression-level 9
96+
brotli-lgwin 20
97+
zstd-compression-level 15
98+
7199
allow /this/*.js
72100
allow !/notthis/*.js
73101
allow !/notthat*

0 commit comments

Comments
 (0)