Skip to content

[POC] xy chart decimation#2805

Draft
lukeelmers wants to merge 3 commits into
elastic:mainfrom
lukeelmers:poc/decimation
Draft

[POC] xy chart decimation#2805
lukeelmers wants to merge 3 commits into
elastic:mainfrom
lukeelmers:poc/decimation

Conversation

@lukeelmers
Copy link
Copy Markdown

@lukeelmers lukeelmers commented Mar 10, 2026

This is a proof of concept and performance analysis — not intended to merge as-is.

Summary

This POC set out to test whether decimation on xy charts could significantly improve rendering performance for large time series data. The short answer: decimation works as expected, but the client-side data pipeline is a bigger bottleneck. The most valuable outcome of this work is an instrumented breakdown that quantifies exactly where time is spent, and suggested we explore some of the data pipeline restructuring proposed in #2561.

What was observed

Using an instrumented benchmark that isolates each stage of the geometry computation pipeline, this data was taken using 1M points on a 1920×1080 panel:

Stage Time % of total
Data pipeline (computeSeriesDomainsSelector) 2,957ms 99.6%
Geometry rendering (with pipeline cached) 49ms 1.6%
Decimation scan 16.8ms 0.6%

The data pipeline — series splitting, gap filling, sorting, stacking, domain computation — dominates at every scale tested. Decimation reduces the rendering step to a constant cost (bounded by pixel width). Because the pipeline dwarfs both, the overall improvement from decimation alone is marginal... however it will become a more significant factor if the pipeline cost is able to be reduced.

What's included

Decimation implementation: An M4 decimation algorithm that divides ordered series data into pixel-width buckets, retaining up to 4 values per bucket: the first, minimum y1, maximum y1, and last. Compared to pure min/max bucketing, this also preserves the entry and exit points of each pixel column, producing a more accurate line shape. The algorithm is a single O(n) pass that activates when the point count exceeds DECIMATION_THRESHOLD_FACTOR * panelWidth (currently 4, configurable as a named constant in decimation.ts). It's injected into renderGeometries for line and area series, and because the decimated data flows through to renderPoints, the spatial index is also built from the reduced dataset.

Benchmark story: A Storybook story at Test Cases > Decimation Benchmark that generates time series data at configurable sizes (100K–10M) and displays render time.

Pipeline breakdown benchmark: A jest-based benchmark that separately measures the data pipeline, geometry rendering, and decimation scan to show where time is actually spent.

How to test

Start Storybook and navigate to Test Cases > Decimation Benchmark:

git checkout poc/decimation
yarn install
yarn start
# Open http://localhost:9001

To run the instrumented pipeline breakdown:

npx jest --config jest.config.js decimation_benchmark --verbose --testTimeout=300000
Screenshot 2026-03-10 at 9 16 08 AM

Learnings

  1. Server-side downsampling is our largest opportunity. Regardless of the client-side optimizations explored here, the single biggest performance improvement we can make is reducing the data sent over the wire to something more manageable and based on the available pixel space. This should be our top priority.

  2. Data pipeline restructuring (#2561) is our largest client-side opportunity. Reducing redundant scans, simplifying series grouping, and optimizing for common chart types (e.g., single time series without stacking) would have the largest impact on rendering times... but the most dramatic end-to-end gains will still come from server-side downsampling.

  3. Decimation can be easily layered in alongside or after pipeline work. It's a small change (~40 lines) that caps the post-decimation rendering cost at any scale. Once the pipeline is faster, decimation prevents rendering from becoming the next bottleneck — especially at very large data volumes (5M+) where even browser-accelerated Canvas would slow down.

@elastic-datavis
Copy link
Copy Markdown
Contributor

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