Engineering · Performance · Operations

Three hops on a wire costing two seconds each

One screen took five seconds, and two of them were a single trip to the database. We cannot shorten the wire. We can stop crossing it three times in a row.


At lunchtime one screen went to the top of the board by a distance: the menu tags page, six loads, five seconds on average, nine at worst. One call. Nearly four seconds of it inside the server. We know what one trip from the server to the database costs on every request, because the gate that checks who you are makes exactly one, and on this screen that one trip read 1.9 seconds.

That morning the same trip had read a tenth of a second. The code had not changed. The route had not changed. Somewhere between the owner's browser and the database, the wire had got slow, and every number on the board that afternoon was that wire multiplied by however many times a screen crossed it.

What code can and cannot move

Nothing we deploy shortens a wire. Where the owner was, what his connection was doing, which path his requests took to a database three thousand miles away: none of that is ours to change from a route file. What a route file does decide is how many times it crosses that wire before answering, and this one crossed it three times in a row.

First it read the venue. Then it read the venue's dishes. Then it took the dish ids that came back and asked for their ingredients' allergen states, handing the database a list it had just been given by the database. The first two reads were both keyed on the venue id in the address. The third was keyed on the second's answer, but only in form: the database can select those ids itself in the same statement, as a subquery, and never needed them handed back.

One

All three now run as one wave. The venue check still happens before anything is built or returned, so a venue the caller may not see is still refused; the reads for it simply run alongside the row that says no and are thrown away. The test counts three statements and one wait, and pins what the chain produced: two visible dishes in section order and the hidden one absent, a burger told it contains gluten and may contain milk because its bun does and its patty does not, a slaw with no recipe behind it marked so and told nothing, and the right refusals for another company's venue, a venue that does not exist, and no venue at all.

Two of the test's first seeds were wrong, which is worth saying. One put the venue inside a company, and a platform account is correctly refused a venue that belongs to anyone. One wrote allergen states as yes and no, and the vocabulary is contains, may and free, so the suggestion came back empty. Both times the code was right and the test was wrong, and both times the honest move was to fix the test.

What that afternoon still looked like

Slow. One hop on a two-second wire is two seconds, and the rest of the five was the wire too. We are not claiming the screen was fast by teatime. On an ordinary ninety millisecond hop the route goes from about 270 milliseconds to about 90, and that is the part that was ours to change. The structural answer to the wire itself, a database copy closer to the UK, is on the owner's list and is not a route fix.

For anyone running a floor

When the supplier's van is stuck in traffic, you cannot make the traffic move. You can make sure you ordered everything in one delivery rather than three. Separate the delay you own from the delay you do not, fix the one, and say plainly that the other is still there.


Try it on tonight’s service.

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