polycratia

A broker told me opening a deal took about three seconds. I assumed the database was at fault. The database turned out to be the cheap part.

This was an aircraft transaction platform. A deal carries listing data, broker roles, deposit state, compliance checks, and every signed document it picked up on the way to closing. One endpoint returned all of it, because years earlier one screen needed all of it.

When I traced a real request, query time was a small slice. The rest went into serializing a deeply nested object graph, then fetching file metadata one document at a time. So response time scaled with how far along the deal was. The oldest deals, the most advanced and most valuable ones, were the slowest in the system. That bothered me more than the three seconds did.

So I didn't optimize the endpoint. I asked what each screen actually reads. The list view needed a handful of fields. The documents tab needed documents and nothing else. The closing checklist needed state, not file bytes. Split by consumer, batch the metadata lookups, and the common path lands around 200ms.

The cost was finding out who else depended on the fat response. I kept the old shape alive for a release cycle and logged its callers before removing it: an older mobile build showed up there, which I would not have guessed from reading the code.

What I do differently now: when an endpoint gets slow, I count how many different questions it is answering first. Field lists have no owner, so endpoints accumulate fields the way those deals accumulate documents, and nobody notices until latency grows with the data.

If you've split an endpoint by consumer: how did you work out who was still on the old response shape?

react

$ new-project --brief

or email hey@polycratia.com