Skip to content

Raise default global-dict retained budget 1GB -> 2GB (#303 finding 2)#306

Merged
dfa1 merged 1 commit into
mainfrom
dict-budget-2gb
Jul 25, 2026
Merged

Raise default global-dict retained budget 1GB -> 2GB (#303 finding 2)#306
dfa1 merged 1 commit into
mainfrom
dict-budget-2gb

Conversation

@dfa1

@dfa1 dfa1 commented Jul 25, 2026

Copy link
Copy Markdown
Owner

What

On a wide, high-cardinality file, the global-dict retained budget (1 GB) is too tight: the writer buffers each admitted column's per-chunk codes in memory until close() (~37 MB/column, the ADR 0021 design), and with ~30 dict columns on nyc-311 the total (~1.15 GB) crosses the budget. Eviction then demotes the largest-retained columns — the highest-cardinality ones — to per-chunk dictionaries, repeating their values pool each chunk. That's exactly what happened to Cross Street 1/2 and Street Name (#303 finding 2).

How

Raise the default globalDictMaxRetainedBytes from 1 GB to 2 GB. Measured: 2 GB, 3 GB, and 8 GB all produce the identical file, so nyc-311's retained total tops out ~1.15 GB and 2 GB fits it with headroom while still bounding the pathological many-wide-columns risk. Constrained-heap writers can lower it via withGlobalDictMaxRetainedBytes(...).

Tradeoff (why this is a policy bump, not a pure bug fix)

The budget exists to cap writer memory. Raising it lets the writer buffer up to 2 GB before evicting, so a wide/tall enough file uses more heap. This is a deliberate size↔memory tradeoff, kept overridable per-write.

Impact (real nyc-311 corpus, off main)

vortex-java vs vortex-jni (1762 MB)
Before (main) 1934.23 MB 1.10×
After 1879.34 MB 1.07×

−54.9 MB off main. Note this overlaps #305 (both improve the same street columns — this PR keeps them global, #305 bitpacks per-chunk codes): stacked on #305 the budget adds ~35 MB net (1862 → 1827 MB), not another 55.

Testing

  • WriteOptionsTest default assertions updated to 2 GB.
  • Full ./mvnw verify green.

Closes #303.

)

On a wide, high-cardinality file the per-column code buffers (~37 MB each,
ADR 0021) sum past the 1 GB budget, and eviction demotes the largest-retained —
i.e. the highest-cardinality — columns to per-chunk dictionaries, repeating their
values pool every chunk. nyc-311 (~30 admitted string columns ≈ 1.15 GB retained)
lost its three Cross Street / Street Name columns this way.

Raise the default to 2 GB, which fits that file with headroom (measured: 2 GB and
3 GB both match the 8 GB result, so retained tops out ~1.15 GB) while still bounding
the pathological many-wide-columns risk. Constrained-heap writers can still lower it
via withGlobalDictMaxRetainedBytes(...).

nyc-311 re-encode: 1934.23 MB -> 1879.34 MB (1.10x -> 1.07x vortex-jni). This
overlaps #305 (both improve the street columns, via keeping-global vs bitpacked
codes): stacked on #305 the budget adds ~35 MB net (1862 -> 1827 MB).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dfa1
dfa1 merged commit de8d2c7 into main Jul 25, 2026
6 checks passed
@dfa1
dfa1 deleted the dict-budget-2gb branch July 25, 2026 06:18
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.

nyc-311: global-dict street columns ~54MB larger than vortex-jni (dict codes not bitpacked?)

1 participant