Kit-Bin
Donate

← All guides

How Do QR Codes Actually Work?

A QR code looks like a random grid of black and white squares, but nothing in it is random. Every square has a job: locating the code, aligning it, storing data, or protecting that data against damage. Here's what each part is actually doing.

The three finder patterns

Look at three of the four corners and you'll see identical concentric-square targets, a solid square, inside a white ring, inside another solid square. These are finder patterns, and they exist so a scanner can locate the code in a photo before it even tries to read data. Their nested-ring structure produces a distinctive 1:1:3:1:1 ratio of dark and light pixels along any scan line through the center, a signature that's extremely unlikely to occur by accident elsewhere in an image. Three corners have one and the fourth doesn't, so the scanner can also work out the code's rotation and correct for skew, whether the photo was taken at an angle or the code itself was printed crooked.

The quiet zone

The plain blank border surrounding the code isn't just margin, it's a required part of the spec called the quiet zone, and a scanner uses it the same way the finder patterns are used: as a signal that the code starts here and nothing else is bleeding into it. Crop that border too tight, place the code hard against a busy background, or print it right up to the edge of a label, and a scanner can fail to recognize where the code begins even though every module inside is perfectly intact. The minimum quiet zone is four modules wide on every side, scaled to whatever size the rest of the code is printed at.

Modules: the actual data grid

Every individual black or white cell in the grid is called a module. Each module is one bit, but the data isn't just laid out in a simple line, it's arranged in a specific zigzag pattern across the grid, interleaved with error-correction data, and encoded using one of several modes (numeric, alphanumeric, byte, or kanji) depending on what characters the content actually needs. A short numeric string packs far more efficiently than the same number of characters in general byte mode, which is part of why a code storing just a phone number looks simpler than one storing a full URL.

Versions: what controls the size

QR codes come in 40 defined "versions," numbered 1 through 40. Version 1 is a compact 21×21 module grid; version 40 is a dense 177×177 grid. Higher versions have more modules and can store proportionally more data, but they also need more physical space to print at a resolution a scanner can still resolve. A generator picks the smallest version that fits the content, which is why encoding a full paragraph of text produces a visibly denser, busier-looking code than encoding a short URL.

Reed-Solomon error correction: why a damaged code still scans

This is the part that makes QR codes genuinely robust rather than just a data grid. QR codes use Reed-Solomon error correction, a mathematical scheme that adds redundant data alongside the actual content. Reed-Solomon works over blocks of data and can reconstruct missing or incorrect symbols as long as the number of errors stays under a known threshold, the same family of error correction used in CDs, DVDs, and satellite communication to survive physical damage or signal noise.

This is exactly why a QR code with a logo stamped in the middle, or a printed code that's scratched, smudged, or partially torn, can still scan successfully. The scanner doesn't need every module intact, it reconstructs the missing ones mathematically from the redundant data, as long as the damage stays within the code's error-correction budget.

QR codes let you choose that budget directly, as one of four error-correction levels:

  • L (Low) — recovers from roughly 7% damage, maximizes data capacity
  • M (Medium) — recovers from roughly 15% damage, the common default
  • Q (Quartile) — recovers from roughly 25% damage
  • H (High) — recovers from roughly 30% damage, minimizes data capacity

It's a direct trade-off, not a free upgrade. Higher error correction reserves more of the grid for redundant data, leaving less room for the actual content, which is why a code with a logo embedded in it, or one destined for a rough print environment, should use a higher level (Q or H) deliberately, while a clean digital code with no obstruction can use L or M and pack in more data instead.

Generating and reading codes

Generate a QR code with a chosen error-correction level, or scan an existing QR code to decode its contents, both entirely in your browser.

Written by the Kit-Bin teamPublished Spotted an error? Tell us