QR Code Error Correction Levels: L, M, Q, H — Which Should You Use?
A practical guide to qr code error correction levels — what L, M, Q and H actually recover, what each level costs you in data capacity and print size, and which one to pick for a menu, a logo QR, a factory label or a billboard.
The Short Answer
QR code error correction levels are four settings — L, M, Q and H — that decide how much of a damaged, dirty or covered QR code a scanner can still read. L recovers roughly 7% of the pattern, M roughly 15%, Q roughly 25% and H roughly 30%. Higher recovery is not automatically better: every extra bit of recovery data makes the code denser, which means either a physically larger print or a tighter scan. For most Indian business printing — menus, flyers, shelf-talkers, standees — Q is the right default, which is exactly why SMLLR sets Q as the default on every code you create. Move up to H only when you are placing a logo in the middle of the code or printing into a genuinely harsh environment, and drop to L only for clean on-screen display.
- L — Low: ~7% recovery. Clean digital displays, in-app screens, PDFs nobody prints.
- M — Medium: ~15% recovery. General-purpose business use where nothing will touch the code.
- Q — Quartile: ~25% recovery. Printed materials and outdoor signage — SMLLR's default.
- H — High: ~30% recovery. Logo-in-the-middle designs, factory floors, cold storage, anything abrasive.
What Error Correction Actually Does
A QR code does not simply store your link once. It stores the link plus a block of mathematically derived recovery data, using an algorithm called Reed-Solomon coding — the same family of maths that keeps a scratched CD playing and a deep-space probe's telemetry intact. When a scanner reads a code, it reconstructs the data blocks; if some modules (the little black and white squares) are missing, smudged or covered, Reed-Solomon can rebuild the missing values from the recovery data, as long as the damage stays within the level's budget.
This is why the error correction level is not a "quality" slider where more is always better. It is a budget decision. You are deciding how much of the printed area you want to spend on insurance instead of on data. Our technical anatomy of a QR code post goes deeper into how the Reed-Solomon blocks and masking patterns are laid out inside the symbol itself.
The Real Trade-off: Recovery vs Density
Recovery data has to be printed somewhere, and that somewhere is inside the same square. Encode the same URL at L and at H and you get two visibly different codes: the H version has noticeably more modules packed into the same area, or needs a higher QR "version" (a larger module grid) to fit at all.
Denser modules have two practical consequences on the ground. First, each module is physically smaller at the same print size, so a phone camera needs to be closer or the print needs to be larger for a reliable scan — the 10:1 distance-to-size relationship covered in our QR code size guide still applies, but your starting size goes up. Second, cheap printing has less margin for error: a low-DPI flexo print on corrugated cardboard or a thermal label that bleeds slightly will blur small modules together faster than large ones.
So the honest framing is: H buys you damage tolerance and pays for it with print size. If you can't make the code bigger, jumping to H can make scanning worse, not better.
What Each Level Costs You in Data Capacity
The same trade-off shows up as raw capacity. At the largest QR version (version 40, a 177×177 module grid), the maximum byte capacity by level is:
| Level | Recovery | Max bytes at version 40 |
|---|---|---|
| L | ~7% | 2,953 |
| M | ~15% | 2,331 |
| Q | ~25% | 1,663 |
| H | ~30% | 1,273 |
Moving from L to H costs you well over half your usable capacity. For a dynamic QR code this barely matters — a SMLLR short link is a couple of dozen characters, so even H leaves enormous headroom. For a static code carrying a long raw URL with UTM parameters, a vCard, or a Wi-Fi config string, the level you pick can be the difference between a clean, scannable symbol and a dense mess. Our data capacity guide has the full numeric, alphanumeric and byte tables.
The Logo Question: Why Logo QR Codes Need H
Placing a brand logo in the centre of a QR code works because the logo is literally covering modules — and error correction is what lets the scanner rebuild them. This is the single most common reason to move off the default.
A practical rule: at H, you can usually cover up to roughly the middle 25–30% of the code's area before scan reliability starts to fall off, and you should stay comfortably inside that budget rather than testing the ceiling. Keep the logo centred (the corners hold the finder patterns and must never be covered), keep it compact, and leave a small clear margin between the logo edge and the surrounding modules.
Critically, the damage budget is shared. If you spend most of H's 30% on a logo, you have almost nothing left for a real-world scratch, a thumb smudge or a fold through the code. A logo that covers half the budget on a laminated menu is fine; the same logo on a carton that will be dragged across a warehouse floor is not. Our QR code logo design guide covers the placement and contrast rules that go with this.
Choosing a Level by Where the Code Is Going
Match the level to the physical reality of the placement, not to a preference for bigger numbers:
- L — Low: a code shown on a screen only — an in-app QR, a code on a TV or digital standee, a PDF invoice viewed on a phone. Nothing can physically damage a code that is never printed, so the recovery budget is wasted space.
- M — Medium: clean indoor print on good stock that nobody will handle roughly — a laminated table tent, a framed poster, a wall-mounted acrylic sign, a page inside a brochure.
- Q — Quartile: the safe default and the right answer for most Indian print runs. Flyers, pamphlets, newspaper inserts, shelf-talkers, outdoor standees, packaging labels, hoardings. Handles print variance, light soiling and outdoor weathering without inflating the code.
- H — High: logo-in-the-middle brand codes, factory and warehouse asset labels, cold-storage and refrigerated packaging where condensation is guaranteed, agricultural and construction-site signage, anything that will be scanned through a plastic sleeve or after months of UV exposure.
Where to Set It in SMLLR
In SMLLR the Error Correction Level selector sits in the design step of the QR create wizard, alongside the colour, shape and logo controls. It is available from the Starter plan (₹499/month) upward, and every code defaults to Q so you get sensible printed-material behaviour without touching anything.
One thing worth knowing if you use dynamic codes: because a dynamic SMLLR code encodes a short redirect link rather than your final destination URL, the payload stays tiny no matter how long or messy the destination is. That means you can raise the level to H for a logo design and still end up with a comfortably low-density, large-module code — which is precisely the combination you cannot get from a static code carrying a long URL. Our static vs dynamic comparison covers the rest of that difference.
Test Before You Commit to a Print Run
Whatever level you choose, print one physical proof at the exact final size, on the exact final material, and scan it the way a real customer will — from the real distance, at the real angle, under the real lighting. A code that scans instantly off a bright laptop screen can fail on matte recycled paper under a warm restaurant bulb.
If the proof is unreliable, the fix order is: make the code larger first, increase the quiet zone (the blank margin) second, raise contrast third, and only then reconsider the error correction level. Raising the level on a code that is already too small usually makes things worse, because it adds modules to a symbol that was short on physical space to begin with.
Create your QR code on SMLLR, set the error correction level in the design step, and download a print-ready vector file before your print run goes out.
Related Reading
Frequently Asked Questions
What are the four QR code error correction levels?
L, M, Q and H. L recovers roughly 7% of a damaged code, M roughly 15%, Q roughly 25% and H roughly 30%. Higher levels tolerate more damage but make the code denser, which usually means printing it larger.
Which error correction level should I use by default?
Q for anything printed. It recovers around 25% of the pattern, which handles ordinary print variance, light soiling and outdoor weathering without inflating the code. SMLLR sets Q as the default on every code for exactly this reason.
Do I need error correction level H for a logo in my QR code?
Yes, in practice. The logo covers modules, and error correction is what lets a scanner rebuild them. At H you can usually cover up to roughly the middle 25–30% of the code's area — but keep the logo well inside that budget so there is still damage tolerance left for real-world scratches and smudges.
Does a higher error correction level make a QR code harder to scan?
It can, if you don't also increase the print size. Higher levels add recovery modules to the same square, so each module gets physically smaller. On a code that was already borderline in size, moving from Q to H can reduce scan reliability rather than improve it.
How much data capacity do I lose moving from L to H?
A lot. At the largest QR version, L holds up to 2,953 bytes while H holds up to 1,273 bytes — well over half the usable capacity gone. This matters for static codes carrying long URLs or vCards, and barely matters at all for dynamic codes, which encode only a short redirect link.
Which SMLLR plan includes the error correction level setting?
The Error Correction Level selector is available from the Starter plan (₹499/month) upward, in the design step of the QR create wizard. Every code defaults to Q whether or not you change it.
Can I change the error correction level after printing the code?
No. The error correction level is baked into the printed pattern itself, so changing it means generating and reprinting a new code. What you can change on a dynamic SMLLR code without reprinting is the destination the code points to — that lives behind the redirect, not in the pattern.