tooldura

Developer Tools

How QR Codes Actually Store Your Data

T
tooldura editorial
8 min readUpdated August 26, 2026Open tool →

A QR code looks like noise until a camera reads it, but every square in that grid is doing one of a handful of specific jobs: some hold your data, some hold a copy of it recomputed for error correction, and a few fixed patterns exist only so the scanner can find the code and untilt it. ISO/IEC 18004, the standard behind every QR code, defines all of it precisely enough that two independent implementations produce byte-identical grids for the same input.

Modules, Versions and Why the Grid Size Jumps

Each black or white square is called a module, and the grid is always square. The standard defines 40 sizes, called versions: version 1 is 21×21 modules, and each version after it adds 4 modules per side, up to version 40 at 177×177. A generator picks the smallest version that fits your data at the error correction level you asked for, which is why a short URL and a long one at the same settings can come out as visibly different sizes.

Three of the four corners carry a large square-in-a-square finder pattern, which is what a camera locates first to detect a QR code's position and rotation before trying to read anything else. From version 2 onward, smaller alignment patterns are added across the grid so the reader can correct for the barrel or pincushion distortion a real camera lens introduces, and a timing pattern of alternating modules tells it exactly where each row and column of data cells sits.

Why a Torn or Dirty Code Still Scans

QR codes carry two kinds of data in the same grid: your actual content, and Reed–Solomon error-correcting codewords computed from it. Reed–Solomon is the same family of algorithm used on CDs and in satellite links, and it lets a reader reconstruct the original data even when part of the code is missing or misread, up to a limit set by how many correction codewords were included.

The standard defines four levels, and you choose the trade-off yourself: more correction capacity means fewer modules are left for your actual content, so the same text produces a larger code at a higher level.

The Four Error Correction Levels

Approximate share of codewords that can be wrong or missing and still let the code scan correctly.

LevelRecovery capacitySuits
L~7%A clean digital display, or when the content is already long
M~15%The general default, printed and handled normally
Q~25%Small prints, or a logo placed over part of the code
H~30%Outdoor signage, packaging, anything likely to get scuffed
📏

The white border is not optional

The blank margin around a QR code, called the quiet zone, needs to be at least 4 modules wide on every side per the standard. A scanner uses the contrast between that quiet zone and the finder patterns to work out where the code starts; crop it too close and codes that decode perfectly on screen fail once printed at real size.

Why a Logo in the Middle Does Not Break It

Nothing in the specification reserves space in the centre of a QR code for a logo. The centre holds data like everywhere else, and a logo sitting on it is destroying that data. It keeps working for the same reason a scratched code does: the Reed–Solomon codewords let a reader rebuild what it could not see, and a logo is simply damage applied on purpose.

That makes the budget the error correction level, which is why generators that offer logos push you to level H. The number that matters is area rather than width, and the difference is larger than it looks because area goes up with the square. A logo spanning a fifth of the code's width covers 4% of it; at a third of the width it covers 11%; at half the width it covers 25%, which is already past what level Q can recover and close to the limit for H.

Those figures are also optimistic, because they assume the damage is spread evenly across the grid. Reed–Solomon works on blocks of codewords, and a solid square in the middle wipes some blocks out entirely while leaving others untouched, so a code can fail below the headline percentage. Two things follow. Keep the logo well under the level's rated capacity rather than at it, and never cover a finder pattern, which carries no error correction at all: a reader that cannot find the three corners never gets as far as reconstructing anything.

🔍

The only test that settles it is a decode

Coverage percentages and contrast ratios are both predictions. Whether a particular code with a particular logo, at particular colours, actually reads is a question with an exact answer, and getting it costs one decode of the finished image. Any generator can do this and almost none do, which is how printed runs of unscannable codes happen. If a tool is going to offer logos, shapes and colours, it should also tell you when you have gone too far.

How Much a Single Code Can Hold

Capacity depends on both the version and the character set. The standard defines four encoding modes: numeric (digits only, three per ten bits), alphanumeric (adds uppercase letters and a handful of symbols, two characters per eleven bits), byte (any 8-bit data, including lowercase text and Unicode as UTF-8), and kanji (Shift JIS double-byte characters, two bytes packed into thirteen bits). A generator picks whichever mode fits your content most efficiently, which is why an all-uppercase, all-digit code can hold noticeably more than the same character count in mixed-case text.

At version 40, the largest defined, error correction level L holds up to 7,089 numeric digits, 4,296 alphanumeric characters, or 2,953 bytes. At level H that drops to 3,057 digits, 1,852 alphanumeric characters, or 1,273 bytes. That is close to half the content for the same physical code, since more of the grid is now spent on error correction.

What's Actually Inside a Wi-Fi or Contact Code

A QR code only ever stores a string. What makes one do something specific, like joining a network or saving a contact, is a payload format phones already recognize, not a special kind of QR code.

1

Wi-Fi: WIFI:T:WPA;S:name;P:password;;

Not part of ISO/IEC 18004 itself, but a de facto convention (used by ZXing and every major generator) that iOS and Android's camera apps both recognize and offer to join. Semicolons, commas and colons inside the network name or password are escaped with a backslash so they aren't read as field separators.

2

Contact: a vCard 3.0 record

BEGIN:VCARD through END:VCARD, the same plain-text format an address book exports to a .vcf file. A phone's camera recognizes it inline and offers to add the contact directly, without downloading anything.

3

Email, text and phone: standard URI schemes

mailto: for email (RFC 6068), sms: for a pre-filled text (RFC 5724), and tel: for a number to dial. These are the same links a mailto or tel anchor tag uses on a web page, just handed to the phone through the camera instead of a browser.

4

Everything else: plain text

A URL is not a special case. It's just text starting with http, and the camera app's own link detection is what turns it into a tappable prompt. Anything else you type comes back exactly as scanned.

Build one of your own

Link, Wi-Fi, contact, event or location. Add a logo, restyle it, and every version is decoded back before you download it.

Open the QR Code Generator →

Frequently Asked Questions

Related Tools

Keep Reading