31 March 2026 · 5 min read

Your ticket does not need a blockchain

A ledger earns its cost only when several parties who distrust each other must write to it. A venue's ticketing has one writer, and one writer means a signature and a row.

The pitch for blockchain ticketing is that a ticket on a chain cannot be forged or double-spent, and both halves of that are true. They are also true of a signed ticket in a database, at a fraction of the cost and latency, and the reason is that a venue's ticketing has exactly one writer. When I built the QR ticketing and contactless entry system for visitor attractions, the question of whether the tickets should live on a chain came up early and was settled by a count, not by an opinion about blockchains.

Count the writers

Here is the test. Count the mutually distrusting parties that must append to the record. Not read it, append to it. If the answer is one, the record is a database with signatures: the one writer signs what it writes, anyone can verify the signature, and nobody else needs to be trusted because nobody else writes. If the answer is two, the two parties need a shared log that neither can rewrite alone, and there are several ways to get one that are not a blockchain. Only when the answer is many, and there is no operator all of them would accept, does a chain pay for itself, because a chain is the machine for letting strangers append to one record without an operator.

A venue's tickets have one writer: the venue, or the platform it uses. The venue issues the ticket, the venue admits the visitor, the venue refunds the cancellation. The visitor never writes to the record; the visitor presents a credential and the venue writes the result. There is no second party who needs to append anything and who would distrust the venue's log, because the only party with an interest in the log's integrity is the party keeping it.

Where different records sit, by writer count and need for public verification A two by two grid. Horizontal axis: number of mutually distrusting writers, one on the left, many on the right. Vertical axis: need for public verifiability, low at the bottom, high at the top. Bottom left: tickets, receipts, loyalty points; a signed database. Top left: audit logs and certificates; a signed database with published hashes. Bottom right: settlement between a few known firms; a shared log among the parties. Top right: a public asset register among strangers; a chain. Signed rows, hashes published certificates, audit logs A chain strangers, no operator anyone accepts Signed rows in a database tickets, receipts, loyalty points A shared log among the parties settlement between known firms Mutually distrusting writers: one to many Need for public verifiability: low to high
Illustrative: a placement of record types; the dot is a venue's tickets.

What a signed row gives you

Take the two properties the chain pitch promises and check them against a signed ticket in a database.

Cannot be forged. The venue signs each ticket at issue with a private key; the signature, 64 bytes under Ed25519, proves the ticket came from the venue and has not been altered. A gate verifies it with the public key, offline if it has to. Nobody without the private key can produce a ticket that verifies. That is the same guarantee a chain gives, from the same primitive, because a chain's forgery resistance is also a signature.

Cannot be double-spent. This is the one people think needs a chain, and it needs a row. The ticket's row has a status, and admission is a conditional update: set it to spent where it is unspent, in one statement. The database serialises two gates racing on the same ticket and exactly one wins. I wrote up that design in an earlier post. A chain achieves double-spend protection by having many parties agree on the order of transactions; a single-writer database achieves it by having one party, whose ordering is the only one that matters.

A signed ticket from issue to refused replay, with one writer Three lanes: the visitor's phone, the venue's API and database, and a gate. The venue issues a signed ticket to the phone. The gate scans it; the venue verifies the signature and atomically marks the row spent, admitting the visitor. A second scan of the same ticket fails the conditional update and is refused. The venue is the only lane that ever writes. Visitor's phone Venue: the one writer Gate issue: signed ticket, row status unspent present the code at the gate verify signature, set spent where unspent 1 row: admit same code again 0 rows: refuse, already used
Illustrative: the full life of a ticket with a single writer; the visitor and the gate only present and verify.

What a chain would cost you

Against those two properties, which the signed row already has, a chain adds three costs that a gate cannot afford.

Latency. Ethereum's mainnet produces a block every twelve seconds, and a write is not final for longer than that. Layer-two networks confirm faster at their sequencer, in seconds, and settle to the base layer later. A gate has about a second before a visitor starts wondering, and a conditional update on an indexed row takes a millisecond. Nothing on a chain gets close, and the usual answer, admit first and settle on chain later, means the chain is not the thing preventing the double-spend. The database is, again.

Cost per write. A chain charges for every append, in a fee that moves with demand for block space, and a venue's busiest hour is exactly when it can least afford variable cost per scan. A row in a database costs the same at nine in the morning and at noon.

A public record of who went where. A ticket on a public chain is a public record of an admission, tied to an address, forever. Most venues do not want that, most visitors do not want that, and the privacy work needed to avoid it on a chain is larger than the ticketing system it was meant to support.

Time for one write to be safe to act on, by where the write lives Horizontal bars on a logarithmic scale. A conditional update on a database row, about one millisecond. A layer-two sequencer confirmation, about two seconds. One Ethereum mainnet block, twelve seconds. The gate's budget of about one second is marked between the first two. How long before the write can be trusted Log scale, milliseconds to seconds Database row about 1 ms Layer-two sequencer seconds Ethereum mainnet block 12 s the gate's budget, about 1 s Anything to the right of the brick line admits first and records later.
Source: the twelve-second slot time from the Ethereum developer documentation; the database and layer-two figures are order-of-magnitude values stated as assumptions, and the gate budget is this post's design constraint.

The middle case, and what to keep

The two-writer case deserves its own paragraph because it is where the count most often lands in practice, and where people reach for a chain out of habit. A venue and a payment provider, a venue and a tour operator, a venue and an auditor: two parties who each write to the record and who would each like to be able to prove the other did not rewrite it. The answer there is a log that neither party can alter alone, and the cheap way to build one is to publish. Each party keeps its own database and, at intervals, publishes a hash of its log, a Merkle root over the day's entries, somewhere the other party can see and keep. Any later alteration changes the root, and the other party has the old one. That is an append-only log with a witness, it costs a few bytes a day, and it is what a chain provides for strangers at a thousand times the cost.

Which points at what the single-writer design should keep from the chain conversation, because it is not nothing. Signatures on every record, so that a copy can be verified without asking the venue. An append-only transition log rather than a mutable status column, so that the history of a ticket is a sequence of signed events and a refund is an event rather than an edit. Published hashes when a second party needs assurance. Those are the ideas that made chains interesting, and they all work in a database with one writer.

When the count says yes

The test is not an argument that chains are useless, and it is worth showing the case where it says yes, because that is what makes it a test rather than a prejudice. Suppose the ticket is resold. Now a second party, the reseller, wants to append to the record, and the venue and the reseller may distrust each other about whether a resale happened and at what price. Add a third and a fourth reseller, and a rule that the venue takes a cut of every resale, and a public market where buyers want to verify a ticket without trusting any reseller. The writer count is now many, there may be no operator all of them accept, and public verifiability is a requirement. That is the top-right cell, and a chain is a defensible answer there.

Even then, the admission itself stays a single-writer event. The gate still needs a millisecond answer, and the venue is still the only party that admits. The chain, if there is one, records ownership between admissions; the row records the admission. The two are different records with different writer counts, and confusing them is how ticketing systems end up with a chain in the critical path of a turnstile.

The rule

Before choosing where a record lives, count the parties that must append to it and would not trust each other's log. One writer means signatures and a database. Two means a shared log. Many, with no acceptable operator, means a chain. A ticket is a one-writer record, and the decision is a count, not a philosophy.

ArchitectureBlockchainTicketing
All writing

Written by Mohd Shayan

Get new posts by email

Occasional essays on engineering, AI, and building for the people technology leaves behind.

One email per new post. Unsubscribe any time.

Subscribe with RSS