Three Ways to Count QR Code Scans, and What Each One Misses

by KoloQR TeamBasics

A tilted yellow-green tile carrying a black QR code on a magenta background, with a dark pill label reading "UTM" at its top-left corner and another reading "Dynamic" at its bottom-right.

A QR code cannot count itself. A scan becomes a number only when the phone requests something you can see: your landing page, a redirect on your domain, or a dynamic QR provider's short link. UTM tags in the code's link show the visits in the analytics you already use, for free. A redirect on your own domain counts every request and keeps the link editable. A dynamic QR code adds time, device and city per scan for a monthly fee. None of them sees a person who scans and never taps the link.

Key points

  • A QR code is a printed pattern with no connection to anything, so it cannot count scans by itself. Every tracking method counts the web request the phone makes after the scan.
  • The free method is UTM parameters on the code's link, read by the analytics already on your site. It counts visits, not scans, and it adds characters that make the printed pattern denser.
  • A redirect on your own domain, such as yourdomain.com/menu-qr, keeps the pattern short, counts every request, and lets you change the destination later. Use a 302 or 307 redirect, because browsers cache a 301.
  • A dynamic QR code is a paid redirect run by a provider. It reports time, device and approximate city per scan, and the printed code depends on that provider's short link.
  • In Google Analytics 4, a link tagged utm_medium=qr lands in the Unassigned channel, because no default channel rule matches "qr". A custom channel group fixes that.
  • Use one code per placement. A single code on every poster tells you how many people scanned, but not which poster worked.

Can You Track a Static QR Code?

A static QR code cannot report its own scans, but the visits it produces can be tracked. A static QR code is a code whose link is stored in the pattern itself, so the phone goes straight to that link with nothing in between. Whatever counts the scan has to sit at the destination: the page's analytics, or a redirect you control.

The practical consequence is that tracking is decided by the link you put in the code, not by the generator that drew it. A code from any free generator, KoloQR included, is as trackable as a paid one if its link carries UTM parameters or points at a redirect on your domain. KoloQR, a free QR code generator with circular and custom-shaped QR codes, makes static codes today; what it encodes is exactly the link you paste.

What a static code can never report is the scan that was not followed. Phone cameras show the decoded link as a banner and open nothing until the person taps it. A scan without a tap produces no request, so no analytics tool, redirect or dynamic QR platform can count it.

The Three Methods Compared

Choose the method by what you need to know and how long the code will stay in print. UTM tags answer "did this campaign bring visitors" at no cost. A redirect on your own domain answers "how many times was this code opened" and keeps the link editable. A dynamic QR code answers "when, where and on what device" without any setup on your side.

UTM tags + your analyticsRedirect on your own domainDynamic QR code
What is countedPage visits that arrived through the codeEvery request to the short pathEvery request to the provider's short link
Extra detail per scanWhatever your analytics records for any visitWhatever your server or host logsTime, device type, operating system, approximate city
Ongoing costNoneNone on most hostingA monthly or yearly subscription
Change the destination after printingNoYesYes, while the account is active
Works when the link opens an appNo - the app opens, your analytics never loadsYes - the redirect is counted before the app opensYes - the redirect is counted before the app opens
Effect on the printed patternLonger link, denser codeShort link, simple codeShort link, simple code
SetupAdd parameters to the linkOne redirect rule on your domainAn account with the provider
Every row follows from where the counting happens: at the destination page, at your own redirect, or at the provider's redirect.

A common combination is a redirect on your own domain that forwards to a UTM-tagged destination. The printed code stays short and permanent, the redirect counts every request, and the analytics on the page still attributes the visit to the right campaign.

How to Track QR Code Scans With UTM Parameters

UTM parameters are labels added to the end of a link that tell analytics tools which campaign, source and medium a visit came from. Google Analytics, Matomo, Plausible and most other web analytics tools read them without any setup. Google recommends always setting three: utm_source, utm_medium and utm_campaign.

  1. Start From the Destination Link. Copy the page the code should open, for example https://example.com/menu. Check it opens on a phone before tagging it.
  2. Add Source, Medium and Campaign. Append ?utm_source=table-tent&utm_medium=qr&utm_campaign=autumn-menu. The source names the placement, the medium names the channel and the campaign names the effort.
  3. Keep Every Value Lowercase. Google Analytics treats utm_source=Poster and utm_source=poster as two different sources. Lowercase values with hyphens keep the report in one row per placement.
  4. Generate the Code From the Tagged Link. Paste the full tagged link into the URL field of a QR code generator, then style and download the code as usual.
  5. Scan It and Check Real-Time Reports. Scan the printed proof with a phone, open the page, and confirm the visit appears in your analytics' real-time view with the right campaign name.

One parameter is worth adding when the same campaign is printed in several places: utm_content. Google describes utm_content as the parameter that differentiates creatives, so utm_content=window and utm_content=counter tell two placements of one campaign apart without inventing a second campaign.

Where QR Code Traffic Shows Up in Google Analytics 4

In Google Analytics 4, visits tagged utm_medium=qr appear in the Unassigned channel. GA4's default channel group sorts traffic by fixed rules - "email" goes to Email, "sms" to SMS, "referral" to Referral - and no rule matches "qr", "print" or "offline". The visits are recorded correctly; only the channel label is unhelpful.

To read QR traffic by itself, open Reports, then Acquisition, then Traffic acquisition, and switch the table's dimension to Session source / medium or Session campaign. Your QR sessions appear as rows such as table-tent / qr, with their engagement and conversions beside them.

To make QR codes a channel of their own, create a custom channel group in the Admin settings and add a QR channel whose condition is medium exactly matches qr. Place it above the default rules so it wins, and every report that groups by channel will show QR codes as one line.

Do not borrow a medium GA4 already recognises just to avoid Unassigned. Tagging QR codes utm_medium=referral or utm_medium=social files them under the wrong channel and mixes them with traffic that has nothing to do with print.

UTM Tags Make the QR Code Denser

Every character added to the link adds data to the pattern, and UTM tags can triple the length of a short link. At error correction level M, the 24-character link https://example.com/menu fits QR version 2, a grid of 25 by 25 modules. The same link with three UTM tags is 85 characters and needs version 6, a grid of 41 by 41.

At the same printed width, a denser grid means smaller modules. Printed 3 cm wide, a version 2 code has modules about 1.2 mm across; a version 6 code has modules about 0.7 mm across, which old phones and dim rooms read less reliably. Codes with a centre logo usually use level H, which grows the grid further.

Two fixes keep the pattern simple. Short UTM values help: utm_source=table instead of utm_source=table-tent-autumn-2026. A redirect on your own domain helps more: the code holds yourdomain.com/t4, and the redirect adds the full tagged link after the scan, where its length costs nothing. The QR code capacity guide has the full table, and the minimum print size guide turns module size into a printed size.

How to Track Scans With a Redirect on Your Own Domain

A redirect on your own domain is a short path, such as yourdomain.com/menu-qr, that forwards each visitor to the real page and can be counted as it does. A redirect is a server response that sends a browser from the address it requested to a different one. Most website hosts and CMS platforms can create one without code: Vercel, Netlify and Cloudflare all have redirect rules, and WordPress has redirect plugins.

  1. Pick one short path per placement, such as /qr/menu-table and /qr/menu-window. A path you will never reuse for anything else keeps the counts clean.
  2. Point each path at the destination, with UTM tags on the destination if you also want campaign attribution in analytics.
  3. Answer with a 302 or 307, not a 301. Browsers cache a 301 redirect and may skip your server on the next scan, which loses the count and makes a later change of destination invisible to repeat visitors.
  4. Read the counts in your host's request logs or redirect analytics, filtered to the path. Expect some requests from bots and link checkers, and exclude your own test scans.
  5. Encode the short path in the QR code, then print. The pattern stays small, and the destination stays yours to change.

The redirect is what makes app links countable. A QR code that opens an Instagram profile, a WhatsApp chat or a Google review form usually lands in an app, where your site's analytics never runs. A redirect on your domain records the request first and then hands the phone to the app, so the scan is counted even though no page of yours was viewed. The same applies to an Instagram QR code or any other link that opens an app.

Tracking Scans With a Dynamic QR Code

A dynamic QR code is a code that encodes a provider's short link, which redirects to your destination and records each scan on the way. The provider's dashboard typically shows total and unique scans, the time of each scan, the device type and operating system, and a country and city estimated from the IP address. It needs no setup on your website.

The trade-off is dependency. The printed pattern holds the provider's hostname, so the code keeps working only while that provider keeps the link alive, and most charge for as long as the print is in use. The static vs dynamic QR codes guide sets out when that is worth paying for, and what a dynamic code subscription costs over time puts numbers on it.

KoloQR codes are static today, so tracking a KoloQR code means UTM tags or your own redirect. KoloQR dynamic codes with scan analytics are in development, with a waitlist open; they record the same kind of data described above and keep redirecting to the last destination if the subscription ends.

Why Your Scan Numbers Don't Match

Different methods report different numbers because each one counts a different moment. A redirect counts requests, analytics counts page visits that loaded its script, and a dynamic platform counts requests to its own link. The gaps between them are predictable:

  • Scans without a tap are invisible to every method. The camera decodes the code and shows the link, and if the person does not tap it, nothing is requested.
  • Links that open an app reach a redirect but never reach your page analytics, because the app takes over before any page of yours loads.
  • Declined cookie banners and ad blockers stop many analytics tools from recording a visit that did happen. A redirect is not affected, because it is counted on the server.
  • Repeat scans inflate totals. The same person scanning a table card three times is three requests; unique counts estimate devices, not people.
  • Your own tests count like anyone else's. Note the date you printed and ignore the scans before it, or filter your own network out.
  • Bots and link checkers occasionally request a redirect path. They show up as requests with no matching visit and are usually a small, steady background.

Treat the numbers as a comparison, not an audit. The same method applied to two placements tells you reliably which one works better, even when neither number is the exact count of people who scanned.

Measure Each Placement Separately

One code per placement is the rule that makes scan tracking useful. A single code on every flyer, poster and table card produces one total and no answer to which placement worked. A separate code per placement - different UTM content values or different redirect paths - produces a row per placement, and the comparison is the useful part.

PlacementUTM tagsRedirect path
Table tentutm_source=table&utm_medium=qr&utm_campaign=autumn-menu/qr/menu-table
Shop windowutm_source=window&utm_medium=qr&utm_campaign=autumn-menu/qr/menu-window
Takeaway bagutm_source=bag&utm_medium=qr&utm_campaign=autumn-menu/qr/menu-bag
Same campaign, three placements: one row per placement in the report.

Print the placement name in tiny type beside each code on the print file, so the codes cannot be swapped by accident when the job reaches the printer. Codes that look identical and differ by four characters in the link are the easiest thing in a print run to mix up.

What Scan Tracking Can and Cannot Know

Scan tracking records the request a phone makes, never the person holding the phone. A QR code cannot read a name, a phone number, an email address or a GPS position, because all a scan does is make the phone open a link. What a server can see is what any website sees: the time, the IP address, and the browser's description of the device.

Location in scan reports is an estimate from the IP address. It is usually right about the country and often right about the city, and it can be far off on mobile networks, which route traffic through regional gateways. Treat a city in a scan report as approximate.

In the European Union, an IP address can count as personal data under the GDPR. If your redirect or analytics stores IP addresses, mention scan tracking in your privacy notice, and prefer tools that shorten or discard the address once the location is derived.

Make Your QR Code

Free, with no account and no watermark. Choose a shape, add a logo, check the contrast, and export SVG, PDF, EPS or PNG - a static code with no subscription behind it.

Generate QR Code

Questions? Answered

Only if the code's link leads through something that counts. A static code reports nothing by itself. Add UTM parameters to the link to see visits in your analytics, encode a redirect on your own domain to count every request, or use a dynamic QR code, whose provider counts scans for you.

Yes, from the destination. A printed code's link cannot change, but you can still count what arrives at it: look for referrer-less visits to that page in your analytics, or, if you control the server, read its logs for that address. Next time, encode a redirect or a tagged link before printing.

No. UTM parameters are ordinary characters in the link, and any phone opens a tagged link normally. They do make the code denser: three tags can push a short link from QR version 2 to version 6. Keep values short, or encode a short redirect that adds the tags after the scan.

Because GA4's default channel rules do not recognise utm_medium=qr. The visits are recorded correctly, but no default channel claims them. View them by Session source / medium, or create a custom channel group with a QR channel that matches the medium qr.

No. A scan only makes a phone open a link, so tracking sees what any website sees: the time, the device type and an IP address that gives an approximate location. It cannot read a name, a phone number or a GPS position. Identity only appears if the person fills in a form afterwards.

Yes, two. UTM parameters on the link cost nothing and work with the free tier of Google Analytics and most other analytics tools. A redirect on your own domain is free on most website hosting. Both work with codes from any free QR code generator.

Because the redirect counts every request and the analytics counts only visits that loaded its script. Visits blocked by cookie refusals or ad blockers, links that open an app, and people who left before the page loaded all reach the redirect but never reach the analytics. A gap of that kind is normal.

Only if the code already points at something you control. A code that encodes your own redirect path, or a dynamic code, can start forwarding to a tagged link at any time. A code that encodes the final page directly can only be counted at that page, through its analytics or server logs.

Why KoloQR?

  • Create QR codes for websites, menus, Wi-Fi, PDFs, and business cards
  • Customize colors, logos, and unique shapes
  • Download high-quality PNG and SVG files
  • Built for both print and digital
Generate QR Code
A plain black QR code beside the same code restyled as a circle with brand colors