Performance
Numbers below come from local measurements (real Chrome, 6 mixed-type columns). The Node in-process regression baseline (SLA 200/500/1000 ms) lives in src/__tests__/performance.test.ts; the toBuffer cliff is verified out-of-band via independent processes (see the package README).
Benchmarks
| Rows | Workbook (main) | Fast stream | What auto picks |
|---|---|---|---|
| 10,000 | ~120ms | — | main + Workbook |
| 50,000 | — | ~400ms | Worker + Fast stream |
| 100,000 | 17.5s (legacy) | ~780ms | Worker + Fast stream |
Takeaways
Workbook.toBuffer()shows a superlinear cliff beyond ~55k rows (17.5s at 100k), while Fast stream stays at ~0.8s — henceSTREAM_THRESHOLD = 50_000;- In the browser, ≥ 20,000 rows run in a Worker; the main thread only does one structured clone (~94ms at 100k rows);
- The stream path's cost is missing styles/layout, so small files keep the fully-styled Workbook path.
Optimization tips
- Stay on
mode: "auto"; never forcemainfor large files; - Keep styled exports under 50k rows; for larger data accept degraded styling or split sheets;
- Set
decimalsexplicitly onnumbercolumns for consistent stored values across paths (Workbook/Stream/fallback); - Run large server-side exports in background tasks.