Lessons Learned: On Handling Daily Api Calls Using Laravel
Lessons Learned: On Handling Daily Api Calls Using Laravel
LESSONS LEARNED I
ON HANDLING 300M+ DAILY API CALLS USING LARAVEL
NEO IGHODARO
Senior Software Engineer @ ABOUT YOU
@neoighodaro • neoi.sh
There are a lot of things you can do to improve performance on your own server
or application. Like with most things, it depends on your application. Not every thing
2
INFRASTRUCTURE
3
FRAMEWORK
1
LANGUAGE
2
INFRASTRUCTURE
3
FRAMEWORK
1
LANGUAGE
2
INFRASTRUCTURE
3
FRAMEWORK
1 LANGUAGE
KEEP YOUR PHP VERSION UPDATED
It may seem trivial but keeping PHP updated can make a lot of difference especially on
systems that have to deal with heavy loads. Each new version has typically increased the
amount of requests per second and reduced memory usage.
Source: https://phoronix.com/scan.php?page=news_item&px=PHP-7.4-Early-Benchmarks
1 LANGUAGE
OPTIMIZE PHP PROCESSES
By default, php-fpm for instance, will have a base configuration. of course this
configuration will work just fine but when under heavy loads, you might want to tweak
them for better performance.
Source: https://tideways.com/profiler/blog/an-introduction-to-php-fpm-tuning
2 INFRASTRUCTURE
OPCODE CACHING
When a new request is received in PHP here is a simple representation of what happens and
how the request is treated.
Source: https://www.programmersought.com/article/7229142807/
As seen, parsing the code will happen every time, even if the code did not change. If your code
does not change too frequently, you can benefit from opcode caching…
2 INFRASTRUCTURE
OPCODE CACHING
…once an opcode caching extension e.g OPCache is enabled, it will cache the opcode and
ensure subsequent requests do not have to be parsed. Thus resulting in faster performance.
Source: https://www.programmersought.com/article/7229142807/
2 INFRASTRUCTURE
OPCODE CACHING
'So I spun up a small DO droplet with 1 CPU and 1 GB RAM and ran Apache Benchmark. I
requested the default welcome page of Laravel 5.4 and let the benchmark run for 1 minute with
10 concurrent connections:'
Depending on how aggressive your opcache configuration is, you might need to clear the
cache after every code change. This can be a little annoying so just installing a laravel package
can help with this. After installation you can then add the artisan command to your deploy
script.
https://github.com/appstract/laravel-opcache
Varnish cache is a web application accelerator also known as caching HTTP reverse proxy. It
acts more like a middle man between your client and your web server.
Source: https://www.cloudways.com/blog/varnish-cache/
2 INFRASTRUCTURE
HTTP LAYER CACHING
1st request: GET /stuff → Web Server → PHP process → Client (200ms)
Subsequent requests: GET /stuff → Varnish Cache Hit → Client (10ms)
Source: https://www.cloudways.com/blog/varnish-cache/
2 INFRASTRUCTURE
HTTP LAYER CACHING
As with opcache earlier, we also have to clear the varnish cache whenever the responded
changes. Using a Laravel package we can do this programmatically. With the package we can
also set rules on which routes get cache and which routes don't get cache
https://github.com/spatie/laravel-varnish
Unfortunately, there are just too many things to speak about. We move.
3 FRAMEWORK
CACHE ROUTES AND CONFIGURATION FILES
Caching the route and configuration files needs to be a part of your build process if
you have one. This will remove the need for Laravel to attempt to load the
configuration every time it is referenced.
You will need to clear and cache the files again if you need to make changes.
3 FRAMEWORK
UNDERSTAND ELOQUENT
There is a lot of stuff that happens under the hood with Eloquent and understanding
some of it will help you understand when using Eloquent can be tricky.
This could already lead to high memory usage as Eloquent will create a new model
object for each of these rows. You can improve the memory footprint using
LazyCollections.
3 FRAMEWORK
UNDERSTAND ELOQUENT
!//
For every property we access in this loop, Eloquent will likely call the __get() method
to automatically get the attribute. This will begin a slew of checks, which will return a
value or maybe a relationship model.
This is extra overhead that may not be needed for this particular part of your
application and you could actually be better off just using the query builder without
Eloquent.
3
FRAMEWORK
UNDERSTAND ELOQUENT
3 FRAMEWORK
UNDERSTAND ELOQUENT: THE INFAMOUS N+1
We have probably all heard about the need to be weary of accessing relationships in
loops without eager loading them first as it can lead to N+1 queries being sent to the
database.
There are a couple of packages that can help with detecting them:
1. beyondcode/laravel-query-detector
2. barryvdh/laravel-debugbar
3 FRAMEWORK
FINDING BOTTLENECKS USING BLACKFIRE.IO
When looking for bottlenecks in your code, a good tool you can use if Blackfire. It will
help understand your code and where the most time is being spent.
3 FRAMEWORK
PREHEATING (IN-MEMORY CACHING) AND QUEUES
In-memory caches like Redis are very fast can help with storing some data that will be
used repeatedly. Preheating the known areas of the application will make those
resources super ready for when they are needed.
3 FRAMEWORK
PREHEATING (IN-MEMORY CACHING) AND QUEUES
You can also return responses before doing further processing like writing to a cache.
This can be useful because the user is only subject to the time it took that request to
be fulfilled minus the cache write time.
THANK YOU
#StaySafe