Why Transit Ticket QR Codes Work Underground With No Signal — featured illustration
Technology

Why Transit Ticket QR Codes Work Underground With No Signal

7 min read
Create a QR code

A fare gate at a busy metro station clears something like thirty people a minute, and it is often two levels underground with no usable signal. Those two facts decide almost everything about how a transit QR code is built. The gate cannot ask a server whether your ticket is real, and it does not have time to think about it either.

The gate cannot phone home

Event tickets mostly work by lookup. The code carries a long random ID, the scanner sends it to a server, the server answers valid or already used. That model is the subject of how ticket validation works, and it is the right model for a conference door with WiFi and a queue you can absorb.

A fare gate is a different room. It sits in a tunnel, or in a mezzanine under a concrete slab, or in a station whose backhaul goes down during track work. Forty gates all hitting one central service at 08:40 is also a traffic pattern nobody wants a morning commute to depend on. So transit systems push the decision down into the gate. The machine in front of you decides, locally, with no round trip.

Signed, not looked up

If the gate decides on its own, the ticket has to carry its own proof, and that is what a signed payload is. Inside the code sits the ticket data: product type, validity window, zone or line entitlement, issue time, a serial number. Alongside it sits a cryptographic signature produced with a key held by the issuer. Every gate holds the matching verification key.

Checking it is arithmetic on data the gate already has. It costs a fraction of a millisecond and needs nothing from the network. What it proves is authorship: the operator issued this, and not one byte has been edited since. What it cannot prove is freshness. A signature says nothing about whether this same ticket went through gate 12 ninety seconds ago.

Freshness gets handled a layer up. Gates keep a local list of serials they have already admitted and exchange that list with the station controller on whatever interval the system runs, sometimes seconds, sometimes minutes. A ticket presented twice at the same gate is refused immediately. Presented at two gates inside one sync window, it may pass both. Operators accept that gap on purpose, because closing it means making every entry depend on a network the station cannot promise. The same trade appears from the other direction in whether QR codes work without internet.

The budget at the gate is optical, not computational

The whole transaction, from you lifting your phone to the barrier releasing, has a few hundred milliseconds in it before the queue behind you notices. Signature verification is the cheapest item on that list. The expensive part is getting a clean image.

Reading a code is a loop over video frames: expose, focus, threshold the frame into dark and light, search for the three corner squares, sample the grid, correct errors, decode. At thirty frames a second each failed attempt costs about thirty-three milliseconds, so the difference between a first-frame read and a tenth-frame read is the difference between a gate that feels instant and a gate people swear at. Nothing about the ticket changes that. The image does.

Which means the part a passenger controls is worth knowing. Hold the screen flat and parallel to the reader window rather than at an angle. Fill the window, because most gate readers are fixed focus with a narrow depth of field, and a code held too far back is a small code. Hold still for one beat instead of sweeping the phone past, since a sweep hands the reader motion blur on every frame.

Brightness, and a cracked screen

A phone screen is an emitter, and the reader under the gate glass usually has its own illumination pointed straight up at it. Those two light sources fight. A screen at twenty percent brightness in a station lit like an operating theater gives the reader almost no separation between dark and light modules, and automatic brightness will not have caught up because you only just woke the phone. Set brightness to maximum before you reach the gate. Some transit apps do it for you while a ticket is on screen, which is a good sign about the app.

A crack across the code is a harder problem than it looks. Error correction repairs missing or misread modules up to a fixed proportion, and the levels and what they buy explain the arithmetic. A crack does not remove modules; it adds a bright specular line across them, which the thresholder reads as light wherever it falls. Move the code to an undamaged part of the screen if the app lets you scroll or rotate, and tilt the phone a few degrees so the reader's own lamp reflects off the crack somewhere other than back into the lens. If the crack runs through a corner square, the gate will not find the code at all, and the ticket office is the answer. Codes read off another screen covers the same physics in the general case.

Why a screenshot sometimes works

This is the question everyone asks, and the answer is genuinely conditional.

A screenshot works when the ticket is a fixed signed payload and the gate is verifying offline. The signature is still valid in the image, the gate has no way to know it is a copy, and the barrier opens. It is the same property that makes the ticket work in a tunnel.

A screenshot fails when any of three things is true. The code rotates, so the captured one is stale within seconds. The gate did reach the network, found the serial already marked used, and refused. Or the operator binds the ticket to a device or a live app session, so the square on screen is not the only thing being checked.

The practical upshot for a passenger is that a screenshot is a reasonable backup against a dead app or a captive WiFi portal, and a bad plan as your only ticket. The upshot for an operator is that offline signed tickets and strict single-use enforcement cannot both be complete at the same time.

Rotating codes, and the account tap they compete with

A rotating ticket regenerates its code every few seconds from a secret seeded into the app and from the clock. Gates verify it without a network because they hold the same secret and agree on the time, and a screenshot is worthless almost immediately. The cost lands entirely on the passenger: an app, an account, a charged battery, and a connection at some point before travel to receive the seed. Large systems pay it. Small ones should ask what they are buying, which is the same calculation set out in event check-in with QR codes.

Then there is the thing that looks identical at the gate and is not a ticket at all. In account-based ticketing, the code identifies an account rather than a journey. The gate is not checking a fare; it checks whether this identifier is on the local accept list, opens, and reports the tap. The fare is computed later by the back office, which is why these systems can cap daily spend, charge you the cheaper of two products after the fact, and let a balance go briefly negative. A ticket code answers whether this journey is paid for. An account code answers whether this rider is in good standing. Both are black and white squares, the machinery behind them has almost nothing in common, and it explains why one operator can fix your entitlement remotely while another tells you to buy a new ticket. Car parks run into the same confusion, where a permit code and a payment code get treated as one thing.

Next time a gate refuses you, note which failure it was: no read at all, which is optics, or a red light with a message, which is the ticket. The first is yours to fix in about two seconds by raising screen brightness and holding the phone flat against the glass. The second is the ticket office. QRolling does not issue transit fares; our codes cover URLs, text, contact details and the rest of the generator's list, and every one of them is dynamic, with the destination editable on the paid plan.

Share this article