I am working with a pretty heavy Laravel site with many requests and lots of Eloquent/SQL calls. Even though the high-memory and high-cpu VPS, I felt there is room for performance improvement. That is why I would like to write out some improvements to speed up Laravel:
1. Use Database or Redis for cache and sessions
When you navigate to config/cache.php and config/session.php, you see that the default CACHE_DRIVER and SESSION_DRIVER = file. If you have Redis installed, just try to set it as a cache and session driver. Check if Redis is installed by running:
If it is installed, try to define the drivers in your .env file:
2. Use several artisan pre-made commands
There are various artisan commands that are made to cache several parts of Laravel. You can configure them in the deployment process of Laravel Forge or Envoyer:
php artisan route:cache
php artisan config:cache
php artisan optimize --force
Use Developer tools guideline
Do a run at https://developers.google.com/web/fundamentals/performance/ and optimize several steps:
3. Optimize images like PNGs and JPEGs
Images sometime possess useless extra data that can be lossless optimized. Therefore you can use the packages OptiPNG and JPEGOptim. In Ubuntu install OptiPNG:
sudo apt-get update
sudo apt-get install optipng
And also install JPEGOptim:
sudo apt-get install jpegoptim
Now navigate to the folder that you would like to optimize its images. For optipng run:
For jpegoptim run:
for i in *.jpg; do jpegoptim --all-progressive "$i"; done
Note that also the subdirectories might be optimized
4. Use HTTP2 instead of HTTP 1.1 if you have an SSL certificate enabled
The following guideline helps you through the process of updating to HTTP2 in Nginx.
Note that you need to have a SSL certificate. Google PageSpeed gave a server speed change from 0.52s (without HTTP2, with SSL) to 0.35s (with HTTP2)
Result: About 30% speed increase
5. Cache response in Redis or File
Sometimes it is unnecessary that the page is called from a database many times. Just caching the page reduces quite some load. That is exactly the same idea of the Laravel Response Cache plugin. The install instructions are quite good. In my case it had a drastic performance improvement.
Result: about 200 ms speed increase in my case
6. Optimize InnoDB innodb_buffer_pool_size
I am not sure why, but for some reason InnoDB has a really small innodb_buffer_pool_size when deploying your initial Laravel Forge server. In my default case, the innodb_buffer_pool_size was 8MB, while some blogs estimate that you can reserve up to 80% of your ram for innodb_buffer_pool_size. So edit the my.conf file:
sudo nano /etc/mysql/my.cnf
And add for example:
innodb_buffer_pool_size = 1G
Result: Several times faster queries
7. Reduce load by adding swap
My server regularly had Redis full-memory issues and high loads. This was solved by adding some swap to Ubuntu. As described by DigitalOcean:
One of the easiest way of increasing the responsiveness of your server and guarding against out of memory errors in your applications is to add some swap space. Swap is an area on a hard drive that has been designated as a place where the operating system can temporarily store data that it can no longer hold in RAM.
Read more about adding swap at the DigitalOcean website.
Result: a reduction in load when entering the ‘top’ command
8. Using Eager Loading instead of Lazy Loading
When using Laravel Eloquent models with relations it’s tempting to use ‘lazy loading’. That is a way of getting relational models in a loop. E.g.:
$blog = Blog::all();
foreach ($blogs as $blog)
In this way, foreach blog the comments will be loaded in separate queries. When using Eager loading, the comments would be loaded in ONE IN query:
$blog = Blog::with('comments')->get();
foreach ($blogs as $blog)
Read more about Eager Loading on Laravel’s documentation.
How to find queries that may need optimization?
Don’t know how to find queries that might need some optimization? E.g. that might need eager loading instead of lazy loading? The easiest way is to install and enable Laravel Debugbar on your development server. With this toolbar you can view the queries per page. If you see lots of queries that could have been simplified with a simple join or in-query, you know it’s your queue to optimize that script with eager loading.
Result: Each query saved, couple of milliseconds per query
This list is still a work-in-progress list, although above tips gave me a speed improvement of MORE THAN 1 SECOND. Got any tips, let me know in the comments!
Also share your speed improvements 🙂