# QR code generation performance

> Encoding a QR matrix is trivial — microseconds to low milliseconds on any modern CPU. Rendering dominates the cost: building an SVG string is cheap, rasterising a PNG is 10 to 100 times more expensive. Performance only matters in batch jobs, hot API paths and serverless cold starts; for one code at a time, everything is fast enough.

Source: https://useqr.app/docs/developers/qr-code-generation-performance · Last reviewed 2026-08-21 · UseQR is free forever, MIT licensed, no signup.

---

## Where the time actually goes

"Generate a QR code" is three stages with wildly different costs:

| Stage | What happens | Order of magnitude |
|---|---|---|
| Encode | segment data, add [Reed–Solomon](/glossary/reed-solomon) codewords, choose a [mask](/glossary/mask-pattern) | microseconds to low milliseconds |
| Render to SVG | walk the matrix, emit path strings | comparable to encoding |
| Rasterise to PNG | rasterise vector shapes, encode PNG | **10–100× the encode cost**, growing with pixel size |

We deliberately give orders of magnitude rather than a benchmark table: absolute
numbers vary by CPU, runtime, library and payload, and published QR benchmarks age
badly. The *shape* of the cost is stable, and it is the shape that should drive your
decisions.

Two things make encoding more expensive, both modestly: longer payloads (a
[version 40](/docs/reference/qr-code-version-and-module-table) code has a 177×177
matrix versus 21×21 for version 1) and mask selection, which scores up to
[8 candidate masks](/docs/spec/mask-selection-penalty-scores) against penalty rules.
Even so, encoding almost never appears in a profile. Rasterisation always does.

## Consequences

**Prefer SVG when you can.** An SVG is a string — no pixel work, tiny output,
scale-free, and [better for print](/docs/print/why-you-should-print-qr-codes-from-svg)
anyway. UseQR's batch endpoint caps rendered-PNG batches at 100 items but URL/SVG
batches at 1,000, precisely because rasterisation is the expensive stage.

**Rasterise per size, cache the matrix.** The matrix depends only on data and EC
level; pixel output depends on size and styling. If you serve one payload at several
sizes, compute the matrix once and rasterise per request — or better, rasterise once
per size and cache the bytes, since output is deterministic
([caching strategy](/docs/developers/caching-and-cdn-strategy-for-qr-images)).

**Batch cost is rendering cost.** A million-code job spends its time in the
rasteriser and the filesystem, not the encoder. Parallelise across cores and emit SVG
where the downstream tooling allows —
[bulk generation at scale](/docs/developers/bulk-qr-generation-at-scale) covers the
worker-pool pattern.

**Pixel size is a real knob.** PNG rasterisation cost scales with the pixel area, so
a 4096 px render is roughly an order of magnitude more work than 1024 px. Generate at
the size you need, not the maximum you might someday want — the
[size calculator](/size-calculator) tells you what you need.

## When performance actually matters

Honest list — for a single code in a UI, every library and API is effectively instant,
and optimising there is wasted effort. It matters in:

- **Batch jobs** — thousands to millions of renders multiply every per-code cost.
- **Hot API paths** — a QR image endpoint under real traffic wants deterministic
  output and long-lived caching far more than a faster encoder; a cache hit is always
  cheaper than the fastest render.
- **Serverless** — where bundle size and native dependencies affect cold starts more
  than compute does; pure-JS generators keep functions small
  ([details](/docs/developers/qr-codes-in-serverless-functions)).
- **Embedded and low-power devices** — the one context where encoder implementation
  genuinely matters, and where matrix caching buys the most.

One measured data point from UseQR's own pipeline: CI decode-verifies the full
permutation matrix of module styles, eye styles, gradients and EC levels — hundreds of
render-plus-decode round trips — and the decode step, not generation, dominates that
suite's runtime. Decoding is computer vision; generation is arithmetic.

## FAQ

### How long does it take to generate a QR code?
Encoding the matrix takes microseconds to low milliseconds on any modern hardware. Rendering dominates: an SVG string is nearly free, while rasterising a large PNG can take tens of milliseconds. For interactive use, everything is effectively instant.

### Why is my bulk QR job slow?
Almost certainly rasterisation and disk I/O, not encoding. Switch to SVG output if downstream tools accept it, render at the size you need rather than the maximum, and parallelise across CPU cores with a worker pool.

### Is SVG faster than PNG for QR codes?
Yes, by a wide margin — SVG generation is string building while PNG requires rasterising every pixel, and the gap grows with image size. SVG is also smaller to store and sharper to print.

### Do longer URLs make QR generation slower?
Slightly. Longer payloads mean higher versions with larger matrices and more error-correction maths, but encoding stays in the low-millisecond range even at version 40. The real cost of long URLs is scan reliability, not generation speed.

## Try it

- https://useqr.app/url
- https://useqr.app/bulk
- https://useqr.app/validate
