Perishables Get a Date. Everything Else Gets a Serial.

A GS1 Digital Link QR code can carry far more than a product number. It can carry lot numbers, serial numbers, dates, weights and dozens of other fields defined by GS1 Application Identifiers. The question is not what you can encode. It is what you should.

Our answer is deliberately short: perishables get a best before date, and everything else gets a serial number. Here is the reasoning, starting with the arithmetic rather than the recommendation, because we have a stake in the answer and you should be able to check it.

This post is the short version. The full reference, with the catalog table and the version-by-version numbers, lives in our docs at Choosing Application Identifiers.

The arithmetic

An Application Identifier, or AI, is a numeric prefix that tells a scanner what the data after it means. AI 01 is a GTIN, AI 21 a serial number, AI 15 a best before date.

In a Digital Link, those become parts of a web address. The GTIN and its key qualifiers, lot and serial, are path segments in a fixed order. Data attributes such as dates go in the query string as key=value pairs, which is a requirement of the Digital Link URI Syntax (release 1.7.0, section 4.10).

Every character in that address has to be encoded in the QR code, and, as we covered in the sizing post, your data length chooses your symbol version, and your symbol version sets your minimum printed size. More data, bigger code. There is no way around that chain.

We encoded the same GTIN with each combination of AIs on our short resolver host, uppercase, at error correction level M, using Zint 2.15.0. Sizes are the symbol only, at the 0.495 mm target X-dimension.

Data on the codeCharactersVersionSize
GTIN only34212.4 mm
+ best before date44314.4 mm
+ serial (8 characters)46314.4 mm
+ serial + best before56314.4 mm
+ lot + serial57314.4 mm
+ lot + serial + expiry67416.3 mm

The last row is the anti-pattern. Everything it puts on the pack in lot form, the serial row already delivers through the resolver, at a full version smaller.

There is a second effect worth knowing about. The ? and = that begin a query string are outside the QR alphanumeric character set, so a single date attribute forces part of the symbol into a less dense mode. On the short host, a GTIN plus a 13-character serial plus a best before date is 61 characters and encodes at version 4. A GTIN plus a lot plus the same serial is 62 characters and encodes at version 3. A shorter string, a bigger symbol.

That is the cost of a date. The point of the next two sections is that it is worth paying, and that choosing a serial over a lot is how you pay for it.

The test for what goes on the pack

We use one question for every AI:

Must a machine act on this at the moment of scan, before any network call can complete?

Everything we recommend follows from it.

Dates pass the test

When a cashier scans a carton of yogurt, the register has to act on that sale in the same instant it rings up the price. That decision cannot depend on a web request completing, and it has to keep working when the store’s internet does not.

Because the best before or expiration date is encoded directly in the QR code as AI 15 or AI 17, a point-of-sale system can parse it locally from the scan data and decide on the spot. No lookup, no latency, no failure mode. GS1’s guideline on 2D barcodes at retail point-of-sale lists preventing the sale of out-of-date product and automatic date-based markdowns among the benefits of encoding data beyond the GTIN, and notes that point-of-sale systems may need upgrading to use that data. Check what your retail partners’ systems read before you rely on it.

And the right action depends on which date it is. GS1 draws the line itself in the General Specifications (release 26.0):

  • A best before date (AI 15) “signifies the end of the period under which the product will retain specific quality attributes or claims even though the product may continue to retain positive quality attributes after this date.”
  • An expiration date (AI 17) is “the date that determines the limit of consumption or use of a product.” For food, it indicates “the possibility of a direct health risk resulting from use of the product after the date.”

A best before date is a quality promise, so a passed date is a markdown opportunity: the register can apply an automatic discount and move product that would otherwise become shrink. An expiration date is a safety limit, so a passed date blocks the sale. Fifteen means mark it down. Seventeen means pull it.

On the law, we will keep to the directional picture, because it varies by product and market. In Canada, CFIA says it is not illegal to sell food past its best before date, while food past its expiration date should not be bought, sold or eaten, and expiration dates are required only on certain foods, infant formula among them. In the United States, USDA FSIS notes that product dating is not required by federal regulation except for infant formula, and some states regulate particular products. Near-date discounting is already ordinary retail practice. The lane just automates it.

Fresh products usually cannot be serialized economically, but they do not need to be. The best before date changes at exactly the cadence your packaging line already prints, so encoding AI 15 costs you nothing operationally. In return, retailers can automate markdowns and shoppers see freshness the moment they scan.

One category takes this from best practice to something close to obligation. Infant formula is the only US food with a federally required date, and we cover it in its own article.

The serial is a pointer, not a payload

A serial number is not a data payload. It is a key.

The General Specifications define it as assigned to an item for its lifetime and, combined with a GTIN, identifying one individual unit. When a scanner resolves a serialized Digital Link, the resolver already knows which lot that unit came from and the dates recorded against it. In Closient every serial links to its lot, so a recall scoped to a lot automatically covers the right serials, and rules and destinations can be scoped to an exact serial, a lot, or a named group of either.

That gets you lot-level traceability with roughly ten characters on the package. Encoding the lot alongside the serial buys you nothing a resolver lookup does not already provide, and it costs you a bigger printed code.

Competitors tend to treat the QR code as a data container and stuff it with AIs. We treat it as a key into a resolver. The key is short and permanent; what it points to can be as rich as you need and can be corrected after the pack is printed.

Keep serials short, uppercase alphanumeric, and meaningless. AI 21 allows 20 characters. Use 8 to 10. Every character beyond what uniqueness requires is wasted modules.

What belongs in the resolver

Almost everything else.

AIOur advice
10, batch or lotUsually a smell. If you can serialize, the serial implies the lot.
11, production dateRarely on the pack. Resolve it from the lot or serial.
30 and 310n, count and net weightVariable measure products only.
422, country of originOnly when a rule requires it on the pack.
Anything elsePut it in the resolver, not the URI.

GS1 defines hundreds of Application Identifiers. If one you want is not in that list, the answer is almost always the same. And do not encode anything that can change: the code is printed and immutable, so anything that might be corrected later belongs behind the resolver. A date does not violate that rule. It is fixed at fill time, which is the whole point of the print run.

Where this advice stops

Two honest limits.

It is scoped to consumer-facing scanning. A receiving dock or a retail backroom running a recall check with no signal is also an offline decision, and pushing the lot off the pack breaks it. Supply chain data capture has a different answer. If trading partners scan your product as well as shoppers, you may reasonably need the lot on the pack. The legitimate cases for AI 10 are product you cannot serialize, such as fresh-cut produce, and scans with no network. We walk through the produce case in the 2026 lettuce recall.

We benefit from serials. Closient counts serial records in its plans, so advice that points towards serials is advice that points towards our product. That is why we led with the version arithmetic. It holds with any QR encoder, so run it yourself. Encoders differ in how well they switch between encoding modes, so confirm the version in your own generator before you commit artwork.

What to do on Monday

  1. For perishables, encode the best before date, or the expiration date if it is a safety or regulatory limit.
  2. For everything else, encode a short uppercase serial.
  3. Leave the lot off the pack unless you cannot serialize or a trading partner needs it offline.
  4. Check the printed size before you commit artwork. Data length sets your symbol version, and your symbol version sets your minimum print size. The sizing guide has the exact numbers.

Closient’s Digital Link builder composes the URI with the AIs in the order the standard requires and hands off to the print size tool, so you can see what a combination does to the printed size before it goes to plate.

Standards citations in this post were checked against GS1 General Specifications release 26.0 and Digital Link URI Syntax release 1.7.0 on October 15, 2026. Version figures were produced with Zint 2.15.0. Regulatory statements are general and not legal advice.