Moving to Bun, adding DataLoaders, and keeping the output byte-for-byte identical.

A GraphQL service had multi-second p99s on a handful of operations. The cause wasn't the database — it was the shape of the work: N+1 resolvers firing hundreds of round trips per request.

The fix, in three steps

  1. DataLoaders — one loader per relation, created per request, so a list of 50 items becomes one batched query instead of 50.
  2. Runtime move to Bun — faster startup and I/O, adopted only after the test suite passed unchanged.
  3. Byte-for-byte verification — replay production traffic against old and new, comparing raw response bytes. Parsed comparison hides key-order changes; byte comparison doesn't.

The lesson: performance work on a live API is a migration, not a refactor. Batch the queries, then prove clients see identical pages before you celebrate. Roll out behind a flag, watch p99 and error rate, and keep the old path one deploy away until the numbers hold.