# How to Make a QR Code That Actually Scans

> Most QR codes that fail to scan fail for three reasons: size, contrast, or too much data in the pattern. Measured module counts at each error correction level, and the print rules that decide whether a phone reads it.

Source: https://toolpantry.app/blog/how-to-make-a-qr-code

A QR code is not a picture of a link — it is the link, written in squares. Which means the usual failure is not a broken generator; it is a code that is too small, too low-contrast, or carrying more data than a phone camera can pick out.

## Quick answer

**Short answer:** open the [QR code generator](https://toolpantry.app/qr-code-generator), paste a URL, pick **H** error correction if you plan to print it or put a logo over the middle, and download the PNG at 512 × 512 or larger. Then scan it with a real phone, at arm's length, before you print anything.

## What a QR code actually is

The content is stored **in the pattern itself**. There is no lookup service, no subscription, and no expiry date attached to the code — which is the main reason static codes are still the right answer for menus, posters, packaging and business cards.

Two things follow from that, and both matter more than the generator you use:

- **The code never expires; the destination can.** A QR pointing at menu.example.com/breakfast keeps working after that path is renamed, and then it points at a 404. Put the code on a short, stable URL you control.
- **Nothing is hosted for you.** There is no dashboard telling you how many scans happened, and no monthly bill for keeping the code alive.

## Pick the error correction level

Every QR code carries a set of extra codewords whose only job is to repair damage. How much damage it can repair is the level: L recovers about 7% of the symbol, M 15%, Q 25%, H 30%. More recovery means a denser code, because the repair data has to fit in the same square.

Same 47-character URL, measured on October 20, 2026:

| Level | Recovery | Modules | Square | SVG size |
|---|---|---|---|---|
| L | ~7% | 29 × 29 | small | 6 KB |
| M | ~15% | 33 × 33 | medium | 8 KB |
| Q | ~25% | 37 × 37 | larger | 10 KB |
| H | ~30% | 41 × 41 | largest | 12 KB |

H is 41 modules across where L is 29 — 41% more pixels in each direction, and roughly twice the area. On a 2 cm code that difference is the difference between a comfortable read and a squint.

- **L or M** for a short link shown on a screen, where the code will be clean and large.
- **Q or H** for print, for a code with a logo in the middle, or for anything that will get scratched, folded or stuck on a textured surface.

## How much you can fit

The more text you encode, the bigger the square has to be. Measured at level M with plain text:

| Characters | Modules | Square |
|---|---|---|
| 20 | 25 × 25 | small |
| 50 | 33 × 33 | medium |
| 100 | 41 × 41 | medium |
| 200 | 57 × 57 | large |
| 400 | 77 × 77 | large |
| 800 | 109 × 109 | very large |
| 1,200 | 133 × 133 | very large |

The standard allows more: at version 40, byte mode holds 2,953 characters at level L, 2,331 at M, 1,663 at Q and 1,273 at H ([ISO/IEC 18004](https://www.iso.org/standard/83389.html), the QR Code symbology standard). A 177 × 177 module code is not a thing you put on a business card.

Our generator stops at **1,500 characters** and returns an error rather than producing a code so dense that no phone will read it. For anything that long, a short link is the better answer — the code stays small and the long text stays in the page it points to.

## The rules that decide whether it scans

- **Size.** For print, keep the code at least 2 cm wide. Our generator offers 256, 512 and 1024 px; 512 covers most print and screen uses, 1024 is for posters.
- **Contrast.** Dark modules on a light background. Contrast matters more than colour — a brand colour on white is fine, a pastel logo over the code is not.
- **The quiet zone.** The spec asks for a margin of four modules of blank space around the code. Without it, scanners struggle to find the edges. Do not crop tight to the pattern.
- **Never stretch it.** The modules are squares. Scaling width and height differently turns them into rectangles and breaks the read. If you need a different size, regenerate rather than rescale — [resize](https://toolpantry.app/image-compressor?mode=resize) on the PNG will not help here.
- **Test the actual file.** Scan the downloaded PNG with a real phone at arm's length, on the surface it will sit on, before you print or publish. A code that works on a monitor at 40 cm can fail on a menu at 30 cm under a warm light.

One more: if you overlay a logo in the middle, keep it to roughly a quarter of the code's area and use level H to pay for the covered modules. Our generator does not draw logos — generate the code, add the logo in any image editor, and re-test.

## Where to use which

- **Restaurant menus and event posters** — a URL, level M, 512 px or larger, printed on matte paper.
- **Packaging inserts** — a short link to the instructions or warranty page, level H, and check the code survives the folding.
- **Business cards** — 2 cm is the floor here, and 3 cm is safer. Test on the actual card stock.
- **Email addresses and phone numbers** — the generator writes mailto: and tel: payloads, which open the right app on a phone instead of showing a web page.

If you are putting a code on retail packaging rather than marketing material, a [barcode](https://toolpantry.app/barcode-generator) is the format your scanner expects — the two are not interchangeable.

## What our generator does not do

- **No dynamic codes.** The pattern is fixed; there is no short-link service behind it and no scan analytics.
- **No logo overlay, no styling, no colours.** You get the pattern as generated. Add anything afterwards and re-test it.
- **PNG for the page, SVG from the API.** The [API](https://toolpantry.app/api) returns image/svg+xml for print work and accepts ec, size and margin parameters.
- **1,500 characters maximum**, and no account, no saved codes, no history.

## Notes

By the Tool Pantry team, October 2026. Module counts below were measured on October 20, 2026 against our own API. The capacity figures come from ISO/IEC 18004, the QR Code symbology standard (2015 edition, section 6.1).

## FAQ

**Do QR codes expire?**

A static QR code does not expire — the destination is stored in the pattern itself, with no subscription service behind it. What can expire is the destination: the page the code points at can be moved, renamed or taken down, and the code will keep scanning into a dead link.

**How big does a QR code need to be to scan?**

For print, keep the code at least 2 cm wide and test it with a real phone at arm's length before the run. On screen, 256 px is fine for a chat message and 512 px is the safe default for anything printed or shown on a display.

**Can I put a logo in the middle of a QR code?**

Yes, and the way to make it work is error correction: level H recovers 30 percent of a damaged symbol, which is what covers the area your logo hides. Keep the logo under about a quarter of the code's area, and re-test after you add it.
