Reliability · Operations

The venue table that cannot take one more column

A per-venue setting is the most natural thing to add as a column on the venues table — until the table hits the database’s limit and the change can never be applied. What we found at exactly one hundred, and the pattern that replaces it.


Every venue in a food hall has settings: its name and address, its opening hours, its colour scheme, whether it takes collection orders, how it offers a tip. The obvious place for each of those is a column on the venues table. Add a column, write a migration, ship. We did that a hundred times.

Literally a hundred. The database this system runs on allows a table one hundred columns, and the venues table stood at exactly that when a migration to add the tipping setting failed with a message nobody had seen before: too many columns. It failed locally, which is where it should fail. Had it gone straight to production it would have failed there identically, because production carries the same hundred.

Why the ceiling was already showing

The same limit had bitten once before, from the other side. A query that reads the whole venue row plus a handful of derived figures had crossed a hundred columns in its result and been refused, and had been split into two reads. That was recorded as a quirk of one endpoint. It was the first sign of a structural fact: the table was full, and the next setting anybody added would have nowhere to go.

The pattern that replaces it

A per-venue setting now gets its own small table, keyed by the venue: one row per venue, present only when the venue has set something, absent meaning "the defaults". Several settings already lived that way — tipping, review links, counter adjustments — so the pattern was there to follow rather than invent. The venues table stays what it is, and the rule is written where the next person will read it: never a new column on that table, always a side table.

The general lesson is about the difference between a limit you have read about and a limit you have hit. The first is a fact in a document. The second changes how every future change is designed, and the only way to make it stick is to write it into the place where designs get made — in this case, the working instructions the next migration is written from.


Try it on tonight’s service.

Nothing to install, no card. Not better by the weekend? Close the tab.