---
title: "QR code error correction levels explained: L, M, Q and H, and why it matters for data storage"
description: "What QR code error correction levels L, M, Q and H really recover (7, 15, 25 and 30% of codewords, not of the printed area), how Reed-Solomon works, why a higher level makes a denser code, and which level to print. With decode tests on real codes: at H, a centred square of 16.6 to 20.5% of the area was the most any code survived."
canonical: "https://linkbreakers.com/help/article/understanding-qr-code-complexity-why-it-matters-for-data-storage"
last-updated: 2026-11-10
---

# QR code error correction levels explained: L, M, Q and H, and why it matters for data storage

> What QR code error correction levels L, M, Q and H really recover (7, 15, 25 and 30% of codewords, not of the printed area), how Reed-Solomon works, why a higher level makes a denser code, and which level to print. With decode tests on real codes: at H, a centred square of 16.6 to 20.5% of the area was the most any code survived.

Video: [QR code error correction levels explained: L, M, Q and H tested on real codes](https://www.youtube.com/watch?v=DrirNo1Bw84)

## Short answer

Every QR code carries extra bytes that let a scanner rebuild the parts it cannot read. The **error correction level** sets how many. The QR code standard, ISO/IEC 18004, defines four levels, and the share of the code each one can recover:

| Level | Recovers about | Usual name |
|---|---|---|
| L | 7% of codewords | Low |
| M | 15% of codewords | Medium ("Standard" in ISO's guidance) |
| Q | 25% of codewords | Quartile |
| H | 30% of codewords | High |

Two things most pages leave out:

- **The percentage counts codewords (bytes of data), not printed area.** In our decode tests on clean digital images, the largest centred square a code survived at H was **16.6 to 23.7% of its area**, not 30%. A hairline scratch covering **0.7%** of the area was enough to break the L and M versions of the same code.
- **A higher level makes the code denser.** The same 44-character link is 29 x 29 modules at L and 37 x 37 at H (picture above). At the same print width, every module is smaller.

Plain guidance: **M** for screens and clean indoor print, **Q** or **H** for packaging, outdoor use, stickers or a logo in the middle, and never at the expense of the quiet zone or the corner squares, which no level protects.

## How it works

A few words first, each used throughout this page:

- **Module:** one black or white square of the code. A code is measured in modules per side: 21 x 21 for the smallest (version 1), 4 more per side for each version up to version 40 at 177 x 177 ([DENSO WAVE, versions](https://www.qrcode.com/en/about/version.html)).
- **Codeword:** one byte, 8 modules. DENSO WAVE, the company that invented the QR code: "One codeword of QR Code is equal to 8 bits" ([DENSO WAVE, error correction](https://www.qrcode.com/en/about/error_correction.html)). The data is stored as data codewords, the repair information as error correction (EC) codewords.
- **Finder patterns:** the three big squares in the corners. A scanner looks for them first, to locate the code and work out its angle.
- **Quiet zone:** the blank margin around the code. ISO/IEC 18004 requires it to be 4 modules wide on all four sides (clause 6.3.8).
- **Reed-Solomon:** the error correcting code QR codes use. It is also used on music CDs (DENSO WAVE).

### 1. Extra bytes computed from your data

When the code is made, the encoder cuts your data (a URL, for example) into data codewords and computes EC codewords from them. ISO/IEC 18004: "QR Code employs Reed-Solomon error control coding to detect and correct errors. A series of error correction codewords is generated, which are added to the data codeword sequence in order to enable the symbol to withstand damage without loss of data" (clause 7.5.1). When a scanner reads a damaged code, it uses the EC codewords to work out what the damaged data codewords must have been.

### 2. Fixing one wrong byte costs two repair bytes

A scanner usually does not know **where** the damage is. A stain or a scratch turns black modules white or the other way round, and the damaged byte reads as a different, valid-looking value. ISO calls that an **error**, and "such an error causing a substitution error in the data requires two error correction codewords to correct it" (7.5.1). Only an **erasure**, a byte the scanner knows is missing, costs one.

DENSO WAVE gives the arithmetic for level Q: with 100 data codewords, correcting 50 of them takes 100 Reed-Solomon codewords, "In this case, the total codewords are 200, 50 of which can be corrected. Thus, the error correction rate for the total codewords is 25%. This corresponds to QR Code error correction Level Q."

### 3. The size is fixed, the level changes the split

Each version has a fixed number of codewords. The level only decides how many of them are data and how many are repair. Version 1 always has 26 codewords:

| Version 1 (21 x 21) | L | M | Q | H |
|---|---|---|---|---|
| Data codewords | 19 | 16 | 13 | 9 |
| EC codewords | 7 | 10 | 13 | 17 |

So at the same version, a higher level holds less data. To hold the same data, the code moves up to a bigger version, which is why the H code in the picture above has more modules.

### 4. Blocks and interleaving

In larger codes, the codewords are split into **blocks**, and Reed-Solomon is applied to each block separately (ISO 7.5.2). **Each block can only fix its own damage**: the code fails as soon as one block has more errors than half its EC codewords, even if every other block is clean.

To make that less likely, the blocks are **interleaved**: the first codeword of block 1, then the first of block 2, and so on (ISO 7.6), and the result is placed in two-module-wide columns zigzagging up and down from right to left (ISO 7.7.3). Neighbouring codewords on the print belong to different blocks, so one smudge is shared between several blocks instead of landing on one. In our test below, a centred square on a code with 4 blocks damaged 11, 10, 10 and 9 codewords, each block within its limit of 11. (ISO does not state why it interleaves; spreading local damage is our reading, and that measurement shows it happening.)

```mermaid
flowchart LR
  A["Your data, as bytes"] --> B["Split into blocks"]
  B --> C["Reed-Solomon adds EC codewords to each block"]
  C --> D["Interleave the blocks"]
  D --> E["Place in 2-module columns, apply a mask"]
  E --> F["Printed code"]
  F --> G["Scanner finds the 3 finder patterns"]
  G --> H["Reads level and mask from the format information"]
  H --> I["Corrects each block on its own"]
  I --> J["Your data"]
```

### 5. What error correction does not protect

Reed-Solomon only repairs codewords. Several parts of a code are not codewords:

- **Finder, timing and alignment patterns.** They sit outside the encoding region (ISO 6.3.7). The scanner needs them to find the code and lay a grid over it before any correction starts.
- **Format information.** 15 bits next to the finders, stored twice, that say which level and mask the code uses. It has its own small code that corrects up to 3 bit errors (ISO 7.9.1 and Annex C.3). This is how a scanner knows which level it is reading.
- **The quiet zone.** No level compensates for a margin that is missing or filled with graphics.

In our tests, this is where small damage was fatal: the random ink blots that broke a code at only 1 to 4% of its area landed next to the timing pattern, the format information or a finder's edge, at every level.

### 6. The percentages are approximate

ISO's table says "approx." and the real figure is often a little higher: in its own example, a version 6-H code has 172 codewords, 112 of them EC, which "can correct 56 misdecodes or substitution errors, i.e. 56/172 or 32,6% of the symbol capacity" (7.5.1). In the smallest codes, a few EC codewords are kept back to detect wrong reads instead of correcting them: version 2-L has 10 EC codewords and an error correction capacity of 4, not 5 (ISO 7.5.1).

## Capacity: how much fits at each level

Characters of a URL (byte mode) per version and level, computed with the segno library and identical to [Thonky's character capacity table](https://www.thonky.com/qr-code-tutorial/character-capacities):

| Version | Modules per side | L | M | Q | H |
|---|---|---|---|---|---|
| 1 | 21 | 17 | 14 | 11 | 7 |
| 2 | 25 | 32 | 26 | 20 | 14 |
| 3 | 29 | 53 | 42 | 32 | 24 |
| 4 | 33 | 78 | 62 | 46 | 34 |
| 5 | 37 | 106 | 84 | 60 | 44 |
| 6 | 41 | 134 | 106 | 74 | 58 |
| 7 | 45 | 154 | 122 | 86 | 64 |
| 8 | 49 | 192 | 152 | 108 | 84 |
| 9 | 53 | 230 | 180 | 130 | 98 |
| 10 | 57 | 271 | 213 | 151 | 119 |

The largest QR code, version 40, holds at most 2,953 bytes, at L ([DENSO WAVE, standards](https://www.qrcode.com/en/about/standards.html)).

### What that means for three real URLs

Here is the version each URL needs at each level, and the size of one module when the code (quiet zone not included) is printed 2 cm or 3 cm wide:

| URL | Level | Version | Modules per side | Module at 2 cm | Module at 3 cm |
|---|---|---|---|---|---|
| 24-character short link | L, M | 2 | 25 | 0.80 mm | 1.20 mm |
| | Q, H | 3 | 29 | 0.69 mm | 1.03 mm |
| 44-character short link | L | 3 | 29 | 0.69 mm | 1.03 mm |
| | M, Q | 4 | 33 | 0.61 mm | 0.91 mm |
| | H | 5 | 37 | 0.54 mm | 0.81 mm |
| 92-character URL with UTM tags | L | 5 | 37 | 0.54 mm | 0.81 mm |
| | M | 6 | 41 | 0.49 mm | 0.73 mm |
| | Q | 8 | 49 | 0.41 mm | 0.61 mm |
| | H | 9 | 53 | 0.38 mm | 0.57 mm |

**Modules per side at each error correction level**

| Error correction level | 24-character short link | 44-character short link | 92-character UTM URL |
|---|---|---|---|
| L | 25 | 29 | 37 |
| M | 25 | 33 | 41 |
| Q | 29 | 33 | 49 |
| H | 29 | 37 | 53 |

Versions chosen by segno 1.6.6 and python-qrcode 8.2 (they agree on every case), byte mode. Linkbreakers measurements, 10 November 2026.

Three things to read from it:

- **The 44-character link at H is exactly as dense as the 92-character URL at L** (37 modules). At the same print size, you can have the long URL with the least protection, or the short link with the most.
- **Sometimes a level is free.** The 44-character link is version 4 at both M and Q, so Q costs nothing in size. Check this for your own URL before settling on M.
- **A long URL at a high level gets small modules.** The UTM URL at H, printed 2 cm wide, has 0.38 mm modules.

ISO says the same in general terms: the four levels "offer increasing capabilities of detecting and correcting errors, at the cost of some increase in symbol size for a given message length" (Annex K.2). Shortening the URL, for example with a short redirect link as [dynamic QR codes](/help/article/dynamic-vs-static-qr-codes-key-differences) use, is what brings a high level back to a small code.

## We measured it: how much damage each level survived

The percentages are a theory about codewords. We wanted to know what they mean on an actual code, so we damaged real codes step by step and read them with three open-source decoders.

### Method

- **Codes:** the three URLs above (24, 44 and 92 characters), each at L, M, Q and H: 12 codes. All three are live links to real pages: two Linkbreakers short links to a cold brew guide (`https://linkbreak.ing/cb` and `https://linkbreak.ing/t4IKtfknp?lbsrc=qrcode`, the form a Linkbreakers QR code encodes) and a store list page with UTM tags. Made with segno 1.6.6 in byte mode and cross-checked with python-qrcode 8.2. Rendered at 10 pixels per module with a 4-module quiet zone, pure black on white.
- **Decoders:** zxing-cpp 3.1.1, zbar 0.23.95 and OpenCV. A pass means the exact URL came back.
- **Damage:** a white square in the centre (like a logo on a white knock-out), the same square in black, a white bite out of the bottom-right corner, a white band across the middle, black ink blots at 30 random spots away from the finders, and whole codewords flipped on purpose. Each grew in steps of 0.2 module until every decoder failed. "Largest that decodes" is the largest size with no failure below it, as a share of the code's area, quiet zone excluded.
- **Codeword count:** a script maps every module to its codeword and block, so for each damaged image we know how many codewords each block lost.

**These are clean digital images.** No print, no camera, no blur, no angle. A printed code photographed by a phone will do worse, so read every number below as an upper bound, and test your own final file with a phone.

### The theory holds exactly, in codewords

Flipping whole codewords inside one block, every decoder read the code up to exactly half that block's EC codewords and failed at one more, for all 12 codes. The one exception is the one ISO predicts: on the version 2-L code, zbar stopped at 4 errors, keeping ISO's detection reserve, while zxing-cpp and OpenCV corrected 5.

### But not in area

The largest centred white square each code survived, with the 44-character link read by zxing-cpp:

**44-character link: nominal recovery vs largest centred square that still decoded**

- **23.1%** of the area at H, nominal 30%
- **4.3%** of the area at L, nominal 7%

| Error correction level | Nominal (share of codewords) | Measured (share of area) |
|---|---|---|
| L | 7 % | 4.3 % |
| M | 15 % | 8.8 % |
| Q | 25 % | 12.8 % |
| H | 30 % | 23.1 % |

Nominal: ISO/IEC 18004:2015, Table 8. Measured: Linkbreakers decode tests, 10 November 2026, white centred square on a clean digital image, zxing-cpp 3.1.1. Real prints and phone cameras do worse.

All three URLs, largest centred white square that decoded, % of area (zxing-cpp / zbar / OpenCV):

| URL | L | M | Q | H |
|---|---|---|---|---|
| 24-character short link | 5.8 / 5.4 / 5.8 | 5.8 / 5.4 / 5.8 | 11.4 / 11.9 / 11.4 | 16.6 / 17.1 / 17.1 |
| 44-character short link | 4.3 / 4.3 / 4.0 | 8.8 / 8.8 / 8.8 | 12.8 / 12.8 / 12.8 | 23.1 / 23.1 / 23.7 |
| 92-character UTM URL | 4.7 / 4.4 / 4.9 | 11.3 / 11.3 / 11.7 | 20.2 / 19.8 / 16.7 | 23.7 / 23.7 / 24.1 |

Other kinds of damage, zxing-cpp, % of area:

| Code | Black centre square | Corner bite (bottom right) | White band across the middle | Ink blot, median of 30 (worst) |
|---|---|---|---|---|
| 44 characters, L | 4.3 | 8.4 | fails at 0.7 | 5.0 (1.3) |
| 44 characters, M | 8.8 | 14.1 | fails at 0.6 | 9.9 (2.3) |
| 44 characters, Q | 13.2 | 19.0 | 6.1 | 16.4 (2.3) |
| 44 characters, H | 23.1 | 24.7 | 16.2 | 17.3 (3.8) |
| 92 characters, L | 4.7 | 7.9 | fails at 0.5 | 5.8 (3.8) |
| 92 characters, M | 11.3 | 16.0 | 4.4 | 11.2 (1.1) |
| 92 characters, Q | 17.0 | 20.9 | 12.7 | 18.9 (1.2) |
| 92 characters, H | 20.5 | 21.2 | 22.3 | 21.4 (0.8) |

What the numbers say:

- **No code survived its nominal percentage as area.** At H, the best centred square was 16.6 to 23.7% of the area; at L, 4.0 to 5.8%.
- **In codewords, the 30% holds, and a little more.** The 23.1% square on the 44-character link at H damaged 44 of its 134 codewords (32.8%), exactly 11 in each of its four blocks, whose limit is 11: the most this code can repair, which is why ISO writes "approx." 30%. One step bigger put three blocks over 11, and it failed. A shape's edges clip codewords partly, and one wrong module spoils a whole codeword, so the codeword share runs ahead of the area share.
- **Each level step buys real tolerance.** 4.3, 8.8, 12.8 and 23.1% of the area for L, M, Q and H on the same link.
- **Where matters more than how much.** The worst ink blots broke codes at 0.8 to 3.8% of the area, at every level, because they hit the timing pattern, the format information or a finder's edge. H does not protect the frame.
- **Decoders differ.** zbar failed much earlier than zxing-cpp on black centre squares at Q and H on the long URL (7.3% and 6.0% against 17.0% and 20.5%). The scanner in a phone's camera is none of these three, and we did not test one.

## Why a thin scratch can be worse than a big blot

A white line 0.2 module thick across the middle of the 44-character link covers 0.7% of its area and changes only 14 modules. At L, those 14 modules belong to 9 different codewords of the code's single block, whose limit is 7: zxing-cpp and zbar could not read it. At M it changed 17 modules in 13 codewords, 10 of them in one block (limit 9), and failed too. Q and H read it.

The reason is the layout: codewords are placed in two-module-wide columns, so a line across the code enters a new codeword about every two columns, and each one, even with a single wrong module, is a full error to correct. A round blot of the same area stays inside far fewer codewords. Error correction is counted in damaged bytes, and a line across the code damages the most bytes per square millimetre. (OpenCV still read the L and M codes; probably because it samples module centres differently and missed the thin line, but we did not check why.)

## Which level to print

ISO/IEC 18004 says the choice depends on "the expected level of symbol quality", "the importance of a high first read rate", "the opportunity for re-scanning" and "the space constraints". It calls M "Standard", "a good compromise between small size and increased reliability", Q "High reliability", "suitable for more critical or poor print quality applications", and H "the maximum achievable reliability" (Annex K.2). DENSO WAVE: "Level Q or H may be selected for factory environment where QR Code get dirty, whereas Level L may be selected for clean environment with the large amount of data. Typically, Level M (15%) is most frequently selected."

Guidance built on those and on our numbers:

- **Screens, slides, PDFs, clean indoor print** (a menu under a sleeve, a flyer): **M**. If your URL is short, check whether Q costs a version; for the 44-character link it does not.
- **Packaging, labels that get handled, stickers, receipts, outdoor print:** **Q or H**. In our test, only Q and H survived the hairline scratch.
- **A logo in the middle:** **H**, or at least Q, and keep the logo well under the nominal figure. The largest centred square that decoded was 16.6 to 23.7% of the area at H and 11.4 to 20.2% at Q, on clean images. A logo also spends the budget that dirt would need later. See [scannability best practices](/help/article/qr-code-scanability-best-practices-contrast-readability-optimization) for contrast and logo placement.
- **A very long URL:** a high level can push it up several versions (37 to 53 modules for the 92-character URL, L to H). Print bigger or shorten the URL.
- **Never at the expense of the quiet zone or the corners.** No level repairs finders, timing, format information or a missing margin.

Size goes with it. A common rule of thumb, from vendors, not a standard, is a distance-to-size ratio of about 10 to 1: a code scanned from 1 m should be about 10 cm wide ([Bitly](https://bitly.com/blog/minimum-size-for-qr-code/), [FreeQR](https://support.freeqr.com/hc/en-us/articles/15101916370703-QR-code-size-guide)). Bitly also suggests at least 2 cm x 2 cm. Both assume a typical code: a denser code has smaller modules at the same width, so it needs a bigger print for the same distance. More on print sizes in [QR code size and print dimension benchmarks](/help/article/qr-code-size-and-print-dimension-benchmarks).

Library defaults vary, so check yours: python-qrcode defaults to M, segno and ZXing's Java writer to L, and the qr-code-styling library to Q.

## Myths

1. **"H is always better."** At the same data, H makes a bigger version: 29 to 37 modules for the 44-character link, 37 to 53 for the 92-character URL. At a fixed print size, smaller modules are harder to read from a distance or on rough print.
2. **"At H, a logo can cover 30% of the code."** 30% is of codewords, not area. Our best centred square at H was 16.6 to 23.7% of the area, on a perfect image.
3. **"Anywhere is fine as long as it is under the percentage."** Finders, timing, format information and the quiet zone are not protected. Ink blots of 1 to 4% failed there at every level.
4. **"A small scratch is harmless."** A line 0.2 module thick (0.7% of the area) beat L and M.
5. **"The percentage is exact."** ISO says approximately: 6-H really corrects 32.6%, and version 2-L corrects 4 errors where 5 might be expected.
6. **"The scanner knows where the damage is."** Usually not. Printed damage reads as wrong values, each costing two EC codewords.
7. **"A higher level lets you print smaller."** The opposite: it makes the code denser at the same width.
8. **"All scanners handle it the same."** Same standard, different decoders: in our tests they disagreed at the limits and on dark centre squares.

## Setting the level in Linkbreakers

In the Linkbreakers QR code designer, the level is in the **Quality** section, under **Error correction level**: a dropdown on a wide screen, four buttons on a narrow one. The labels are Low (L), Medium (M), High (Q) and Very high (H), so Linkbreakers' "High" is the standard's Q. A line under the control shows the nominal figure: 7, 15, 25 or 30%. New designs start at **Q**. The level is saved with the design and can also be set through the API (`error_correction_level`).

The level also caps the logo: when the dots behind the logo are hidden, the renderer clears room for it in proportion to the level, so **raising the level makes the same logo size setting draw a bigger logo**. Using that exact rule, every level decoded at the default logo size (0.5) for all three URLs in our tests, and with the slider at its maximum (1.0) only the shortest URL at L still decoded. After each change, the designer decodes its own image and shows "This QR Code is scannable." or a warning that it may not be. It checks the digital image, not a print, so a final test with a phone is still worth it.

## Limits and caveats

- **Our measurements are one rendering:** clean black on white, 10 pixels per module, no blur, no perspective. Prints and phone cameras will do worse.
- **We did not test phone camera apps.** zxing-cpp, zbar and OpenCV are open-source decoders; we found no documentation of how the iPhone Camera or Google Lens handle error correction.
- **The ISO text quoted is the 2015 edition** (ISO/IEC 18004:2015). ISO has replaced it with the 2024 edition, which we could not read in full.
- **Codeword counts near a shape's edge are approximate** (a partly covered module is judged at its centre pixel), so they can be off by one or two near the threshold.
- **The 10 to 1 size ratio and the 2 cm minimum are vendor rules of thumb**, not part of the standard.

## Frequently asked questions

### What are the QR code error correction levels?

Four levels defined by ISO/IEC 18004: L recovers about 7% of the code's codewords, M about 15%, Q about 25% and H about 30%. The level is chosen when the code is made and stored in the code itself.

### Does 30% error correction mean 30% of the code can be covered?

No. It is 30% of the codewords (bytes), not of the printed area. In our tests on clean images, the largest centred square a code survived at H was 16.6 to 23.7% of its area, and small blots next to the finder, timing or format areas broke codes at 1 to 4%.

### Which error correction level should I use?

M for screens and clean indoor print, Q or H for packaging, outdoor use, stickers or a logo in the middle. ISO calls M the "Standard" level, and DENSO WAVE says M is the one most frequently selected.

### Does higher error correction make a QR code bigger?

Yes, for the same data. A higher level leaves less room for data in each version, so the code moves up a version and gains 4 modules per side each time: a 44-character link goes from 29 x 29 modules at L to 37 x 37 at H.

### Can I change the error correction level of a printed QR code?

No. The level is part of the printed pattern. With a dynamic QR code, you can generate a new code at another level that points to the same short link.

### What is the best error correction level for a QR code with a logo?

H, or at least Q, with the logo kept well under the nominal figure, away from the corners, and the final file tested with a phone.

### Why does a scratch break a QR code that survives a bigger stain?

Error correction counts damaged codewords, not area. A thin line crosses many codewords, each costing the full repair budget, while a round stain of the same area stays inside a few.

## Sources

- ISO/IEC 18004:2015, Information technology, Automatic identification and data capture techniques, QR Code bar code symbology specification (clauses 5, 6.3, 7.5 to 7.9, Annex C and Annex K.2): https://nuintun.github.io/qrcode/spec/ISO-IEC-18004-2015.pdf
- ISO/IEC 18004:2024, the current edition: https://www.iso.org/standard/62021.html
- DENSO WAVE, error correction feature: https://www.qrcode.com/en/about/error_correction.html
- DENSO WAVE, information capacity and versions: https://www.qrcode.com/en/about/version.html
- DENSO WAVE, QR Code standardization: https://www.qrcode.com/en/about/standards.html
- Thonky, QR Code Tutorial (error correction table, character capacities): https://www.thonky.com/qr-code-tutorial/
- Bitly, minimum size for a QR code (11 October 2024): https://bitly.com/blog/minimum-size-for-qr-code/
- FreeQR, QR code size guide: https://support.freeqr.com/hc/en-us/articles/15101916370703-QR-code-size-guide
- python-qrcode: https://github.com/lincolnloop/python-qrcode
- segno: https://segno.readthedocs.io/
- ZXing QRCodeWriter: https://github.com/zxing/zxing/blob/master/core/src/main/java/com/google/zxing/qrcode/QRCodeWriter.java
- qr-code-styling: https://github.com/kozakdenys/qr-code-styling
- Linkbreakers decode tests, 10 November 2026: segno 1.6.6, python-qrcode 8.2, zxing-cpp 3.1.1, zbar 0.23.95 (pyzbar 0.1.9), OpenCV 5.0, jsQR 1.4.0; 12 codes, 6 kinds of damage, 3 decoders.

## Last reviewed

10 November 2026, against ISO/IEC 18004:2015, DENSO WAVE's QR code pages and our own decode tests. For how a QR code works as a whole, see [how do QR codes work](/help/article/how-do-qr-codes-work).
