# 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, 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
