polycratia

The compliance team kept telling me the moderation queue felt slower every month, and nothing in the data explained it.

Same table, same filters, roughly the same count of pending items. One page took about three seconds to come back.

The permission check ran per row. Every item asked the access layer whether this operator could see it, whether they could act on it, whether their issuance tier covered it. A page of items meant a resolution per item, each one walking roles and permissions. So latency tracked page size and the number of roles in the system, not the amount of data. That is why it crept up so quietly: every new role made every list a little slower.

Caching was not the fix. I resolved the operator's effective permission set once per request, then expressed it as a predicate the query itself could apply. Rows the operator couldn't act on never left the database. Same endpoint, around two hundred milliseconds.

What that had been costing: moderators kept shrinking their page size to keep the screen usable, which made the queue look shorter than it was and pushed real review work out of view. A performance problem had turned into a compliance blind spot.

What I do differently now: when an endpoint is slow, I check first whether latency scales with page size. If it does, the work is per row, and no index will rescue it. Authorization is where I find it most often, probably because it looks like a cheap in-memory call right up until it stops being one.

I write up more of these in long form here: https://polycratia.com/c/53e6c9eb

Worth knowing where your authorization actually runs: inside the query, or per row after the rows come back...

react

$ new-project --brief

or email hey@polycratia.com