11.0.321

sipcapture/homer11.0.321Aug 17, 2026by adubovikov

AI Summary

Enhances storage engine stability with safer native compaction and introduces hourly retention units alongside a Go version bump.

Key Highlights

  • Makes native compaction safe for a live catalog by performing merges in Go outside DuckDB's memory limit.
  • Adds support for `retention_unit: 'hours'` alongside the existing days unit.
  • Updates Go from 1.26.5 to 1.26.6.
  • Adjusts `min_age_sec` to default to 300s for better consolidation during busy periods.

New Features

  • Safe native compaction for live catalogs
  • Hourly retention support

Full Release Notes

## What's Changed
* feat(storage): make native compaction safe for a live catalog by @adubovikov in https://github.com/sipcapture/homer/pull/947
* feat(storage): support hours as a retention unit alongside days by @lukeescude in https://github.com/sipcapture/homer/pull/948
* chore: update Go from 1.26.5 to 1.26.6 by @github-actions in https://github.com/sipcapture/homer/pull/949

The default compaction engine is still `duckdb` — nothing changes unless you opt in. `engine=native` is now safe to try: every catalog write goes through `ducklake_add_data_files`, so DuckLake alone allocates snapshot and file IDs (this is what corrupted catalogs before). Merging is done in Go, outside DuckDB's `memory_limit`, and a partition is left alone rather than merged when it is unsafe or not worth it: source row groups larger than `max_row_group_bytes` (default 256MB uncompressed), row-level delete files in that partition, inlined data, hive-style data paths, or a column type that survives the parquet round trip differently than the catalog declares it. `min_age_sec` now actually works and defaults to 300s so a busy writer still consolidates during the day.

Real-file measurement: Homer rows are wide (~7KB), so a 10.5k-row row group is ~1.5GB uncompressed and merging three of them peaked at ~10GB RSS. `max_row_group_bytes` is the guard against exactly that — see `docs/OOM.md` before raising it.

Retention can now be expressed in hours via `retention_unit: "hours"`, which reinterprets the existing `retention_days` values. Default behavior is unchanged. Note that an hours cutoff falls mid-day and creates row-level delete files, which makes the native engine skip that one partition until retention removes the whole day.

**Full Changelog**: https://github.com/sipcapture/homer/compare/11.0.320...11.0.321