Designing Tracking Numbers That Do Not Break at Scale

Logistics, courier & cargo5 min read

Tracking number schemes fail in predictable ways: collisions, transcription errors, and numbers that leak volume. How to design one that lasts.

A tracking number is the most-used piece of data a courier produces. It is written on a label, read aloud over the phone, typed by customers, scanned dozens of times, and quoted in every dispute. It is also usually designed in an afternoon and then impossible to change.

Here is what goes wrong and how to avoid it.

It will be transcribed by humans

However good the scanning is, people will read tracking numbers aloud and type them in. That single fact drives most of the design.

Drop ambiguous characters. 0 and O, 1 and I and l, 5 and S, 8 and B. Either use digits only, or use an alphabet that has already removed the collisions — Crockford’s base32 exists for exactly this reason.

Add a check digit. A single check character catches almost every single-character error and most transposed pairs. It costs one character and turns “the customer typed it wrong” from a support call into an immediate, specific error message at the point of entry.

Keep it short. Every extra character is another chance to mistype and another thing to read over a bad phone line. Twelve characters is comfortable; twenty is not.

Group it. ABCD-1234-EF is measurably easier to read aloud and retype than ABCD1234EF. Store it without the separators and display it with them.

It should not be guessable in sequence

If consignment 100341 exists, then 100342 exists too, and anyone can walk your entire database from a single tracking number. That exposes customer names, addresses, phone numbers and COD amounts — other people’s data, from a public tracking page with no authentication.

It also leaks volume. A competitor who books two parcels a week apart can read your throughput directly off the difference in numbers, and so can anyone doing due diligence on you.

The fix is to separate the internal sequential identifier from the external tracking number. Internally, an auto-incrementing ID is fine and useful. Externally, issue a non-sequential token — random within a defined space, checked for uniqueness at issue.

If you must issue sequentially, then the public tracking page has to require a second factor, usually the last few digits of the recipient’s phone number. That is the common approach and it works, but it adds friction to the thing customers use most.

Prefixes are useful and dangerous

It is tempting to encode meaning into the number: branch, service type, year.

Some of that is genuinely useful. A short prefix identifying the issuing branch or the service level lets staff route a parcel from the label alone when a scanner is unavailable, which happens.

The danger is encoding anything that can change. A parcel booked at one branch and transferred to another still carries the original branch prefix forever — which is correct, since it records where it was booked, but people will misread it as where it currently is. And a service level encoded in the number becomes wrong the moment a customer upgrades a shipment.

The rule: encode facts that are true at issue and never change. Everything else belongs in a field.

Offline issuance must not collide

Branches lose connectivity. If a booking counter cannot issue a tracking number without asking a central server, booking stops during an outage — and staff will start writing on paper, which means parcels enter the network without a number at all.

Two workable approaches:

  • Pre-allocated blocks. Each branch is issued a range in advance and draws from it locally. Simple, and requires monitoring so a branch does not exhaust its block.
  • Branch-embedded numbers. The branch identifier is part of the number, so two branches cannot generate the same value even with no coordination.

Pre-printed waybill stationery is really the physical version of the first approach, and it works for the same reason: the numbers were allocated before they were needed.

Barcode format

Whatever the number, it has to scan. Code 128 handles alphanumeric data compactly and is well supported by the handheld scanners common here. QR codes hold more and scan from a phone camera, which matters if riders use phones rather than dedicated scanners.

Printing both is common and sensible: the linear barcode for warehouse scanners, the QR for phones, and the human-readable number underneath for when neither works. Thermal labels smudge and tear, so the human-readable fallback earns its space.

Do not reuse numbers

Ever. Even after years, even for cancelled bookings. A reused number means a tracking lookup can return the wrong shipment, and historical records become ambiguous.

Cancelled bookings keep their number, marked cancelled. The space is large enough that you will not run out — and if you are worried you might, make it one character longer now rather than reusing later.

A worked example

A scheme that satisfies all of the above:

  • 2 characters: branch code, fixed at issue
  • 8 characters: random from a 32-character unambiguous alphabet, unique-checked
  • 1 character: check digit over the whole thing

Eleven characters, displayed as KT-A7F2K9M4-3. Non-sequential, so it leaks nothing. Issuable offline, because the branch code guarantees no collision. Self-validating on entry. Comfortable to read aloud.

The internal database ID stays sequential and private, where it belongs.

We build the logistics management system that courier and cargo networks in Nepal use, including offline-safe number issuance and label printing. If your tracking numbers are a running count, talk to us.

Read next

Stay Updated with the Latest Tech