Benchmarks
These numbers come from the streaming benchmark in packages/benchmark, run on 2026-09-22 against version 4.2.0 and the current engine with the same harness, schema and data. The charts read the published report directly.
Export time
Each workload writes an 11-column report with styles, dates, number formats and summary rows, committed in 5,000-row batches. Every notes cell contains XML-reserved characters and Unicode, so escaping is part of the measurement.
The current engine is 3.2× to 3.4× faster across the four workloads. The gain is in row processing and spooling: finalizing the ZIP still takes about one second at 200k rows and 2.4 seconds at 500k, as before.
Peak memory
With inline strings, peak memory barely moves between 200k and 500k rows (274 and 279 MiB). Shared strings trade memory for a smaller file: the string table stays in memory until the workbook is finalized. See Large Exports for how to choose.
Memory is not constant for every schema. Shared strings, merged sub-rows, images, hyperlinks and row-aware summary formulas keep their own metadata for the whole export.
A real application export
The same engines exported a production-shaped report from a local PostgreSQL database: 202,058 records, 25 columns, 41 batches, with file spooling and the low-memory profile. The whole worker job went from 40.3 s to 19.4 s.
| Phase | 4.2.0 | Current |
|---|---|---|
| Fetch hydrated records | 11.08 s | 10.58 s |
| Commit XLSX rows | 27.21 s | 6.88 s |
| Finalize XLSX | 1.66 s | 1.54 s |
| Whole job | 40.33 s | 19.36 s |
Writing the five million cells went from 27.2 s to 6.9 s, so fetching from the database is now the slowest phase. Both versions produced byte-identical files (21,832,191 bytes).
How it was measured
- Node 24.13.0 on an Apple M5 with 32 GiB of RAM, macOS.
- Baseline and current engine run serially in alternating fresh processes.
- 200k-row results are the median of three runs. The 500k-row case is a single run per engine, so read it as a scaling check.
- Peak memory is the process high-water mark (
maxRSS). - All 20 benchmark workbooks are byte-identical between the two engines.
These are local measurements, not a production or concurrent-load guarantee. The full report, raw JSON and the commands to reproduce it are in packages/benchmark/artifacts/reports/stream.