Slide 1

Slide 1 text

LESSONS LEARNED ON HANDLING 300M+ DAILY API CALLS USING LARAVEL SOME I

Slide 2

Slide 2 text

NEO IGHODARO Senior Software Engineer @ ABOUT YOU @neoighodaro neoi.sh •

Slide 3

Slide 3 text

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 in this talk will be applicable to you.

Slide 4

Slide 4 text

1 2 3 LANGUAGE INFRASTRUCTURE FRAMEWORK

Slide 5

Slide 5 text

1 2 3 LANGUAGE INFRASTRUCTURE FRAMEWORK

Slide 6

Slide 6 text

1 2 3 LANGUAGE INFRASTRUCTURE FRAMEWORK

Slide 7

Slide 7 text

1LANGUAGE 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. KEEP YOUR PHP VERSION UPDATED Source: https://phoronix.com/scan.php?page=news_item&px=PHP-7.4-Early-Benchmarks

Slide 8

Slide 8 text

1LANGUAGE 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

Slide 9

Slide 9 text

Source: https://www.programmersought.com/article/7229142807/ 2 INFRASTRUCTURE When a new request is received in PHP here is a simple representation of what happens and how the request is treated. OPCODE CACHING 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…

Slide 10

Slide 10 text

Source: https://www.programmersought.com/article/7229142807/ 2 INFRASTRUCTURE …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. OPCODE CACHING

Slide 11

Slide 11 text

2 INFRASTRUCTURE '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:' OPcache disabled: 10.18 requests per second Enabled with default values: 34.52 requests per second Enabled with optimized values: 42.53 requests per second OPCODE CACHING Source: Olav van Schie https://medium.com/appstract/make-your-laravel-app-fly-with-php-opcache-9948db2a5f93

Slide 12

Slide 12 text

2 INFRASTRUCTURE 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 OPCODE CACHING $ composer require appstract/laravel-opcache $ php artisan opcache:clear

Slide 13

Slide 13 text

Source: https://www.cloudways.com/blog/varnish-cache/ 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. 2 INFRASTRUCTURE HTTP LAYER CACHING

Slide 14

Slide 14 text

Source: https://www.cloudways.com/blog/varnish-cache/ 1st request: GET /stuff → Web Server → PHP process → Client (200ms) Subsequent requests: GET /stuff → Varnish Cache Hit → Client (10ms) 2 INFRASTRUCTURE HTTP LAYER CACHING

Slide 15

Slide 15 text

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 $ composer require spatie/laravel-varnish $ php artisan varnish:flush

Slide 16

Slide 16 text

Some other things you can do: 2 INFRASTRUCTURE HONORABLE MENTIONS • Database Optimisation – https://www.cloudways.com/blog/mysql-performance-tuning/ • Web Server Optimisation – https://www.nginx.com/blog/tuning-nginx/ • High Read/Write Storage • Load Balancing • More… Unfortunately, there are just too many things to speak about. We move.

Slide 17

Slide 17 text

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.

Slide 18

Slide 18 text

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. !// ~500,000 models in total $cars = Car!::with(‘dealerships’)!->where(‘name’, ‘Benz’)!->get(); 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.

Slide 19

Slide 19 text

3 FRAMEWORK UNDERSTAND ELOQUENT When you let’s say loop through the entries… 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. foreach ($cars as $car) { !// }

Slide 20

Slide 20 text

3 FRAMEWORK UNDERSTAND ELOQUENT

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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.

Slide 23

Slide 23 text

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.

Slide 24

Slide 24 text

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.

Slide 25

Slide 25 text

THANK YOU #StaySafe