The short version
Put the logo in the centre, size it at no more than 25% of the code's width, and generate at error correction Q or H.
That is the whole recipe. The rest of this article explains why those numbers, because the advice you will find elsewhere is stated imprecisely often enough to cause real failures.
One thing to fix before you touch the logo: shorten the destination. A shorter URL produces a code with fewer, larger modules, and larger modules survive both a logo and a bad print. It does more for reliability than any logo adjustment you can make afterwards.
Why a logo works at all
A QR code carries Reed-Solomon error correction, which lets a scanner rebuild data from a damaged symbol. Level L recovers about 7% of data bytes, M 15%, Q 25%, and H 30%.
A centred logo is, from the scanner's point of view, damage. It sits over the data region and destroys whatever modules are underneath. The code still decodes because the redundant bytes elsewhere in the symbol are enough to reconstruct what the logo hid.
That framing gives you the real constraint. You are spending a fixed recovery budget, and the logo is not the only thing spending it. Print quality, ink spread, a scuffed surface, and bad lighting all draw on the same budget. A logo sized to consume most of it leaves nothing for the physical world, which is why codes that scan on a monitor fail on a table tent.
The 20% rule is ambiguous, and the two readings differ by five times
Almost every guide says to keep the logo under 20%. Almost none says 20% of what.
It matters enormously. A square logo covering 20% of the code's width covers 20% × 20% = 4% of its area. A logo covering 20% of the code's area covers 20%. Those are five times apart, and both readings are in circulation.
The geometry is exact, so here it is in full. Read the left column as the logo's width relative to the code's width, which is the measurement you can actually eyeball in a design tool.
| Logo width (as % of code width) | Share of modules covered | Practical verdict |
|---|---|---|
| 10% | 1.0% | Very safe at any level |
| 15% | 2.3% | Safe from M upward |
| 20% | 4.0% | The usual recommendation, comfortable at Q |
| 25% | 6.3% | Our practical ceiling, use Q or H |
| 30% | 9.0% | H only, and test on the final print |
| 40% | 16.0% | Unreliable, expect field failures |
| 50% | 25.0% | Do not |
Tips
- Geometric coverage of a centred square logo. This is exact arithmetic, not an estimate.
- If a tool asks for logo size as a percentage and does not say of what, assume width and verify by scanning.
- A circular logo of the same nominal width covers less area than a square one, which buys a little headroom.
What we measured on real codes
The percentages above are geometry. To check they hold on actual symbols, we encoded three realistic destinations at error correction H and counted the modules a 25%-width centred logo would cover.
| Destination | Characters | Grid at Q | Grid at H | Modules under a 25% logo (H) |
|---|---|---|---|---|
| Short link | 26 | 29x29 | 33x33 | 68 of 1,089 (6.2%) |
| Type page URL | 36 | 33x33 | 37x37 | 86 of 1,369 (6.3%) |
| UTM campaign URL | 75 | 45x45 | 49x49 | 150 of 2,401 (6.2%) |
Tips
- Coverage stays near 6.2% regardless of payload, because both the logo and the grid scale together. The percentage is stable; what changes is how large each module is on paper.
- The longer payload needs a 49x49 grid against 33x33 for the short link. At the same printed size that is a 48% smaller module, which is the real reason long URLs plus logos fail.
- Measured with the same ISO/IEC 18004 encoder behind our [generator](/). Any compliant library returns the same grids.
Where the logo must never go
Error correction protects the data region. It does not protect the structures a scanner needs to find and read the code in the first place, and covering those breaks it regardless of level.
The three large squares in the corners are position detection patterns. A scanner uses them to locate the symbol and work out its orientation. Cover one and there is nothing to recover from, because decoding never starts.
The two dotted lines running between those corner squares are timing patterns, which establish the module grid. The small square near the lower right on larger codes is an alignment pattern, correcting for distortion on curved or angled surfaces. The narrow bands beside the corner squares carry format information about the error correction level and mask.
All of which reduces to one rule: keep the logo centred. The middle of the symbol is data, and data is the only part error correction can rebuild.
The logo itself matters as much as its size
A correctly sized logo can still break a code if it is the wrong kind of image.
Give it a solid background rather than transparency. A transparent PNG lets code modules show through, and the scanner sees a region that is neither clean data nor clean occlusion, which is harder to handle than a solid block. A solid white or solid brand-colour plate behind the logo reads as unambiguous damage, and unambiguous damage is what error correction is good at.
Keep contrast high between the code and the logo plate. A dark logo on a dark code blurs the boundary. Our design guide for dark backgrounds and logos covers the contrast floor in more depth.
Use a simple mark rather than a full lockup. Wordmarks with fine type disappear at the size a QR logo occupies, and a logo nobody can read costs modules for nothing. An icon or monogram at 25% of width is legible; a horizontal logo with a tagline at the same width is not.
Platform marks follow the same rules as your own. A WiFi code with a venue logo and an Instagram code with the app glyph both sit in the centre at the same 25% ceiling. If you are choosing a tool rather than a size, our comparison of generators with logo support covers which ones export vector.
Supply vector where you can. If the code is going to print, a vector export keeps both the pattern and the logo crisp at any size.
Tips
- Solid plate behind the logo, never transparency over the modules.
- Icon or monogram, not a full horizontal lockup with a tagline.
- Match the logo plate to the code background so the occluded region has a clean edge.
How to add a logo, step by step
The order matters. Each step constrains the next, and doing them out of order is how people end up shrinking a logo that was never the problem.
Tips
- Shorten the destination first. Use a [dynamic code](/qr-codes/dynamic) if the URL is long or carries campaign tags, since a short redirect encodes far fewer characters.
- Choose error correction Q for most print work, H for anything curved, outdoors, or industrial.
- Upload the logo and size it to 25% of the code width or less.
- Check the corners. If the logo overlaps a position detection pattern, it is off-centre.
- Export as SVG or PDF for print, PNG for screen.
- Print at final size and scan from the distance people will actually use, on more than one phone. The [size guide](/guides/qr-code-size-guide) has the distance arithmetic.
Testing before you commit
"It scanned on my phone" is not evidence. Your phone has a good camera, you knew where the code was, and you held it at the right distance in good light. None of those conditions apply in the field.
Test on at least three devices, including an older Android, since camera quality is where the variance lives. Print at the size you will actually use rather than checking on screen, because a monitor is far more forgiving than paper. Scan from the real distance, and try it in poor light and at an angle.
For anything going to volume, test on the actual substrate too. A logo code that works on office paper can fail on glossy stock where reflection eats the contrast, and the packaging guide covers why finish matters more than most teams expect.
If it fails, work in this order: shorten the destination, raise the error correction level, increase the printed size, then shrink the logo. Shrinking the logo first is the common instinct and usually the least effective of the four.
Common mistakes
Most logo failures trace back to one of these, and the first is by far the most frequent.
Tips
- Encoding a long UTM-tagged URL directly, then blaming the logo when the dense code fails.
- Reading "20%" as area when the tool meant width, or the reverse, and ending up five times off.
- Placing the logo off-centre where it clips a corner position pattern.
- Using a transparent logo so code modules show through the mark.
- Raising error correction to H without also increasing the printed size, which makes modules smaller and undoes the gain. See [error correction levels](/blog/qr-code-error-correction-levels) for the measured size cost.
- Testing only on screen, at a size nobody will print.
- Printing the code and logo in two mid-tone brand colours with too little contrast between them.