How Do QR Codes Work? (Explained Without the Math)
5 min read · updated 2026-09-07
A QR code looks like visual noise, but it's one of the most elegant pieces of everyday engineering: a square that a 1994 barcode scanner, a modern phone camera, and a low-quality photocopy can all read. Here's what's actually going on inside the pattern — no math degree required.
The one-sentence version
A QR code is a picture of text — your URL, Wi-Fi password or contact card, translated into a grid of black and white squares that a camera can read even when part of it is damaged.
Modules: the pixels of a QR code
Every QR code is a square grid of small cells called modules — the little black and white squares. A code can be anywhere from 21 × 21 modules (version 1) to 177 × 177 (version 40). The more data you encode, the bigger the grid gets: a short URL fits in a 25 × 25 grid; a full contact card might need 45 × 45 or more.
That grid size is why shorter content = easier scanning: fewer modules means each one prints larger, and large modules are readable from farther away (see the QR code size guide).
The three big squares: finder patterns
The three large nested squares in the corners — top-left, top-right, bottom-left — are the code's hello. They exist so a scanner can:
- Detect that there's a QR code in view at all
- Locate its corners and boundaries
- Correct perspective — read the code at an angle, from a photo taken off-center
The fourth corner (bottom-right) carries a smaller alignment pattern that helps with distortion on curved or angled surfaces. That's why you can scan a code from a crumpled flyer or a wine bottle: the finder patterns tell the phone how to un-distort the grid.
Timing patterns and format info
The alternating black-and-white lines running between the finder patterns (the "timing patterns") let the scanner count module rows and columns precisely, even when the image is slightly blurry or the photo is low-resolution. A small patch near the top-left finder encodes the format: which error-correction level and mask pattern the code uses, so the scanner knows how to interpret everything else.
The data itself
Everything else — the seeming noise filling the middle — is your content, plus the machinery to read it:
- Mode indicator — what kind of data follows: numbers, alphanumeric text, raw bytes (used for URLs and international text), or Kanji
- Length — how many characters are coming
- Your data — the actual URL, Wi-Fi credentials, vCard, or text, in segments
- Error-correction codewords — the backup data described below
The bits are arranged in a zigzag path snaking up and down the grid, and a mask pattern (one of eight) is XOR-ed over them — that's what makes two codes with identical content sometimes look different, and it exists to break up large blank or filled regions that would confuse the scanner.
Error correction: why QR codes survive damage
Here's the genuinely clever part. Up to 30% of a QR code can be obscured, torn, coffee-stained, or covered with a logo, and it still scans perfectly.
When a code is generated, a Reed–Solomon code appends redundant data: think of it as the code being able to reconstruct itself from the remaining 70%. You choose how much redundancy when generating:
| Level | Damage it survives | Best for |
|---|---|---|
| L | ~7% | Clean digital use, maximum data capacity |
| M | ~15% | The everyday default |
| Q | ~25% | Codes on things that get roughed up |
| H | ~30% | Codes with a center logo, outdoor use |
The trade-off is capacity: higher redundancy means fewer characters fit in the same grid. That's also why adding a logo to a QR code should bump error correction to H — you're deliberately covering part of the pattern, and the redundancy absorbs it. (The generator does this automatically and warns you when a logo grows too large.)
The quiet zone
The blank margin around a QR code isn't wasted space — it's part of the specification. Scanners need a clean border (nominally four modules wide) to recognize where the code starts and the background ends. Trim it away and many scanners simply won't detect the code, no matter how perfect the pattern inside is.
How a phone reads one in a tenth of a second
- The camera app looks for the distinctive 1:1:3:1:1 ratio of black-white runs in the finder patterns — a shape that almost never occurs in nature
- From the three finder positions it computes the grid's position and perspective
- It samples the module grid, applies the mask, reads the format info
- Reed–Solomon decoding repairs any misread modules
- The decoded text — a URL,
WIFI:string,BEGIN:VCARD— is handed to the operating system, which decides what to do: open the browser, offer to join the network, show the contact card
All of that, from pocket to payload, in about 100 milliseconds.
How much can a QR code hold?
The theoretical maximum is 7,089 digits or 4,296 alphanumeric characters (version 40, error correction L). In practice you want far less: past a few hundred characters the modules become so small that scanning distance shrinks to a few centimeters. A good working budget is under 300 characters — which is why long URLs make dense codes and why vCards stay lean by leaving out photos.
Where the quiet cleverness ends
QR codes are just a transport format — they carry text and trust the scanner to interpret it. That's also their security soft spot: a code can carry any text, including a link to a phishing page ("quishing"). The code itself is neutral; the destination matters. Our phones now show the URL before opening it — read it, the same way you'd read a link in a suspicious email.
See it working
The QR generator shows the live effect of everything above: watch the grid grow as you type more text, shrink when you shorten it, and change texture when you raise the error-correction level. The encoded content panel even shows the exact text being carried by the pattern.