zpl.tools
Performance

zpl.tools and Neodynamic ZPLPrinter

Response time, accepted page counts and response size, measured 2026-08-17

Neodynamic ZPLPrinter is a local engine: commercial .NET engine in its docker web API. This page compares it with zpl.tools engine — the same renderer as the API, on localhost. Neither side crosses a network. A local engine is never compared with the hosted zpl.tools API, because the API adds network time that a local call does not carry.

Response time

Median response time, orderful style
  • zpl.tools engine
  • Neodynamic ZPLPrinter
05001,0001,5002,0000100200300400500Pages per requestMedian response, ms1,808 ms363 ms
Orderful style, PDF.
Values behind this chart
Engine1 p2 p3 p4 p5 p10 p15 p20 p25 p30 p35 p40 p45 p50 p75 p100 p150 p200 p300 p500 p
zpl.tools engine9 ms4 ms10 ms15 ms17 ms27 ms25 ms39 ms42 ms42 ms51 ms57 ms58 ms50 ms83 ms73 ms136 ms166 ms212 ms363 ms
Neodynamic ZPLPrinter38 ms65 ms86 ms105 ms121 ms214 ms299 ms386 ms476 ms562 ms660 ms748 ms838 ms911 ms1,359 ms1,808 ms

On one page, zpl.tools engine answers in a median 9 ms and Neodynamic ZPLPrinter in 38 ms, a factor of 4.2. At 100 pages, the largest packet the benchmark sent to both engines, the medians are 73 ms and 1,808 ms. zpl.tools engine rendered 500 pages in a median 363 ms, and 500 pages is where the benchmark stopped — the renderer sets no page limit. The benchmark measured Neodynamic ZPLPrinter to 100 pages.

Response size

PDF response size, orderful style
  • zpl.tools engine
  • Neodynamic ZPLPrinter
0 B19.07 MB38.15 MB57.22 MB0100200300400500Pages per requestResponse body45.82 MB787.2 KB
Orderful style, PDF.
Values behind this chart
Engine1 p2 p3 p4 p5 p10 p15 p20 p25 p30 p35 p40 p45 p50 p75 p100 p150 p200 p300 p500 p
zpl.tools engine13.9 KB15.8 KB17.9 KB20.7 KB23.3 KB41.6 KB51.5 KB62.5 KB71.7 KB80.9 KB90.6 KB99.4 KB108.2 KB117.4 KB160.0 KB200.4 KB286.9 KB357.3 KB500.9 KB787.2 KB
Neodynamic ZPLPrinter443.9 KB874.3 KB1.32 MB1.76 MB2.20 MB4.57 MB6.93 MB9.21 MB11.40 MB13.70 MB16.07 MB18.25 MB20.63 MB22.74 MB34.33 MB45.82 MB

A one-page PDF from zpl.tools engine is 13.9 KB. At 500 pages the same response is 787.2 KB: 56.8 times the size for 500 times the pages. The PDF writer stores one copy of a repeated page and references it, so a packet grows by its per-page content, not by a whole page. At 100 pages, the response is 200.4 KB against 45.82 MB from Neodynamic ZPLPrinter.

Corpora

Each corpus is one request body, repeated at every page count. A corpus reaches this page only where the run measured both engines on it.

Simple label

Labelary's own example label, duplicated per page. Every page carries the same label.

Pageszpl.tools engine p50zpl.tools engine p90zpl.tools engine p95Neodynamic ZPLPrinter p50Neodynamic ZPLPrinter p90Neodynamic ZPLPrinter p95
16 ms6 ms7 ms44 ms60 ms109 ms
1020 ms21 ms21 ms179 ms182 ms182 ms
5024 ms24 ms25 ms826 ms834 ms836 ms
10073 ms74 ms75 ms1,625 ms1,691 ms1,746 ms
500209 ms211 ms212 ms

GS1 graphics label

A real retailer label with embedded ~DG graphics, duplicated per page. Every page carries the same label.

Pageszpl.tools engine p50zpl.tools engine p90zpl.tools engine p95Neodynamic ZPLPrinter p50Neodynamic ZPLPrinter p90Neodynamic ZPLPrinter p95
111 ms12 ms12 ms42 ms46 ms46 ms
1018 ms19 ms19 ms223 ms239 ms239 ms
5035 ms37 ms37 ms953 ms968 ms974 ms
10062 ms72 ms73 ms3,026 ms3,203 ms3,289 ms
500178 ms182 ms184 ms

Orderful style

Orderful retail compliance labels, a different label on every page. Every page carries a different label, so no engine can reuse a page it already rendered.

Pageszpl.tools engine p50zpl.tools engine p90zpl.tools engine p95Neodynamic ZPLPrinter p50Neodynamic ZPLPrinter p90Neodynamic ZPLPrinter p95
19 ms12 ms12 ms38 ms40 ms40 ms
1027 ms33 ms33 ms214 ms221 ms221 ms
5050 ms52 ms52 ms911 ms949 ms950 ms
10073 ms75 ms78 ms1,808 ms1,825 ms1,830 ms
500363 ms367 ms368 ms

SPS Style

The same retailer labels delivered as ~DG bitmap pages, the SPS Commerce way. Every page carries a different label, so no engine can reuse a page it already rendered.

Pageszpl.tools engine p50zpl.tools engine p90zpl.tools engine p95Neodynamic ZPLPrinter p50Neodynamic ZPLPrinter p90Neodynamic ZPLPrinter p95
19 ms12 ms12 ms33 ms37 ms39 ms
1031 ms34 ms34 ms236 ms247 ms249 ms
50114 ms115 ms116 ms1,091 ms1,125 ms1,228 ms
100203 ms206 ms206 ms2,182 ms2,412 ms2,503 ms

Method

k6 drives every point, one request at a time, 10 iterations per point, 5 past 150 pages. A one-page point carries 10 samples.

Client: k6, one request at a time. Both hosted engines measured in the same session from a Hetzner ccx13 (dedicated vCPU) in the fsn1 datacenter, Germany — network RTT included, the same for both sides. Local engines measured on a MacBook Pro (Apple Silicon), no network crossed; the zpl.tools, zebrash, BinaryKits and Neodynamic summaries carry over from the 2026-08-09 run, because no code in the render path changed between them. labelize was added on 2026-08-17 and measured on the same MacBook, at one page only — see below.

Measured 2026-08-17. The harness is benchmarks/run.sh, and its header names the local servers each engine needs. To repeat the run:

./benchmarks/run.sh
node scripts/distill-benchmarks.mjs
node scripts/generate-performance-pages.mjs

The first command measures, the second writes website/lib/performance-data.json, and the third writes this page from it.