DEV Community

HakamRaza
HakamRaza

Posted on

[Laravel] Solving Bottleneck in Laravel.

Intro

  • this is based on my experience in solving bottlenecks in Laravel projects hosted in AWS EC2. Most of this is simple steps that can be taken on the dot.
  • this will not cover everything, but at least give you some solutions that maybe useful.

Memory Bottleneck

  • Scaling your server vertically may not be the solution.
  • There maybe a situation when your project running slow, but the EC2 CPU% chart is still showing below 50%. Then, it is time to check your server memory. You see, EC2 does not monitor your memory (RAM) usage by default.
  • EC2 also does not 'shared' your memory to another EC2 although behind the same load balancer. i.e, a process can only be compute in one server that execute it. This is an issue if you load everything (eg: User::all()) into memory.
  • you usually only able to check memory available by using command inside the ec2 itself:
cat /proc/meminfo | grep Mem
Enter fullscreen mode Exit fullscreen mode
  • Try to estimate the memory you needed and scale appropriately:

1 php-fpm process size: ~ 40mb - max 80mb RAM
1 queue worker running: ~ 140mb RAM
Standard laravel process: ~ 2mb - 16mb RAM


Database Bottleneck

  • although there is automated server auto-scaling, there is none for AWS RDS, which require manual scaling/upgrade.
  • new spawn server means additional connection to your DB.
  • Amount of connection a DB can handle mainly depend on the amount of RAM the DB has.
  • Any RDS upgrade/scaling operations require 30 mins DB down time. Which means you cannot access your DB during this time.
  • Estimate appropriately, for example a db.t3.large (8GB) can handle up to 600 connections
  • RDS Monitoring tools can be use to monitor CPU usage, query depth and so on.
  • Other steps that can be taken includes:
  1. Index columns with frequent filter / querying / joining
  2. Using aggregate tables (for aggregate summary) instead of query multiple tables for multiple aggregate metrics
  3. Using aggregate function such as withCount to get directly the count instead of loading the whole relationship children.
  4. Read and write using separate database that syncing
  5. Cache common and frequent queries such as list of countries, phone codes, etc.

Application Improvement

  1. Select only columns required to reduce memory consumption
  2. Use eager load moderately as not everything are actually needed on the same time. Utilize lazy loading instead, where for additional information, forward user to another page (new request) instead of eager loading all at once.
  3. Using raw queries instead of eloquent maybe a hassle but that depending on what information you want to fetch. Raw queries use less memory due to no need to load additional methods or properties come with eloquent
  4. Utilize jobs for faster response (depend on your design) and control your application compute and memory consumption when executing something.

Top comments (0)