Bulk QR Codes: What Goes Wrong in a Batch of 500

Generating one code is easy. Generating five hundred that all print the same size, and checking every one is correct before the run, is where it goes wrong.

By QRotto · Published · 8 min read

Table numbers for a restaurant. Asset tags for a maintenance team. Seat codes for a venue. Unique links on a thousand product inserts. These jobs all start the same way: a list goes in, a folder of images comes out, and the folder goes to a printer.

We generated 500 codes to find out what actually goes wrong at that scale. Three things did, and the first one is invisible until the codes are printed and laid out on a sheet.

The numbering trap

Here is the finding that matters most, and it has nothing to do with QR codes being difficult.

QR codes come in fixed version steps, not a smooth scale. Add one character to your data and usually nothing happens, but occasionally the code jumps to the next version and gains four modules on every side. In a batch numbered sequentially, that jump happens partway through the list.

Two rows of QR codes. The top row uses unpadded numbering and the last two codes are 29 by 29 while the first two are 25 by 25. The bottom row uses four digit padding and every code is 25 by 25.
Same URLs, same generator. The top row crosses from four digits to five and the codes change size partway along. The bottom row is padded, and every code in the batch is identical in size.
URLCharsGrid
https://example.com/t/12325 x 25
https://example.com/t/99992625 x 25
https://example.com/t/100002729 x 29
https://example.com/t/200002729 x 29

One extra digit and the grid grows by 16%. Print that batch at a fixed 20 mm square and the codes after 9999 have visibly smaller modules than the ones before it, which means they scan less well in exactly the same conditions. Nobody notices until someone complains that "some of the table cards do not work".

The fix costs nothing. Pad your numbers to a fixed width before you generate. Use /t/0001 rather than /t/1. We regenerated the same 500 code batch with four digit padding and every single code came out 25 by 25, so a single print size works for the whole run.

The same logic applies to any varying field, not just numbers. If half your codes carry a short product name and half carry a long one, the batch will not be uniform. Decide the longest value first and check that one.

SVG or PNG for a print run

We measured both, at the sizes a print job actually needs:

OutputOne codeA batch of 500
PNG, 256 px3.5 KB1.7 MB
PNG, 512 px14.5 KB7.1 MB
PNG, 1024 px41.1 KB19.7 MB
PNG, 2048 px116.0 KB56.6 MB
SVG17.6 KB8.4 MB

SVG is less than half the weight of a print resolution PNG, and unlike the PNG it has no resolution at all. The same file prints crisply on a business card or a shop window. For anything going to a designer or a printer, SVG is the right answer and it is not close.

PNG earns its place in two situations: when the code is going into something that cannot take vector art, such as a spreadsheet, a label printer's own software or an email, and when you want to look at the batch quickly without opening design software.

One thing not to do is export small PNGs to keep the folder tidy. A 256 px PNG is 3.5 KB and looks fine on screen, and it will be upscaled by the printer into something soft. Our scan limits test found blur is what kills codes, and upscaling a small PNG is a way of manufacturing blur.

Advertisement

The characters that break a batch

We ran a list of awkward inputs through our own bulk tool to see what survived a round trip. Most things did. Commas, quotes, ampersands in query strings, semicolons, backslashes and a 200 character URL all came back exactly as they went in.

Two things did not, and both are worth knowing about whatever tool you use:

If your list contains a single accented name, generate that one first and decode it before running the other 499.

Verify the whole batch, not a sample

The usual quality check on a batch is to scan two or three codes with a phone and assume the rest are fine. That catches a broken generator. It does not catch the error that actually happens, which is a row being wrong in the source list.

A wrong row produces a perfectly valid QR code pointing at the wrong thing. It scans beautifully. You find out when a customer lands on table 47's menu at table 12.

The check that catches it is to decode every image and compare the result against the line it came from. That is what we do to our own generators before publishing anything, and it is the only reason we trust the numbers in these articles. If you are producing a batch for a client, it is worth the twenty minutes.

For a single code, our scanner shows you exactly what is inside before you commit, and the stress test shows how much abuse it tolerates.

Naming the files so the printer can use them

A folder of 500 files called qr-code.png, qr-code-1.png and so on is a problem for whoever has to lay them out. Useful names:

Our bulk generator names files from the content of each line and exports the batch as a zip of SVGs, a zip of PNGs, or a PDF sheet for printing directly.

A checklist before you send the run

  1. Numbers padded to a fixed width, so every code in the batch is the same grid size.
  2. The longest value in the list checked, because it sets the size everything else must match.
  3. Any accented or non Latin entry generated and decoded first.
  4. SVG for the printer, PNG only where vector cannot go.
  5. Every image decoded and compared against its source line.
  6. One code printed at the real size, on the real stock, and scanned by a phone that is not yours.

Step six catches things the other five cannot, including paper that is too glossy and a print size decided on screen. Our sizing guide covers how to pick that size from the scanning distance.

How we tested this

The honest limit: this is a software test of the files, not of printing. It tells you which files are correct and which will be uniform. It cannot tell you how your printer's ink behaves on your stock, which is why the last item on the checklist is a physical test.

The summary

Bulk QR generation is not hard. The failures are mundane: a numbering scheme that changes the code size partway through, small PNGs upscaled into blur, an accented name silently mangled, and one wrong row in the source list that produces a perfect code pointing at the wrong place.

Pad your numbers, export SVG, and decode every single one before it goes to print. The first two take a second. The third is the only check that finds the error that actually costs money.

Our bulk QR code generator takes a list, previews every code, and exports the batch as SVG, PNG or a PDF sheet. Like everything here it runs in your browser, so the list never leaves your machine.

QRotto

QRotto builds free browser based QR code generators and writes the guides that go with them. Every generator is verified by decoding the codes it produces and confirming the output matches the input exactly. See our editorial standards.