How QR Codes Work (and Error Correction Levels)
Photo by Unsplash on Unsplash
Table of Contents
How does a QR code store information?
> Quick answer: A QR code stores data as a grid of black and white squares (modules) that a scanner reads as 1s and 0s. The three big squares in the corners are finding patterns that let a camera locate and orient the code from any angle. Crucially, QR codes build in Reed-Solomon error correction, so a portion of the code can be dirty, torn or covered by a logo and it still scans. You pick how much protection at generation time — the QR code generator lets you set it.
The data itself is encoded in the smaller modules filling the grid, packed in a zig-zag pattern around the fixed structural elements. Bigger payloads need a bigger grid, called a higher version, with more rows and columns. But the part that surprises people is that not all of those modules hold your actual data — a chunk of them hold redundant recovery information, which is the whole reason a scuffed code still works.
Why do QR codes still scan when they're damaged?
The practical effect is that a QR code isn't fragile the way a barcode is. Smudge part of it, tear a corner, print it on a crumpled box, or slap a logo in the middle, and the scanner uses the redundant data to fill in the gaps and still read the original payload. There's a limit — lose too much and it fails — but within that limit, damage is genuinely tolerated, not just survived by luck.
That resilience is a design decision, not a happy accident, and it's why QR codes took over the physical world where barcodes struggled. It also explains a trade-off you control directly: more error correction means more of the grid is spent on recovery data rather than payload, so a more damage-proof code holds slightly less information or needs to be physically bigger. The DENSO WAVE team who invented QR codes document the error correction feature in detail.
What do the L, M, Q and H levels mean?
Level L (Low) recovers about 7% of the code. Bump up to M (Medium) and you get around 15%. Quartile — that's Q — recovers roughly 25%, and H (High) tops out around 30%. So an H-level code can lose nearly a third of itself and still scan, while an L-level code tolerates only minor smudging. Higher levels pack in more redundancy, which is exactly why they're more damage-tolerant.
The cost of that protection is capacity. Because the recovery data eats into the grid, a higher level either stores less payload or forces a bigger code to fit the same data. That's the balance you're striking every time you pick a level. Most everyday codes default to M, which is a sensible middle ground of decent protection without bloating the size.
Which error correction level should you use?
For a clean digital code on a website or a slide, L or M is plenty; nothing's going to damage a screen, so spending the grid on heavy redundancy is wasted. For printed codes that face the real world — packaging, posters, stickers, anything outdoors or handled a lot — bump to Q or H so scuffs and creases don't kill them. The rougher the environment, the higher you go.
The one case that trips people up is logos. If you want to drop a brand logo in the center of your QR code, you're deliberately covering part of it, so you need H (or at least Q) for the code to survive the obstruction. Use L with a logo and the code often won't scan at all. So the rule of thumb I use: digital and clean, go low; printed or logo'd, go high. When you set this in the QR code generator, it's a single dropdown, so it's worth matching to the job rather than leaving it on default.
How much data can a QR code hold?
Why cap it lower? Scannability. The more data you pack in, the denser the grid gets, with tinier modules that need a sharper camera and better focus to read. A URL stuffed to the brim prints as a fussy, hard-to-scan mess. In practice, short payloads win: a link, a bit of text, contact details, or Wi-Fi credentials all fit comfortably with room to spare.
This is why shortening a long URL before encoding it is a smart move — fewer characters means a cleaner, lower-density code that scans faster and from farther away. If your data is long, that's a signal to trim it or point the code at a short link rather than the full payload. A QR code is happiest carrying a small key that unlocks something bigger, not the whole thing itself. I learned this the hard way after printing a stack of flyers with a bloated URL crammed into the code — half the room couldn't scan them, and I've shortened every link since.
How do I make a QR code that reliably scans?
Contrast and orientation matter more than people expect. Keep it dark modules on a light background — the classic black-on-white — because many scanners struggle with inverted or low-contrast codes. I've watched a stylish light-on-dark code fail on older phones that a plain black-on-white version scanned instantly. Don't sacrifice function for a look here.
Give it a quiet zone. QR codes need a margin of empty space around them — roughly four modules wide — so the scanner can tell where the code starts and ends. Crop that margin off to save space and scan rates drop. Size matters too: the code has to be physically big enough for the scan distance, so a code on a poster needs to be far larger than one on a business card.
The last habit is boring but saves the most pain: test before you print. I generate the code, set the error correction to match the environment, and scan the final version with two different phones from the distance people will actually use — I'd rather catch a problem on screen than in a print run of a thousand flyers. Build the code with the QR code generator, pick the right level, and give it that quick real-world test before it goes out.
Frequently Asked Questions
Why does a QR code still work when part of it is damaged?
QR codes use Reed-Solomon error correction, which stores redundant recovery data alongside your payload. That lets a scanner reconstruct missing pieces, so a smudged, torn or logo-covered code still reads — up to the limit of its error correction level.
What do the QR error correction levels L, M, Q and H mean?
They set how much damage the code can survive: L recovers about 7%, M about 15%, Q about 25%, and H up to 30%. Higher levels are more resilient but hold less data. You choose the level in the [QR code generator](/tools/qr-code-generator).
What error correction level should I use for a QR code with a logo?
Use H, or at least Q. A logo covers part of the code, so you need the higher redundancy to keep it scannable. A low level like L with a logo often won't scan at all.
How much data can a QR code store?
Up to roughly 4,000 alphanumeric characters at the largest size and lowest error correction, but dense codes scan poorly. Short payloads like a link or Wi-Fi details are best — shorten long URLs before encoding them.
Do QR codes expire?
A static QR code never expires — it encodes the data directly, so it works as long as the destination it points to exists. What can 'break' is the link inside it, not the code. Generate static codes with the [QR code generator](/tools/qr-code-generator). A dynamic code points at a link you can change later without reprinting the code itself.
Try ToolsFuel
23+ free online tools for developers, designers, and everyone. No signup required.
Browse All Tools