Skip to content

Explorer reads samples_map_lite_v3 twice via range requests (~120 MB for a 63 MB file) β€” #345 fixes time-to-usable, not total bytesΒ #351

Description

@rdhyee

πŸ€– rbotyee (Claude, operated by @rdhyee) β€” Raymond's intent: ship #345, but with the numbers stated honestly. What I did: measured the canary (shim on) against production (shim off) three ways on 2026-08-27 and found that the headline "74 MB β†’ 3.8 MB" describes bytes until the facets are usable, not the full cold boot. Filing the part the shim does not fix.

Finding

With range requests working (canary), DuckDB-WASM reads isamples_202608_samples_map_lite_v3.parquet (62.9 MB) in full β€” twice: ~237 ranged GETs, ~120 MB transferred, ~63 MB unique coverage (100 % of the file), ~48 % overlap. It happens in the background over ~40 s after the facets are already on screen.

cold boot, unthrottled, Chromium production (shim off) canary (shim on)
bytes until facets usable ~74 MB ~3.5 MB ← the #345 win
sample_facets_v4 (69.4 MB) 69.4 MB whole 9.9 MB ranged (14 %)
sample_facet_masks (10.1 MB) 10.1 MB whole 0.8 MB ranged (8 %)
samples_map_lite_v3 (62.9 MB) 62.9 MB whole, once ~120 MB ranged, read twice
full-boot parquet bytes (60 s) ~144 MB ~131 MB
"falling back to full HTTP read" 9 0

So #345 turns a 74 MB blocking download into a 3.5 MB one (the 3G time-to-facets goes 423 s β†’ 78 s), but the total transferred over a full boot is roughly unchanged, because the map file is scanned end-to-end regardless β€” and now twice.

Likely cause / fix

Two consumers scan the lite file (globe points and the table/count?), each pulling every row group through DuckDB-WASM's buffer, so ranged reads re-fetch what a single whole-file read got once. Options: (a) load samples_map_lite_v3 once into a DuckDB table at boot and have every consumer read the table; (b) one explicit whole-file fetch for that file only (it is always read entirely), keeping range reads for the facet files; (c) check for duplicate read_parquet of the same URL in explorer.qmd. Fixing this would make the full-boot total ~70 MB lower than today.

Method: Playwright page.on('response') over every .parquet GET incl. Web-Worker fetches, summing Content-Length (206 = range length) and merging Content-Range intervals for unique coverage; harness tests/playwright/bandwidth_matrix.py (on perf/313-bandwidth-findings, host filter widened to workers.dev) reproduces the 3.5 MB-to-milestones figure. Scripts: /tmp/measure_parquet_bytes.py, /tmp/measure_ranges.py (local; will add to the repo).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions