Backend development

How we sped up our Laravel API fivefold

Ruslan Ismailov Published Updated 9 min read
H

Where to start with optimization

Optimization should always start with measurements, not guesses. Before changing any code, we profiled real requests and found that 80% of the response time was spent on database access, not on business logic. So our first target was exactly the work with data.

Fighting the N+1 problem

The most common cause of slow endpoints turned out to be the N+1 problem: for a list of a hundred entities, more than a hundred additional queries to relations were executed. Eager loading via with() reduced this to a few queries.

What exactly we changed

  • Added eager loading for all relations used in the response resources.
  • Enabled protection against lazy loading in the development environment to catch N+1 at early stages.
  • Moved heavy aggregates into separate optimized queries.

Caching hot data

We moved rarely changing reference data and heavy queries into Redis with thought-out event-based invalidation. This removed a significant part of the load from PostgreSQL and stabilized latency under peak traffic.

Resident mode

The final step was running the application in resident mode, which removed the overhead of cold framework initialization on every request. Together, all the measures gave a fivefold speedup of the average response time.

Conclusion

A systematic approach — measure, find the bottleneck, fix it and measure again — allowed us to achieve a multiple speedup without rewriting the application. The main lesson: optimize based on profiling data, not intuition.

Technologies

Tags

Ruslan Ismailov

Senior Web / Backend Developer. Senior web/backend developer with 9 years of experience. Stack: PHP, Laravel, PostgreSQL, Redis, Docker, Kubernetes, REST, microservices, CI/CD. More about me →