How QR codes work and what data they can actually hold

Those black-and-white squares are a clever little file system. Here's what's inside a QR code, why a scuffed one still scans, and how much data really fits.

By Muhammad Tahir7 min readqrexplainer

A QR code looks like random static, but every square is placed deliberately. It's a two-dimensional barcode designed to be read fast, from any angle, even when partly damaged. Once you see the structure, the rest — why it scans upside down, why some hold more data, why a torn one still works — falls into place.

The anatomy: finder patterns, modules, and the grid

A QR code is a square grid of black and white cells. Each cell is called a module, and each module is one bit: black is one value, white the other. The whole thing is just a grid of bits arranged in a precise layout.

The most recognizable features are the three big nested squares in the corners — the finder patterns. They exist so a scanner can instantly locate the code and figure out its orientation. Each finder pattern is a 7-by-7 ring with a consistent ratio of dark-to-light bands (1:1:3:1:1) when you scan a line straight through it. That ratio is rare in ordinary images, so the scanner can spot it reliably and lock on.

Three corners, not four, is the trick that makes orientation work. Because the patterns sit in only three of the four corners, the scanner can tell which way is up no matter how the code is rotated. That's why a QR code reads perfectly whether it's upside down, sideways, or at an angle.

The rest of the layout supports decoding:

  • Timing patterns — alternating black-and-white lines running between the finder patterns, acting as a ruler so the scanner can count modules accurately even on a warped surface.
  • Alignment patterns — smaller nested squares sprinkled across larger codes to correct for perspective distortion when the code is photographed at an angle or printed on a curve.
  • Format and version information — reserved strips near the finders that tell the scanner the error-correction level and which masking pattern was applied before it touches the actual data.
  • The data region — everything else, where your URL or text actually lives, encoded as a winding path of modules.

Versions 1 to 40: the size ladder

QR codes come in 40 versions, and the version sets the grid size. Version 1 is 21 by 21 modules. Each step up adds 4 modules per side, so version 2 is 25 by 25, version 3 is 29 by 29, and so on up to version 40 at a dense 177 by 177 modules.

More modules means more capacity. A version 1 code holds only a tiny amount of data; a version 40 can hold thousands of characters. Generators pick the smallest version that fits your data at your chosen error-correction level, because smaller codes have larger, easier-to-scan modules. This is why a short link produces a clean, blocky code while a long vCard produces a dense, intricate one — the generator climbed the version ladder to make room.

Error correction: why a damaged code still scans

This is the genuinely clever part. QR codes use Reed–Solomon error correction, the same family of math used on CDs and in deep-space transmission. Extra redundant data is woven in so the code can be fully reconstructed even when part of it is unreadable — scratched, smudged, covered by a logo, or torn.

There are four error-correction levels, and you choose one when generating:

  • Level L (Low) — recovers from about 7% damage.
  • Level M (Medium) — about 15%.
  • Level Q (Quartile) — about 25%.
  • Level H (High) — about 30%.

So a Level H code can lose nearly a third of its area and still decode perfectly. This is exactly how those QR codes with a company logo dropped in the center still work — the logo sits on top of redundant data the error correction simply reconstructs.

The trade-off is space. Higher correction means more redundancy, which means less room for actual data, which pushes you to a larger version for the same payload. A practical rule:

  • Use L or M for clean digital displays and well-printed material where damage is unlikely — you get a smaller, less dense code.
  • Use Q or H for codes printed on packaging, exposed to wear, placed behind glass, or stamped with a logo in the middle.

What actually fits: capacity by data type

Capacity depends on the type of characters you encode, because QR codes use different, more efficient encodings for restricted character sets. There are three main modes:

  • Numeric (digits 0–9 only) — the most compact. At the largest version with low error correction, a QR code can hold over 7,000 digits.
  • Alphanumeric (digits, uppercase letters, and a few symbols like space, $, %, *, +, -, ., /, :) — less compact than numeric, topping out around 4,200 characters at maximum size.
  • Byte mode (any UTF-8 text, which covers lowercase letters, most URLs, and arbitrary characters) — the least compact, maxing out around 2,900 characters.

Notice the catch: most real-world content — URLs with lowercase letters, names, addresses — falls into byte mode, the least efficient one. So the realistic ceiling for everyday QR codes is far below the headline numeric figure. The good news is that almost nothing you'd actually encode comes close to even the byte-mode limit.

What you'd really put in one

QR codes are just text inside, but scanners recognize certain formats and act on them. The common ones:

  • A URL — by far the most common use. A typical link is well under 100 characters, so it produces a small, robust code with room for high error correction. This is the case you should optimize for: short URL, high correction, big scannable modules.
  • Wi-Fi credentials — a specially formatted string holding the network name, security type, and password. Scanning it offers to join the network with no typing. Even with a long password this fits comfortably.
  • A vCard (contact card) — name, phone, email, company, address. This is the heaviest common payload because it packs many fields, and it's where codes get dense. If your vCard pushes the code into a high version, consider trimming optional fields or pointing the QR at a hosted contact page instead.
  • Plain text, phone numbers, email addresses, calendar events, geo-coordinates — all small and all well within capacity.

The pattern: the more data you cram in, the denser and harder-to-scan the code becomes, and the larger you must print it. Less is more. When you can, encode a short URL that points to the heavy content rather than embedding the content itself.

Quiet zone and print size: where scans fail in the real world

A perfectly valid QR code can still fail to scan, and it's almost always one of two physical mistakes.

The quiet zone. A QR code needs a margin of empty white space around it — the quiet zone — recommended at 4 modules wide on all sides. The scanner uses this blank border to separate the code from surrounding clutter. Crop the margin too tight, or butt the code against text or a busy background, and scanners struggle or fail. Always leave breathing room.

Print size and contrast. The code must be physically large enough that its smallest modules survive at scanning distance. A loose rule is that the code's width should be at least about a tenth of the expected scanning distance: a code read from across a room needs to be much bigger than one on a business card read at arm's length. As a floor, avoid printing everyday codes smaller than roughly 2 by 2 centimeters, and go larger for denser ones. Keep strong contrast — dark code on a light background — and never invert it (light code on dark) unless you've confirmed it scans, since many readers expect dark-on-light.

A few more reliability tips:

  • Prefer a shorter payload, which yields a lower version with larger modules that survive blur, low light, and small print.
  • Raise the error-correction level if the code will be printed, handled, or branded with a logo.
  • Test the final code on more than one phone and from a realistic distance before you print thousands of them.

Try it

To create one, use the QR Code Generator — paste a URL or Wi-Fi details, pick an error-correction level (M for screens, Q or H for print), and keep the payload short for a clean, robust result. To read what's encoded in an existing code, or to verify your own before printing, the QR Code Decoder pulls the raw text back out so you can confirm it points exactly where you intended.

The squares aren't random. They're a finder grid, a ruler, a redundancy layer, and your data — assembled so a phone can read it in a fraction of a second, even when life has scuffed it up a little.