Benchmarks
XY's large-data claim is about the representation sent to a fixed-size output, not about drawing every source row as an individual marker. The committed 0.1.0 launch baseline measures identical seeded scatter data at 900×420 pixels on an Apple M5 Pro with 64 GiB RAM. Each successful cell below is the mean of three isolated cold runs. The machine name and memory are copied verbatim from the committed environment record.
How to read this comparison. XY switches dense scatter output to a screen-bounded density representation, while the default Plotly and Matplotlib paths retain every marker. These results compare each library's default user-visible outcome at the same output size; they do not claim that the libraries send identical geometry to the renderer.
Snapshot at 10 million points
10M-point cold-render time
900×420 output · mean of three isolated runs · shared linear scale
These summary tables show means only; the linked launch report publishes the sample standard deviation for every successful timing cell. Small reversals in adjacent means, such as 100k versus 1M on the default interactive path, are within the observed three-run variation and should not be read as evidence that more rows are inherently faster.
The output contracts are intentionally separate. Static PNG rows compare validated CPU-rendered images. Interactive rows include figure construction, standalone HTML, a fresh browser, readiness, GPU completion, and a nonblank pixel check. Hardware-WebGL and SwiftShader results are never merged.
Time and memory across scale
The 10-million-point snapshot is one point on a larger curve. Static render time stays close to the output cost after XY switches to density, while the exact-marker paths continue to grow with the number of rows. Peak process-tree RSS tells the same practical story from a different angle.
Static render time by input size
Static 900×420 PNG · measured runs · × marks guarded failures
10M static peak RSS
Static 900×420 PNG · complete process tree · GiB
At 10 million points, the static CPU output contract recorded:
Plotly's static value includes the Kaleido and Chrome processes used by
to_image(). RSS was sampled across each complete process tree every 50 ms, so
very brief peaks may be missed. At one billion points, XY's successful static
row peaked at 22.414 GiB; Matplotlib crossed the 36 GiB guardrail and Plotly did
not produce a PNG on its first guarded attempt.
What scales with rows—and what does not
XY keeps exact source columns in Python. Ingest, range scans, binning, and line decimation still perform work that depends on the number of source rows. Once a large scatter has been reduced, however, the density grid and retained sample are bounded by the viewport rather than growing one marker per row. Long line output is similarly bounded after decimation.
That distinction is visible in the recorded sweep:
At one billion points, XY ingested the rows and produced a validated density PNG and interactive density overview. It did not draw one billion markers. The exact-point Plotly and Matplotlib paths did not complete at that size within this run's 36 GiB process-tree and 180-second limits; those are local guarded outcomes, not universal limits.
What this benchmark does—and does not show
The result is strongest as an end-to-end product comparison: what a user gets from the default API under a fixed output contract. A separate like-for-like representation study is still useful when the question is about the cost of aggregation itself.
Next benchmark coverage
The repository already has harnesses for more than the launch scatter. Results will be published separately as their contracts and reference artifacts are frozen:
- Adaptive peers: dense scatter against Datashader / HoloViews and long lines against Plotly Resampler, kept separate from exact-marker baselines.
- Interaction and applications: pan and zoom refinement, selection, append/streaming updates, transport, and 10/20/50-chart dashboards.
- More chart families: long lines and heatmaps, where decimation and fixed-resolution aggregation exercise different kernels.
- Release and hardware tracking: immutable release directories plus clearly separated macOS hardware-WebGL and CI SwiftShader results.
Until those artifacts are published, this page intentionally keeps its headline claims scoped to the committed launch scatter.
Inspect and reproduce the evidence
The baseline records its source commit (7228f99), exact dependency lock,
hardware, browser, raw samples, failure rows, and render oracles:
After completing the runbook setup, reproduce the frozen default-path sweep from the source revision recorded in the environment file:
One machine and three runs describe that recorded environment, not every machine or workload. New comparisons should retain chart type, data size, representation, backend, output target, and browser-TTFR status rather than shortening these results to a universal “faster than” claim. For the rendering model behind the numbers, read Large data and performance.