Skip to content

feat(hoglake): write zstd-3 parquet by default (HOGLAKE_COMPRESSION) - #155

Merged
jghoman merged 2 commits into
mainfrom
jakob/hoglake-zstd
Oct 23, 2026
Merged

jghoman merged 2 commits into
mainfrom
jakob/hoglake-zstd

Conversation

@jghoman

@jghoman jghoman commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Dependencies

Why

pyhoglake's default codec is pyarrow's SNAPPY. ~97% of prod-us ingest.events_raw bytes are SNAPPY (480-object sample). One 413K-row prod-us slice: snappy 1,138 MB, zstd-3 281 MB. Daytime events objects (~560-620 MiB) sit above the 512 MiB compaction target, so their codec is permanent.

What

  • HOGLAKE_COMPRESSION (default zstd) and HOGLAKE_COMPRESSION_LEVEL (default 3 for zstd), passed to every prepare_append_tables. snappy reproduces the previous bytes (rollback).
  • config.load() validates through pyhoglake.parquet_write_options, not a copy of its rules: zstd 1-9, snappy, none. Errors name the env vars.
  • Codec logged at startup and recorded as codec= in every snapshot message.

Rollout notes

  • Every hoglake consumer switches on the next image; the chart has no per-consumer passthrough yet.
  • zstd-3 events objects (~140 MiB) fall under the compaction target, so daytime events_raw objects become compaction candidates for the first time. Estimate (unmeasured): +190-380 groups/h on prod-us.
  • Encode cost: zstd-3 ~1.9x snappy on a synthetic benchmark, a few seconds per 2 GiB flush. zstd-9 at 2 GiB is ~21 s, past _PREPARE_ALLOWANCE_S (20 s); the liveness model does not yet charge codec or level.

Tests

  • Unit: defaults, passthrough, refusals; codec reaches prepare_append_tables and the snapshot message; installed-pyhoglake signature guard.
  • Integration (real server + MinIO): written object's footer is ZSTD by default and SNAPPY on rollback; snapshot message carries codec=.
  • Against pyhoglake 1.4.4 / pyarrow 26.0.0 / duckdb 1.5.5: 1,445 unit, 155 integration (real hoglake server + MinIO), all pass.

pyhoglake's default codec is pyarrow's SNAPPY, ~4x larger than zstd-3 on
prod-us events, and objects at or over the 512 MiB compaction target are
never rewritten. millpond now always passes a codec: HOGLAKE_COMPRESSION
(default zstd) and HOGLAKE_COMPRESSION_LEVEL (default 3 for zstd).
`snappy` reproduces the previous bytes.

config.load() validates through pyhoglake.parquet_write_options, so a bad
value or a pyhoglake too old to take a codec fails the pod at start
rather than on its first flush. The codec is logged at startup and
recorded as codec= in every snapshot message.

Requires pyhoglake 1.4.3.
pyhoglake 1.4.4 carries the parquet codec keywords and
parquet_write_options this branch calls. It requires pyarrow>=26, which
pyducklake (<26 through 1.0.18) blocked, and pyducklake 1.0.19 moved to
duckdb==1.5.6 against millpond's deliberate 1.5.5 pin. Nothing in
millpond imports pyducklake; it was only a lockstep canary. Drop it; the
DuckLake build stays guarded by test_ducklake_pin.py and the Dockerfile
SHA layer. Cross-repo follow-up in #156.

pyarrow 23.0.1 -> 26.0.0, pyhoglake 1.4.0 -> 1.4.4, duckdb unchanged.
@jghoman
jghoman marked this pull request as ready for review October 23, 2026 17:31
@jghoman
jghoman requested a review from a team October 23, 2026 17:31

@bill-ph bill-ph left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the PR description, full diff, and existing discussion at ba921e2. Checked configuration defaults and validation, codec propagation into parquet preparation and snapshot messages, retry/liveness interactions, dependency and lockfile changes, and unit/integration test coverage. Also checked for overengineering and scope creep. Tests, builds, and linters were not run, as requested.

No issues found.

— Robo Bill v2 (gpt-6.1-sol, high reasoning)

@jghoman
jghoman merged commit 08b8cf8 into main Oct 23, 2026
21 of 22 checks passed
@jghoman
jghoman deleted the jakob/hoglake-zstd branch October 23, 2026 17:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants