# QR code tracking: what you can measure and how to respect privacy

> Only dynamic QR codes routed through a redirect can count scans — and even then, never who scanned. What you can measure, what you cannot, and privacy-friendly tracking habits.

QR codes can tell you how often a code is scanned, roughly when, and on what kind of device — but only if the code is dynamic, meaning it routes each scan through a redirect that logs the visit. No QR code, dynamic or static, can tell you who scanned it. This article explains what is realistically measurable, what is not, and how to track scans while respecting the privacy of the person holding the phone.

## Why only dynamic codes can count scans

A QR code is just a picture of data. In a static code, that data is your destination URL itself. When someone scans it, their phone goes straight to your website, and nothing in between records the event. Your web analytics will see a visit, but it looks the same as any other visit unless you tagged the URL in advance.

A dynamic code works differently. It encodes a short redirect URL — something like `qrmx.vip/abc123` — owned by the generator service. When someone scans, the phone first requests that short URL. The service's server receives the request, logs a few details about it, and sends an HTTP redirect to your real destination. That log is the tracking. It is also why dynamic codes can be edited after printing: change the redirect target and the same black-and-white square keeps working.

The trade-off is dependency. If the redirect service has an outage or shuts down, every printed code stops working. Dynamic tracking buys you measurement and flexibility at the cost of a link in the chain that you do not control.

## What you can reasonably measure

Every scan is an ordinary web request hitting the redirect server, so the measurable things are the things a web server naturally sees:

- **Number of scans.** Each request counts as one scan. Treat the total as approximate: people re-scan, some camera apps prefetch links, and one enthusiastic visitor can inflate the count.
- **Rough time.** The server timestamp gives you the date and usually the hour. This is most useful for comparing placements — a poster by the entrance versus a flyer in the bag.
- **Device type.** The request's user-agent header reveals the operating system family, typically iOS versus Android, and sometimes the browser. It is a coarse signal and can be missing or generic.
- **Country or region.** The server can infer a rough location from the IP address. VPNs, office networks, and mobile carrier routing all skew this, so treat city-level data as a hint, not a fact.

None of this is exotic; it is the same shallow data every website visit produces. The value comes from structure. Give each placement its own code, and the numbers become comparable instead of blended into one lump figure.

## What you cannot know

A scan is an anonymous HTTP request. It carries no name, no email address, no phone number, and no account ID. Unless a person deliberately types their details into a form on the destination page, you have no idea who they are. You also cannot reliably follow one person across multiple codes or visits; without logins or cookies on your own domain, every scan is a fresh stranger.

Two clarifications are worth making, because fear of QR codes often outruns the facts:

- Scanning does not give anyone access to the phone. A code cannot read contacts, photos, messages, or precise GPS location. It can only open a link or, in special cases, trigger something like joining a Wi-Fi network.
- An IP address is not an identity. It hints at a rough area, but it cannot tell you which person in a household — let alone in a city — held the phone.

Even device type is an informed guess based on a header the phone sends, and browsers can alter it. If someone promises you the identities of scanners from a QR code alone, they are selling something they do not have.

## Tracking static codes with UTM tags and web analytics

If all you want to know is how much traffic a code brings to your website, you may not need a dynamic code at all. Keep the code static and append UTM parameters to the destination URL:

`https://example.com/menu?utm_source=poster&utm_medium=qr&utm_campaign=spring`

Your existing web analytics will then show these visits as their own segment — source "poster", medium "qr" — separate from search, social, and typed traffic. No extra service, no redirect dependency, and the code never stops working. The tags are visible in the URL itself, which is a kind of honesty: anyone who cares can see the link is measured.

The limits are real:

- The URL gets longer, so the QR pattern gets denser and slightly harder to scan from a distance.
- You cannot change the destination after printing.
- You measure visits, not scans. Most phones show a URL preview after scanning and wait for a tap, so people who scan, glance, and move on never appear in your analytics.

For many uses — a restaurant menu, a product page, a download link — that is plenty. Choose UTM-tagged static codes when the question is "how much traffic?", and dynamic codes when you need scan counts before the tap or want to edit destinations later.

## Privacy-friendly practice

Measuring scans is legitimate. Doing it carelessly is unnecessary, and in many places it is also a legal problem, since privacy laws such as the EU's GDPR can treat IP addresses as personal data. Three habits keep a scan-tracking setup on the right side of both ethics and law.

### Collect nothing personal

Do not log full IP addresses, do not fingerprint devices, and do not put the useful part of your content behind a login just to identify scanners. Keep only the aggregate signals described above: counts, timestamps, device family, coarse region. If you use a redirect service, prefer one that truncates or hashes IP addresses instead of storing them in full. A useful test: if a record cannot be linked to a person, it is far less likely to cause harm — or compliance trouble.

### Keep it briefly

Raw request logs pile up for no reason. A common rule of thumb: keep raw logs for 30 to 90 days, long enough to spot trends and debug a broken campaign, then delete them and keep only aggregates — monthly counts per code, device splits, and so on. Aggregates answer nearly every question a report asks anyway, and data you no longer hold is data that cannot leak.

### Say what you do

If people would reasonably want to know, tell them. A short line on the poster or the landing page — "Scans of this code are counted anonymously to improve our events" — costs one sentence and buys the trust that covert tracking destroys. If you use a generator service for dynamic codes, read its privacy policy before printing anything: what it logs, how long it keeps it, and whether it shares data with anyone.

## A simple workflow that works

1. Write down the one question you want answered, such as "which poster location works best?"
2. Pick the lightest tool that answers it: a static code with UTM tags for traffic questions, a dynamic code for scan counts and editability.
3. Create one code per placement. Free generators such as QRCodeMax.Vip handle both static and dynamic codes, so you can match the tool to the question.
4. Keep a small note mapping each code to its placement; unlabelled codes become mysteries within a month.
5. Test-scan every code with two different phones before printing anything in bulk.
6. Review the numbers on a fixed schedule — weekly or monthly — and act on them: move the poster, change the destination, retire the campaign.

## The key takeaway

Measure counts and coarse context with dynamic codes or UTM-tagged static ones; never chase the identity of the person behind the scan. Collect less than you could, delete it sooner than you must, and say plainly what you count. That is tracking people can trust — and, not coincidentally, tracking you will actually use.
