Skip to content
Files5 min read

Why free QR codes expire — and how to make ones that don't

Printed a QR code that stopped working? The code was fine. The redirect behind it wasn't.

By Shekhar P ·

A restaurant prints a QR code on five hundred menus. Eight months later it stops working, and the code now leads to a page asking someone to upgrade to a paid plan. The menus are useless.

This happens regularly, and the surprising part is that it is not a bug. It is the business model working as designed, and it turns on a distinction most people never encounter: static versus dynamic QR codes.

A QR code cannot expire

Start with what a QR code actually is. It is a two-dimensional barcode that encodes a string of characters. That is the entire thing. There is no server involved, no account, no timestamp, no expiry field.

If a QR code encodes https://example.com/menu, then scanning it produces exactly that string, forever. Print it on a wall and it will still work in fifty years, assuming the ink survives and the destination still exists.

So when someone says a QR code expired, the code did not expire. Something behind it did.

Static versus dynamic

A static code encodes your destination directly. The scanner reads your URL and goes there. Nothing sits in between.

A dynamic code encodes a link to the generator's domain — something like https://qrsvc.io/a8Xk2 — which redirects to your actual destination. The code is a pointer to a pointer.

Dynamic codes have a genuine advantage, and it is not a trick: you can change where the code points after printing it. Print a code on packaging, and later redirect it from a launch page to a support page without reprinting anything. For some uses that is genuinely valuable.

The cost is that your code now depends permanently on a third party's infrastructure. If they shut down, get acquired, change their pricing, or simply lose the database row, every code you printed breaks at once. And you cannot fix it, because the code encodes their domain, not yours.

Why "free" generators default to dynamic

Because the redirect is where the value is, for them.

It produces analytics. Every scan passes through their server, so they know how many people scanned, roughly where, on what device, at what time. That data is the product for several of these services.

It creates leverage. Once your codes are printed and in the world, you cannot switch providers. That is an unusually strong position from which to introduce a subscription, and several services have done exactly that — offering dynamic codes free, then charging once customers had committed physical materials.

It is a lead funnel. A code that stops working sends its scanner to a page explaining that the owner needs to upgrade, which is an advertisement delivered by your own printed materials.

None of this is hidden, exactly. It is usually in the terms. It is just not what people expect from a button labelled "generate free QR code".

How to tell which you have

Two checks, both quick.

Scan it and look at the URL. If the address bar shows your destination, it is static. If it shows a domain you do not recognise before redirecting, it is dynamic.

Decode it without scanning. Any QR reader will show the raw encoded string. If that string is your URL, you are fine. If it is a short link on someone else's domain, you are dependent on them.

The second is worth doing before printing anything in quantity.

Getting the best of both

If you want the ability to change the destination and independence from any service, the answer is to control the redirect yourself.

Point the static QR code at a URL on your own domainyoursite.com/menu, for instance — and set up a redirect from there to wherever the content actually lives. The QR code is static and permanent. The redirect is yours to change whenever you like.

This gives you everything a dynamic code offers, with none of the dependency. It requires a domain and the ability to configure a redirect, which is a small amount of setup for something you are about to print five hundred times.

If you do not have a domain, a static code pointing directly at the final URL is still the better default. Permanence is worth more than changeability for most uses.

Making codes that actually scan

Separate from the expiry question, plenty of printed codes fail simply because of how they were produced. A few things matter more than people expect.

Size relative to scanning distance. A reasonable rule of thumb is that a code should be about a tenth of the distance it will be scanned from. Scanned from two metres, it wants to be roughly 20cm across. Codes on posters are routinely printed far too small.

The quiet zone. The blank margin around a code is part of the specification, not decoration — scanners use it to locate the code's boundaries. Cropping it tight, or placing the code against a busy background, is one of the most common reasons a code fails to read.

Contrast and direction. Scanners expect dark modules on a light background. Inverting that — light on dark — fails on a significant number of readers. Low-contrast colour schemes fail on most.

Data density. QR codes grow in fixed steps as content lengthens, and denser codes need a better camera or a closer scan. Long URLs full of tracking parameters produce noticeably harder codes to read. Shortening the URL produces a sparser, more reliable code.

Print in vector. Send an SVG to your printer, not a PNG. A raster image scaled up in a layout program produces soft edges that reduce scan reliability, particularly at small sizes.

Error correction, and why logos work

QR codes store redundant data so they still read when partly damaged. There are four levels, recovering from roughly 7%, 15%, 25% and 30% of the code being obscured.

This redundancy is what makes it possible to place a logo over the centre of a code. The centre is not unused space — it carries data like everywhere else — but at high error correction, enough redundancy exists to reconstruct what the logo covers.

The practical rules: choose High correction before adding a logo, keep the logo under about 25% of the code's area, and never cover the three large squares in the corners, which are the position markers scanners use to orient themselves. Test with more than one phone before printing.

Higher error correction costs capacity, so the same content produces a denser code. For anything printed that is a trade worth making, because scuffing, folding, poor lighting and awkward angles are all realistic.

What to use for what

Printed materials with a long life — signage, packaging, business cards, vehicle livery: static code pointing at your own domain, High error correction, SVG output.

Short-term print — event tickets, table tents, a one-off flyer: static code pointing directly at the destination is fine.

WiFi sharing: static, always. The code encodes the network name and password directly, and there is no service involved at all. Worth noting that generating one on a typical online service means typing your network password into a form that posts it to someone else's server — which is an odd thing to do to a password.

Contact cards: static, encoding a vCard directly.

The QR generator here produces static codes only, encoding your content directly with no redirect. That means no scan analytics — a real trade-off, and worth naming — but also nothing that can expire, no account, and nothing that can be taken away. It generates in your browser, so WiFi passwords and contact details never leave your device.

More reading

← All articles · 10 published