Application performance engineering
Laravel Performance & Scaling
Applications that hold under load - measured from production rather than a laptop, fixed at the cause, and defended by budgets in CI so the numbers stay fixed.
Performance work has a predictable ending. A sprint goes into optimisation, the graphs come down, and a month and a half later they are sitting exactly where they started. The fixes were not wrong. Nothing was holding them in place.
How an engagement runs
Measure first, from production. Real traffic, sampled, segmented by endpoint. A p95 of 2.4 seconds on the order listing is an actionable statement; "the app feels slow" is not, and neither is a profile taken on a developer machine against a seeded database.
Find the cause, not the symptom. A slow endpoint in Laravel is nearly always one of five things: the query count, a single query with no usable index, work that should have been queued, a third-party call in the request path, or serialisation of far more data than the response needs. We trace each one to the line that produced it.
Fix at the right level. Moving work into a job, adding the index the query plan actually wants, eager-loading the relation, replacing a collection pipeline with an aggregate, caching a value whose cost genuinely justifies the invalidation problem it creates. These are the changes that hold.
Defend the result. A budget in CI: a query-count assertion on the endpoints that matter, and a failing build for the pull request that exceeds it. The budget is the deliverable; the graph is a side effect.
Why the graph comes back
Because a graph is an outcome and nobody owns an outcome. A budget is a number in a test, checked by a machine, on every pull request, and it fails the build of whoever exceeded it while they still remember what they changed.
That is why most clients never need us a second time for this. Optimising without a budget is borrowing against the next quarter: the same relation quietly loses its eager load, the same report gains one more column that turns out to be an accessor with a query behind it, and the regression arrives one reasonable commit at a time, from people with no way of knowing.
Where the time actually goes
Ranked by how often it is the answer:
The database. Usually the query count rather than any single query - which is why it is its own engagement when it is the whole problem rather than part of one.
Work that should not be in the request. A PDF rendered, an image resized, a webhook delivered, a report generated. Every one of those belongs in a queue, and moving them is usually the single largest improvement available.
A third party in the critical path. An address lookup, a tax service, a payment provider's status call. Their latency is your latency, their outage is your outage, and neither is visible in your own profiling until you look for it.
Serialisation. An endpoint returning two hundred fields because the resource was written as "everything on the model", hydrating relations to produce a list of names.
Cache used as a plaster. Caching is not free - it buys speed with staleness, and an application with a dozen unrelated cache keys and no invalidation strategy has traded a performance problem for a correctness one.
Scaling, once it is efficient
Only then is infrastructure the answer, and the order matters: an inefficient application scaled horizontally is an inefficient application you pay for several times.
When it is warranted, the work is read replicas with the routing decided explicitly rather than globally, session and cache stores that are not the primary database, queue workers scaled separately from web capacity because they fail differently, and a deployment that does not drop in-flight work. Octane where the measurement says framework boot is actually a meaningful share of the request, which is less often than its reputation suggests.
What you receive
A prioritised findings document with each issue traced to its cause and sized by effort, the implemented fixes as reviewable pull requests, the CI budget configuration, and a before/after comparison against production traffic once the change has been live long enough to mean something.
Where the ceiling turns out to be the architecture itself - which happens - the findings say so, and put a number on the alternative beside it. That is a conversation to have in week one, not in the closing summary.
