HarperFast / HarperFast/documentation

http.compressionThreshold: docs say default 1200, shipped config sets 0 (compression off by default)

Open
#656 1 comment 0 reactions 0 assignees View on GitHub
content
Dominant language
MDX
Stars
9
Forks
9
Avg merge
2d 12h
Merged PRs (30d)
32

Description

### What's wrong

The docs state that `http.compressionThreshold` defaults to **1200** bytes, so Brotli response compression is on out of the box. Harper's shipped configuration sets it to **0**, and the runtime treats 0 as "off" — so on a default install, Brotli response compression never happens.

The root cause is not in this repo. **Harper contradicts itself**, and our docs faithfully mirror the half of it that isn't what actually ships.

### Evidence (harper `origin/main`)

| Location | Says |
| --- | --- |
| `config-root.schema.json:25-31` | property description: "Responses larger than this threshold (bytes) will be compressed... **Default: 1200**" |
| `config-root.schema.json:774` | `examples` block: `"compressionThreshold": 1200` |
| `static/defaultConfig.yaml:4` | **`compressionThreshold: 0`** — this is what gets written into a new install's config |
| `validation/configValidator.ts:329` | `compressionThreshold: number.optional()` — no default injected |
| `server/serverHelpers/contentTypes.ts:362` | `const COMPRESSION_THRESHOLD = envMgr.get(CONFIG_PARAMS.HTTP_COMPRESSIONTHRESHOLD)` — **no `\|\|` fallback**, so a configured 0 stays 0 |
| `server/serverHelpers/contentTypes.ts:373` | `canCompress = COMPRESSION_THRESHOLD && request.headers...includes('br')` — 0 is falsy, so compression is skipped entirely |

So the schema *documents* 1200, the shipped template *sets* 0, and the runtime honors 0. There is no code-level 1200 default anywhere.

Note this is specifically **`http.compressionThreshold`**. The unrelated `storage.compressionThreshold` (LMDB record compression) does have a real code default — `(storage.pageSize || 4096) - 60` at `resources/databases.ts:102` — which makes this easy to conflate when grepping.

### Affected pages in this repo

- [`reference/configuration/options.md:37`](reference/configuration/options.md#L37) - "_Default_: `1200` (bytes)"
- [`reference/http/configuration.md:111`](reference/http/configuration.md#L111) - the `http.compressionThreshold` section, plus `1200` in examples at `:123` and `:318`
- [`reference/http/overview.md:104`](reference/http/overview.md#L104) - "Compression applies when the response body exceeds the configured `compressionThreshold` (default 1200 bytes)"
- [`reference/configuration/operations.md:106`](reference/configuration/operations.md#L106) - `"compressionThreshold": 1200` in a config response example

### The question that has to be answered first

**Is `compressionThreshold: 0` in the shipped config intentional?** The docs fix depends entirely on the answer, and the two outcomes are very different:

- **If 0 is a bug in harper** - Brotli compression has been silently off for every default install. That is the real finding here, and the fix belongs in `static/defaultConfig.yaml`. Our docs then need no change beyond possibly noting the versions affected.
- **If 0 is intentional** - then harper's own schema description and examples are wrong too, and our four locations should say compression is **disabled by default** and must be explicitly enabled. In that case `config-root.schema.json` should be corrected alongside.

Either way one of the two harper locations is wrong, so this likely wants a companion harper issue; transferring or cross-linking is fine.

### Why it matters beyond a wrong number

Two things downstream depend on this:

1. Anyone following our docs believes responses over 1200 bytes are compressed. If they are not, that is a real and invisible performance difference on a default install.
2. There is a latent crash gated behind this setting. `contentTypes.ts:410-425` pipes `serializeStream`'s return value into `createBrotliCompress()` whenever `canCompress` is true, but the `application/x-msgpack` handler returns a `Buffer` (not a stream) for a plain array. `Accept: application/x-msgpack` + `Accept-Encoding: br` + an array body would throw `TypeError: stream.pipe is not a function`. That is currently unreachable **only because compression ships disabled** - so if the default is "corrected" to 1200 without fixing the pipe path first, this becomes reachable the same day. Sequencing matters. Surfaced in #655.

### Suggested fix

1. Get a ruling from whoever owns `static/defaultConfig.yaml` on whether 0 is intended.
2. Fix harper's inconsistency (either the shipped default or the schema description + examples).
3. Update the four locations above to match, in one pass so they cannot disagree with each other.
4. Track the `.pipe()` normalization separately, and land it before any change that turns compression on by default.

sent with Claude Opus 5

Contributor guide

Open the contributing guide

Research direction

Start by reviewing the four cited documentation locations and confirming with the owner of Harper's static/defaultConfig.yaml whether compressionThreshold: 0 is intentional. Then verify the companion Harper inconsistency and #655's stream issue before updating all documented values consistently; done means the cross-repo decision is recorded and the four pages match the shipped behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
documentation
Issue type
Documentation
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.