All articles
Laravel 11 min readFebruary 12, 2025

Laravel at Scale: Patterns That Hold Up

What changes when a Laravel application crosses from a few hundred requests per second into the thousands — and the Eloquent advice that quietly stops working.

LaravelPHPPerformanceQueues

Most Laravel performance advice optimizes the wrong thing. Eloquent is rarely the bottleneck; the architecture around it usually is. Once you cross a few hundred requests per second, the same questions come up on every engagement — and the answers look more like distributed-systems advice than framework tips.

Where the time actually goes

  • Synchronous external calls in request handlers (payment, email, S3 uploads).
  • N+1 queries hidden behind innocent-looking accessors.
  • Global model events firing cross-aggregate writes nobody can trace.
  • Cache stampedes on cold deploys because nothing is warmed.

The shape that holds up

Push writes through queues. Materialize reads through projections. Treat the database as a system of record, not a working set. Wrap every external call in a dedicated service with a timeout, a circuit breaker, and a fallback that is honest about what it cannot do.

php
// Bad: synchronous in the request lifecycle Mail::to($user)->send(new WelcomeMail($user)); // Good: queue it, observe it, retry it Mail::to($user)->queue((new WelcomeMail($user)) ->onQueue('transactional') ->afterCommit());

Read replicas are not optional

Adopt a read replica strategy early. Route reporting and search to replicas. Keep transactional reads on the primary, and be explicit in code about which connection you expect.

None of this is exotic. It is the boring middle of the codebase that decides whether the framework keeps its promises at scale.

About the author

Md Arifur Rahman is a Senior Software Engineer, Systems Architect, and Cyber Security professional with 8+ years building production-grade platforms across fintech, government, and enterprise SaaS.