Design
QR code error correction: what L, M, Q and H really cost you
Higher error correction is not automatically safer. Here is what each level recovers, what it costs in capacity and module size, and when to use which one.
Someone raises error correction to H because it sounds like the careful choice, prints the code at 20 mm on a business card, and produces a symbol that is harder to scan than the M version they started with. The redundancy is real; so is the price, and almost nobody prices it.
What the four levels promise
QR codes carry Reed-Solomon error correction codewords alongside the data codewords. The four levels defined by ISO/IEC 18004 differ only in how many:
| Level | Recovery | Data capacity vs L | Typical name |
|---|---|---|---|
| L | ~7% | 100% | Low |
| M | ~15% | ~79% | Medium |
| Q | ~25% | ~56% | Quartile |
| H | ~30% | ~43% | High |
The capacity column is the part people miss. At the largest version, byte mode holds 2,953 bytes at L and 1,273 at H — level H throws away more than half the symbol’s capacity to buy 30% damage tolerance. In practice you rarely notice this as “the code refused my text”; you notice it as the code silently getting denser.
One more clarification on that 30%: it is 30% of the codewords, not a guarantee that any 30% of the picture can be destroyed. The finder patterns in the corners and the timing pattern between them are structure, not data. Damage those and the decoder never locates the grid, whatever the level says.
The cost is measured in modules
A QR symbol comes in versions. Version 1 is 21 modules across, and every version up adds four: version 4 is 33, version 5 is 37, version 10 is 57, version 40 is 177. When you raise the error correction level, the same payload no longer fits in the same version, so the encoder promotes it — and the printed code is suddenly made of more, smaller squares.
At a fixed print size, module size is simply the code width divided by the module count. This is the whole trade-off in one line.
The same URL at four levels
Take a sixty-character link — a domain, a path, no tracking parameters — encoded in byte mode:
| Level | Version | Modules per side | Module size at 25 mm |
|---|---|---|---|
| L | 4 | 33 | 0.76 mm |
| M | 4 | 33 | 0.76 mm |
| Q | 5 | 37 | 0.68 mm |
| H | 7 | 45 | 0.56 mm |
L and M land in the same version here, so M is free — you gain 15% recovery
for no increase in module count at all. That is why M is the right default and
why the image API defaults to M — pass ?ec=l, q or h when
you want one of the others.
H is a different story. 0.56 mm is close to the 0.4 mm practical floor for offset print and already under the ~0.6 mm you want for thermal labels or rough stock. You have bought damage tolerance and spent it on making every module harder to resolve. The print size guide has the per-module minimums by process.
Choosing by medium
| Medium | Level | Why |
|---|---|---|
| Screen, slide, email, social | M | Nothing degrades a backlit image; keep modules large |
| Flyer, menu, poster, business card | M | Clean flat print; size is the constraint, not damage |
| Code with a centred logo | H | The logo is deliberate damage and must be covered |
| Thermal label, warehouse, industrial | Q | Survives scuffing and print head dropout |
| Curved surface — can, bottle, tube | Q | Optical distortion behaves like partial loss |
| Very large format, long URL | L | Modules are huge anyway; buy back the capacity |
The pattern: raise the level only when you can name the thing that will obscure the code. A logo, a fold, a scuff, a curve, a rubber stamp. “Just in case” is not a reason, because the redundancy is not free.
Why H is the wrong instinct on a small code
The failure mode is quiet. Nobody sees the version increase — the generator just draws a denser square, it still previews fine on a retina display, and the problem only appears in a restaurant with a three-year-old Android phone. The rule of thumb that keeps you out of it:
- Under 25 mm printed, use M and shorten the URL instead.
- Between 25 and 50 mm, M unless there is a logo, then H and make the code bigger to compensate.
- Above 50 mm, use whatever the surface demands; the modules have room.
If you find yourself at H on a small code because a logo has to fit, the real fix is usually the URL. Dropping four UTM parameters from a link can save a whole version, which is more module size than any level change will give you. Static versus dynamic QR codes covers the short-URL argument in more detail.
Level and logo are one decision
A centred logo needs H, because the area it covers is genuinely unrecoverable data — even at the 20–25% of the code’s width that is the sane working range, which is 4–6% of the symbol’s area. But H already pushed the code to a higher version, so the printed size has to grow too — otherwise you are stacking smaller modules underneath an obstruction. Setting H, adding a logo and keeping the original 20 mm artwork is the single most common way to produce a code that looks professional and does not work. Putting a logo in a QR code without breaking it works through the geometry.
What error correction never fixes
Redundancy recovers damaged modules. It does not help with:
- Low contrast. If the decoder cannot binarise the image, there are no codewords to correct.
- A missing quiet zone. The four-module margin is how the symbol is found.
- Blur and undersizing. These corrupt the whole symbol at once, not a recoverable fraction of it.
- A dead destination. A perfectly decoded 404 is still a 404.
Each of those has its own fix, and they are collected in why your QR code is not scanning.
Worth noting that this trade-off is not unique to QR. PDF417 exposes nine error correction levels, 0 to 8, and the same logic applies: more correction means more codewords means a physically wider symbol on the same label.
The generator exposes all four levels next to the live preview, so the honest way to make this decision is to set your real URL, flip between M and H, and watch the module count change. Then print the one you chose at final size and scan it before it goes anywhere near a print run.
Frequently asked
Does higher error correction make a QR code more reliable?
Which error correction level should I use for a QR code on a screen?
How much bigger does a QR code get when I switch from L to H?
Can I change the error correction level of a QR code after printing it?
- error correction
- design
- capacity
Make the code this guide describes
The generator runs in your browser — add a logo, pick colours, tag the link with UTM parameters and download a PNG or SVG. No account, no watermark.
Keep reading
-
Printing
What size should a printed QR code be?
The distance-to-size rule that decides whether a printed QR code scans, the minimum millimetres per module, and the quiet zone people keep cropping off.
-
Design
Putting a logo in a QR code without breaking it
Error correction level H tolerates about 30 percent damage, which is not permission to cover 30 percent of the code. Here is the size that actually survives.
-
Troubleshooting
Why your QR code is not scanning
A QR code that fails to scan usually fails for one of eleven reasons, and this walks through each of them with the fix, from contrast to dead short links.