·Future of AI·4 min read·Senior engineers

I Asked Fable to Speed Up One Python Endpoint. It Out-Thought Me.

I gave Fable one unglamorous job — make a slow FastAPI route faster — and it came back with a code review I couldn't have written myself. Here's what it caught, why it surprised a 20-year engineer, and what it says about where software is heading.

I gave Fable a single, unglamorous job: "make this Python endpoint faster." One route, a few hundred milliseconds too slow. I expected a tip or two — add an index, cache something. What I got back read like a review from an engineer who'd lived in the codebase for a year. After twenty years of writing software, that's hard to admit. It found things I wouldn't have thought to look for.

The endpoint everyone has and nobody profiles

It was a FastAPI route serving a paginated list with some per-row enrichment — the kind of code every team ships and nobody profiles until it's on fire. P95 sat around 480ms. I'd already done the obvious: the handler was async, and the main filter column had an index. I pasted the function and the two helpers it called, asked Fable to optimise it, and said nothing about how.

What it caught that I'd stopped seeing

It didn't give me a tip. It gave me an ordered checklist, with the reasoning attached:

  • The N+1 I'd gone blind to. The enrichment loop awaited a per-row lookup. Async, yes — but awaited sequentially inside the loop, so 50 rows meant 50 round trips in series. It rewrote it as one IN query and a dict join. I know that pattern cold. I'd just stopped seeing it in my own code.
  • The serialization tax. I was building Pydantic models for every row only to dump them straight back to JSON, paying validation twice. It suggested model_construct for the trusted internal rows and keeping the response model lean on the hot path.
  • The connection-pool ceiling. This is the one I didn't think about. It noticed the SQLAlchemy pool was still the default size of 5, and explained that under load the endpoint would queue waiting for a connection long before the query itself was slow. It sized the pool to worker concurrency — and told me why, not just the number.
  • The thing I'd never have profiled. It questioned an await on a logging call that shipped to an external sink on every request, sitting in the critical path. Move it off-thread, fire-and-forget. Two lines. I would never have looked at logging.

480ms to 95ms

I applied four of its six suggestions. P95 dropped from ~480ms to ~95ms. The N+1 fix did most of the work; the pool size kept it flat under load instead of cliff-diving at concurrency. None of this was exotic. That's the point — the fixes weren't clever. I'd just have found maybe two of them on a good day, with a profiler open and an hour to spend.

I told it what, not how

Here's what unsettled me, in the good way. I described the outcome — faster — and nothing about the method. No "check for N+1," no "look at the pool." It assembled the checklist itself, in the right order, with the trade-offs spelled out. That's the shift I keep coming back to: you state the goal, and the model brings a breadth of attention you can't physically hold in your own head at 4pm on a Friday.

And it points somewhere bigger. If a model can audit one endpoint this thoroughly in seconds, then "thorough" stops being a budget decision. We tolerate bugs because careful review is expensive and humans get tired. Fable doesn't. I think we're walking toward software iterated to near-perfection — not because engineers suddenly got better, but because the cost of one more careful pass fell to almost nothing. Bugs become a choice, not an inevitability.

Where I still don't trust it

When you can't verify the result. Every change here was one I could read, reason about, and benchmark. Fable found the suspects; I still confirmed the convictions. The day I stop doing that is the day I ship its mistakes with confidence.

But the reflex has flipped. I used to optimise by intuition and reach for a profiler when intuition ran dry. Now my first move is to ask, then verify. It out-thinks me on breadth. I'm still the one who decides what "better" means — and that, increasingly, is the whole job.

share:XLinkedIn