Skip to content

Add workload descriptions to YCSB benchmark series names - #1391

Merged
kriszyp merged 5 commits into
mainfrom
kris/ycsb-workload-titles-core
Jun 19, 2026
Merged

Add workload descriptions to YCSB benchmark series names#1391
kriszyp merged 5 commits into
mainfrom
kris/ycsb-workload-titles-core

Conversation

@kriszyp

@kriszyp kriszyp commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

The nightly YCSB cluster trend dashboard (github-action-benchmark) emitted bare chart-series names — load, workload A, C read p99 — so the dashboard titles and legends weren't self-explanatory. This appends a brief workload description to each throughput and latency series name in the converter.

The description is sourced from the results JSON's per-workload description (written by harness.mts), falling back to the authoritative WorkloadSpec.description in workload.mts so labels stay accurate even for results that predate the description field.

Resulting names (confirmed against workload.mts):

  • load — bulk insert
  • workload A — Update heavy (50% read / 50% update)
  • workload B — Read mostly (95% read / 5% update)
  • workload C — Read only (100% read)
  • workload E — Short ranges (95% scan / 5% insert)
  • workload F — Read-modify-write (50% read / 50% read-modify-write)
  • latency, e.g. A update p99 — update heavy (short tag = the phrase before the op-mix parenthesis)

Attention

  • Renaming series starts new lines on the dashboard. github-action-benchmark keys each series by name, so the old-named series stop updating and new ones begin. This is expected and intended (the cross-model review flagged the same continuity break — it's the deliberate tradeoff here).
  • to-benchmark-json.mts is a standalone CLI invoked by the workflow (not part of the unit-test tree); verified by running it against a sample results file. The shortTag/describeWorkload helpers are exercised through that run.

Coordination

Paired with HarperFast/harper-pro#425, which guards the publish step against partial/cancelled runs and bumps the core submodule pointer to this commit.

Generated by Claude (Opus 4.8).


Follow-up addition (same branch) — --reps median-of-N in the harness

Layered on top of the series-name change above, to reduce the cluster bench's healthy-run jitter.

harness.mts gains a --reps flag (default 1, so single-node behavior is unchanged). When reps > 1, each workload runs N times and the reported point is the median rep by throughput (medianByThroughput). Returning a whole rep — rather than computing each metric's median independently — keeps the reported throughput and its latency block internally consistent (they come from one real run). A single degenerate rep sorts to an end of the set and is never selected; for an even count we take the lower-middle (the more conservative throughput).

  • Warmup runs once per workload, not per rep — the dataset is already hot after the first rep, so re-warming each rep would only add runtime.
  • The cluster runner (harper-pro Update @fastify/static #425) opts into --reps=3.
  • Results JSON gains additive per-workload reps/repThroughputs fields. to-benchmark-json.mts and validate-benchmark-json.mts only read name/description/throughput/latency, so both ignore the new fields and stay compatible (verified by round-tripping a synthetic 5-workload result through convert + validate).

Attention

  • medianByThroughput is not covered by workload.test.mts (it lives in the standalone harness CLI, like the existing convert helpers); verified via a direct round-trip script. Existing workload.test.mts still passes (10/10).

Generated by Claude (Opus 4.8).

The github-action-benchmark dashboard keys each chart series by name, but
the YCSB converter emitted bare names ("load", "workload A", "C read p99"),
so the trend titles/legends were not self-explanatory. Source the workload
description from the results JSON (falling back to the authoritative
WorkloadSpec in workload.mts) and append it to each throughput and latency
series name, e.g. "workload A — Update heavy (50% read / 50% update)" and
"A update p99 — update heavy".

Renaming series starts new lines on the dashboard (series are keyed by
name); the old-named series stop updating. This is expected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request enhances the YCSB benchmark JSON conversion script by incorporating workload descriptions and short tags into the output benchmark names. The reviewer provided valuable feedback on improving robustness, specifically recommending defensive checks to prevent runtime errors if the load phase or workloads array are missing, and suggesting a way to avoid redundant suffix tags when the workload description falls back to the workload name.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread benchmarks/ycsb/to-benchmark-json.mts Outdated
Comment thread benchmarks/ycsb/to-benchmark-json.mts
@claude

claude Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Reviewed the follow-up commits (--reps median-of-N, keyspace carry-forward, reps clamping); no blockers found.

The reps clamp guarantees Math.max(1, …) so medianByThroughput is never called with an empty array. The even-count lower-middle selection (Math.floor((sorted.length - 1) / 2)) is correct. The optional load? in the converter's Results interface is independently guarded; BenchmarkResults.load in the harness remains required, so printReport is safe. New tests cover median selection, clamping, keyCount tracking, and converter label logic.

Each workload can run N repetitions; the reported point is the median rep by
throughput, dampening healthy-run jitter so the nightly trend is robust to a
single degenerate rep. Warmup stays once per workload (the dataset is hot after
the first rep). reps defaults to 1, so single-node behavior is unchanged; the
cluster runner opts into 3. Result JSON gains additive reps/repThroughputs
fields, which the convert + validate scripts ignore.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kriszyp

kriszyp commented Jun 19, 2026

Copy link
Copy Markdown
Member Author

Pushed a follow-up on this branch: a --reps median-of-N flag in harness.mts (default 1, so single-node is unchanged). When reps > 1 each workload runs N times and the reported point is the median rep by throughput — a whole rep, so its throughput and latency block stay internally consistent, and a single degenerate rep is never selected. Warmup runs once per workload, not per rep.

The cluster runner (harper-pro #425) opts into --reps=3. Results JSON gains additive reps/repThroughputs fields that the convert + validate scripts ignore, so both stay compatible (verified). Existing workload.test.mts still 10/10.

— Claude Opus 4.8

kriszyp and others added 3 commits June 19, 2026 06:49
Cross-model review flagged that insert-bearing workloads (E, D) re-inserted the
same keys each rep — a fresh KeyState per rep seeded at config.records made reps
2+ PUT-overwrite the keys rep 1 inserted instead of growing the keyspace. Carry
the acknowledged readable count forward between reps (new KeyState.keyCount
getter) so each rep allocates fresh insert keys, mirroring one continuous run.
Read/scan-only workloads never advance it, so they're unaffected. The carry stays
within the existing key-width budget (worst case records + reps × insertFraction ×
ops < records + ops).

Adds unit coverage: medianByThroughput (middle rep, ignores a degenerate run,
conservative lower-middle on even counts, single-rep no-op) and the KeyState
frontier the carry-forward relies on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two hardening fixes from cross-model review:
- parseOptions now floors and clamps --reps to >=1, so a non-numeric/zero/negative
  value can't leave it NaN — that would make the rep loop never run and
  medianByThroughput crash on an empty set. Covered by a parseOptions test.
- keyWidth budgets for records + reps × opsPerWorkload (every rep all-inserts, the
  pessimistic bound) so the carried-forward keyspace can never overflow the padded
  key width, regardless of a workload's insert fraction.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… tags

- to-benchmark-json: omit the `load` series instead of throwing when
  `results.load` is absent (e.g. a run against a pre-loaded dataset).
- describeWorkload now returns undefined when no real description exists,
  so an unknown workload no longer renders "workload FOO — FOO" / a "foo"
  latency tag — the suffix/tag are dropped instead.
- Extract pure `convert()` and gate `main()` behind an import.meta guard
  so the logic is unit-testable; add to-benchmark-json.test.mts covering
  the normal run, missing-load, no-description, and result-description cases.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@kriszyp
kriszyp merged commit be796d2 into main Jun 19, 2026
51 checks passed
@kriszyp
kriszyp deleted the kris/ycsb-workload-titles-core branch June 19, 2026 19:34
kriszyp added a commit that referenced this pull request Jun 23, 2026
…l runs, timestamp x-axis

- Merge pre-#1391 bare series names into their descriptive equivalents so each
  metric is one continuous trend line (was double-plotting old + new after #1391).
- Drop partial-run outliers (commit points with fewer benches than a full run).
- Custom index.html: timestamp x-axis, commit SHA + click-to-open in tooltip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

1 participant