Skip to content

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.

Scope and terms

Engagement model
Fixed scope, agreed in writing before work starts. Not a day rate against an open backlog.
Price and timeline
Both are set per project, once the scope is. Quoted together, before anything is built.
What we need from you
One person who can approve decisions, and access to your repository and issue tracker.
Not included
Anything outside the agreed scope. It becomes its own scope rather than a variation order.
Third-party costs
Hosting, licences, API fees and SaaS subscriptions are contracted and paid by you.
Invoicing
Codefacture Yazılım A.Ş., Türkiye. EUR, USD or GBP by bank transfer, with no Turkish VAT on exported services.

Frequently asked questions

Will Octane fix our performance problem?
Probably not, and it may hide it. Octane removes framework boot time from each request, which is real but rarely the dominant cost in a slow application. If the request spends 800ms in the database, booting faster saves you 30ms and introduces state that persists between requests. We measure before recommending it.
Should we just add more servers?
Sometimes - horizontal scale is a legitimate answer when the application is efficient and the traffic is simply large. It is the wrong answer when one endpoint issues four hundred queries, because you are then buying four hundred queries in parallel. The measurement tells you which situation you are in.
How do you measure without slowing production down?
Sampling. Application performance monitoring at a low sample rate, the slow query log with a sensible threshold, and the queue metrics you already have. Where none of that exists, installing it is the first deliverable - optimising against a laptop is how teams fix things that were never slow.
What if the bottleneck is a third party?
Then that is the finding, and it changes the work from optimisation to isolation - the call moves to a queue, a timeout is set that is shorter than your patience, and a failure of theirs stops being an outage of yours.
Call us+1 848 272 7583WhatsApp+90 850 308 5436Emailinfo@codefacture.comContact page