Static versus dynamic QR codes
"Static" and "dynamic" sound like two kinds of QR code. They are not. Every QR code is the same
kind of symbol, produced to the same standard (ISO/IEC 18004); the two words describe where the
content lives. In a static code the content is the payload: the link, the
WIFI: string or the contact card is inside the image. In a dynamic
code the payload is the address of a redirect on a provider's domain, and the real destination lives
on that provider's server. Every strength and every weakness of each kind follows from that one difference.
This site produces static codes only. This guide, one of the
guides to the generators, sets out what that means and what it costs.
Two layers, and where the difference sits
A QR code has two independent layers, as the methodology page describes. The payload is the text encoded inside. The symbol is the matrix of dark and light modules that carries that text, produced here by a vendored copy of the reference encoder, kept byte-comparable with upstream. The static-versus-dynamic distinction lives entirely in the payload layer. A scanner cannot tell the two apart by looking at the symbol: it decodes the text and acts on what it finds. If the text is a web address, the phone opens it. If that address belongs to a redirect service, the phone opens the service, which then sends it on, or does not.
That is also why most "my code doesn't work" problems are payload problems rather than symbol problems, and why the payload is where the testing effort on this site goes: each builder is checked against independently constructed reference strings, and a round-trip suite renders, rasterizes and decodes every payload type with an independent decoder.
Worked example: a static link code
A link code for the fictional address https://example.com/menu carries exactly this
payload:
https://example.com/menu
Rendered by the same engine as the URL generator: version 2, 25×25 modules, error correction M. Nothing is added and nothing is rewritten. The URL is encoded exactly as entered after validation, as the ZXing Barcode Contents convention specifies (the barcode encodes exactly the text of the URL, protocol included), never wrapped in a shortener or a tracking redirect, so the phone that scans it goes straight to the address and nowhere else first.
What a dynamic code contains
A dynamic code is still a standard symbol over a text payload. The text is a URL on the provider's own domain, and the provider's server redirects the scanning phone to your destination. That indirection is the entire feature. Because the destination is looked up at scan time rather than fixed in the print, the provider can change it after printing; because every scan passes through the provider's server, the provider can count scans. The same mechanism has another side, which the about page describes: a redirect that can be changed can also be switched to something else, an upgrade page when a trial lapses, for instance, and every printed copy then points wherever the provider decides. Nothing in the symbol changed. The thing it pointed at did.
There are legitimate reasons to want the indirection: campaign analytics, or a destination that genuinely must change after printing. But it is a hosting service you choose deliberately, not a default to be defaulted into. This site does not provide one. The methodology page states the position plainly: every code is static, the data lives in the image with no redirect through our servers, and we consider that the right default and say so rather than selling the alternative.
The trade-offs, stated plainly
| Property | Static (every code on this site) | Dynamic |
|---|---|---|
| Where the content lives | In the image, as the payload text | On the provider's server; the image holds a redirect address |
| Expiry | Never expires; nothing is hosted that could lapse | Lasts as long as the redirect stays in service |
| Control | Cannot be held hostage; no third party between the scanner and the destination | The provider's server sits between every scan and the destination |
| Editing after printing | Not possible; a change needs a new code | The destination can be changed |
| Scan counts | Cannot be tracked | Counted at the redirect |
Neither column is free of cost: static trades editing and counting for independence, and dynamic trades independence for editing and counting. Pick a column knowingly, so that a printed code does not quietly belong to someone else.
"Cannot be edited after printing", demonstrated
The trade-off is easiest to see in a WiFi code, because the thing you might later want to change
is sitting in the payload in plain text. The invented network name ExampleGuest,
WPA2 (the engine writes WPA2 as T:WPA, the token the convention defines) and the
invented password sample-pass-123 produce:
WIFI:T:WPA;S:ExampleGuest;P:sample-pass-123;;
Version 4, 33×33 modules, error correction Q, built by the same engine as the WiFi generator.
The password is inside the image. A phone that scans the print reads it from the modules; no
server is consulted, which is why the code cannot expire and why nobody can switch it off. It is
also why the print cannot be updated. Rotate the password to sample-pass-456 and the
engine produces different text:
WIFI:T:WPA;S:ExampleGuest;P:sample-pass-456;;
Both payloads fit in version 4, so the two symbols are the same size, but their modules are arranged differently: it is a different code, and the printed one keeps carrying the old password for as long as it hangs on the wall. The same holds for a contact card: a changed number means a new card.
One more thing the payload shows. The engine validates format, not truth. It can check that the
WIFI: convention (the ZXing Barcode Contents format the engine follows, verified 2026-07-20)
is followed and that the special characters \ ; , : " are backslash-escaped as that source's
escaping rule requires, but it cannot know whether the password is correct. A mistyped password produces
a perfectly well-formed code that carries the wrong password, and no amount of error correction repairs
that, because nothing in the symbol is damaged. The
WiFi payload guide walks through the convention
field by field.
Fixed address, movable destination
A static link code fixes the address, not what the address serves. Point the code at a URL you control and the page behind it is yours to change for as long as you run the domain, with no third party (including us) able to hold the print hostage. That is the dependency-free way to get most of what an editable code offers.
The payload is also just text, so two codes can name the same page differently. Add a query string and the engine encodes it as entered:
https://example.com/menu?src=poster
The extra characters push the symbol from version 2 (25×25 modules) to version 3 (29×29 modules), a reminder that longer payloads mean denser codes. What a server does with that parameter, count it or ignore it, happens on the server and is outside what the generator does or verifies. The code's job ends at delivering the text intact.
Reading the symbol facts
Every worked example on this site, and the generator's own readout, reports the same facts about a symbol. The worked examples are computed by the engine at build time, never typed in; the generator computes the same readout in your browser from the same code, so the two cannot disagree.
- Version. Chosen by the encoder from the length of the payload and the error-correction level. A higher version has more modules along each side, and at a fixed print size each module is therefore smaller. The link example above is version 2; the WiFi example is version 4. How a QR code encodes data covers the choice in detail.
- Modules. The side length of the symbol, not counting the quiet zone. The quiet zone, 4 modules of background on every side, is rendered into every download and cannot be disabled; cropping it is the most common self-inflicted scan failure. Quiet zone and print size has the numbers.
- Error correction. One of four levels, L, M, Q and H, that the engine exposes. The generators request M unless you choose otherwise; the reference encoder raises the level when doing so does not increase the version, so the readout reports the level actually encoded, which is why a short payload can show a higher letter than was asked for. A logo overlay forces H and is capped at 16% of the symbol area. Error correction and logos explains the cap.
- Print size. The PNG presets are reported as physical sizes at 300 DPI:
512 pxis 1.71 in × 1.71 in (43.3 mm × 43.3 mm) at 300 DPI;1024 pxis 3.41 in × 3.41 in (86.7 mm × 86.7 mm) at 300 DPI;2048 pxis 6.83 in × 6.83 in (173.4 mm × 173.4 mm) at 300 DPI. Error correction helps a damaged code scan, but print size and contrast still matter: the style panel warns when a colour pair drops below 4.5:1 and warns separately for light-on-dark (inverted) codes, which many scanners reject. See Contrast and inverted codes.
Common misreadings
- "My static code expired." It cannot. There is nothing to expire, because nothing is hosted. If a printed static code stopped doing what it did on the day you printed it, the symbol still decodes to exactly the same text; look at what that text names: a page that was removed, a password that was rotated, a number that was reassigned. If a code printed elsewhere stopped working, the about page describes the usual reason, and it is a redirect, not the symbol.
- Trimming the white border. The quiet zone is part of the code, not padding around it. Printing the symbol flush against artwork, or cropping it down to the dark modules, is the failure the renderer tries hardest to prevent by never letting you disable the border.
- Light modules on a dark background. The renderer computes the contrast of your colour pair with the WCAG relative-luminance formula and warns for inverted codes separately from low contrast, because many scanners reject them.
- "It scans, so the content is right." Scanning proves the symbol; it proves nothing about the payload's truth. The engine cannot know whether a WiFi password is correct, a phone number reachable or a URL safe. A wrong password encodes fine.
- "It is generated, so it is done." Treat a freshly generated code as untested until a real device has scanned it, from the print where you can.
Static versus dynamic: questions
Can a static QR code expire?
No. The content is encoded in the image itself, with no redirect through our servers, so there is nothing hosted that could lapse or be switched off. If a printed static code stops doing what it did, the symbol still decodes to the same text; what changed is the thing that text names, such as a page that was taken down or a password that was rotated.
Can I edit a static QR code after printing?
Not the code: the text is fixed in the modules, so a changed link, password or phone number means a new code and a new print. For links there is an ordinary way round this: point the code at a URL you control, and what that address serves is yours to change for as long as you run the domain.
Can scans of a static code be counted?
Not by the code. Nothing sits between the scanning phone and the destination, so there is no point at which a scan could be logged, by us or by anyone else. The payload is plain text, so a link can carry a query string that a server you run may notice, but that happens on the server and is outside what the generator does or verifies.
Does GenerateQRCodes.net make dynamic codes?
No. Every code is static, and the methodology page says so plainly rather than selling the alternative. The optional free account changes nothing about the codes themselves: saving a code stores a copy so you can download it again, and a printed code never depends on the account existing.
Is a dynamic code a different kind of symbol?
No. Both are ordinary QR symbols produced to the same standard. The difference is in the payload text: a static code carries the content, and a dynamic code carries the address of a redirect on a provider’s domain. A scanner cannot tell them apart by looking; it decodes the text and acts on it.
Does a static code check that its content is correct?
No. The engine validates format, not truth. It can confirm that a payload follows its convention and that special characters are escaped, but it cannot know whether a WiFi password is correct, a phone number reachable or a URL safe. Treat a freshly generated code as untested until a real device has scanned it.
Static or dynamic is a question about the payload, and the payload is built where you are: every generator on this site runs in your browser, and nothing you type is transmitted to us unless you choose to save a code to an account. How the encoding is built and verified is on the methodology page.