Slide 1

Slide 1 text

2017.12.13 Laravel TO

Slide 2

Slide 2 text

Hello! I'm David I'm the Backend Team Lead at Chefs Plate. You can find me on Twitter and GitHub at @davidchchang

Slide 3

Slide 3 text

We're Hiring (Intermediate/Senior) Front-End Developer Data Engineer Product Owner - Mobile IT Administrator Plus many more! Check out https://www.chefsplate.com/careers

Slide 4

Slide 4 text

Optimizing PHP Application Performance

Slide 5

Slide 5 text

Performance Checklist ❄ Why performance matters ❄ Identifying performance issues ☆ Finding the culprit (with profiling) ❄ Tackling root causes: ☆ Slow database queries ☆ Caching non-performant results ☆ Expensive function calls and operations ❄ Improving testing and development processes

Slide 6

Slide 6 text

Why Performance Matters

Slide 7

Slide 7 text

Why Performance Matters

Slide 8

Slide 8 text

Speed Matters ❄ Better customer experiences ❄ Determines scalability ❄ Build and iterate faster ❄ Slower performance means more computing resources needed = more expensive

Slide 9

Slide 9 text

Identifying Performance Issues First step: realizing you have a problem

Slide 10

Slide 10 text

“I'm not a real programmer. I throw together things until it works then I move on. The real programmers will say: “Yeah, it works but you're leaking memory everywhere. Perhaps we should fix that". I'll just restart Apache every 10 requests.” - Rasmus Lerdorf

Slide 11

Slide 11 text

80:20 rule (more like 95:5) ❄ Most of the times, 5-10% of your code base is causing 95%+ of your performance issues ❄ Performance dips tend to be tied to code releases ❄ Sometimes massive traffic can reveal infrastructure inadequacies

Slide 12

Slide 12 text

Finding the Culprit Determine where the non-performant code is coming from "Knowing where to tap"

Slide 13

Slide 13 text

Knowing where to tap

Slide 14

Slide 14 text

Questions to Ask ❄ How long do your pages take to load? ❄ Is every request slow? ☆ What are your most frequently-used pages and endpoints? ☆ Is there any code in common across those pages? ❄ Did we release something recently that caused the slowdown?

Slide 15

Slide 15 text

Cue: Application Performance Monitoring ❄ APMs like New Relic and Datadog help to reveal underlying performance issues ❄ View high level performance metrics with enough granularity of specific issues ❄ Can define thresholds for acceptable performance and set up monitoring notifications to get notified when application performance degrades

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Track execution times with chefsplate/php-profiler!

Slide 19

Slide 19 text

Example usage of chefsplate/php-profiler

Slide 20

Slide 20 text

When It's Not Your Code ❄ It could be an infrastructure issue

Slide 21

Slide 21 text

Slow DB Queries Majority of taps

Slide 22

Slide 22 text

Creating Database Indexes ❄ Look-ups and queries perform dramatically faster with the right indexes ❄ Look at what is frequently accessed in your queries ❄ There are some caveats: ☆ Don't index everything ☆ Order of indexes can matter as well

Slide 23

Slide 23 text

Adding a database index usually improves query performance Source: CodeProject, Benchmarking with indexed views

Slide 24

Slide 24 text

Offloading to the Database ❄ Offload as much of the application code back to the database wherever possible ❄ Don't fetch objects into PHP and parse/populate them when you can do it straight in the DB ❄ Utilize built-in aggregation and reporting frameworks if available

Slide 25

Slide 25 text

20,000+ milliseconds!!

Slide 26

Slide 26 text

Offloading reporting logic from PHP to Mongo aggregations

Slide 27

Slide 27 text

Create-if-not-exists Queries ❄ Generating random unique numbers can be expensive on larger tables/collections ☆ One solution: Retryable writes with unique indexes will throw errors; catch exceptions instead of querying for matches

Slide 28

Slide 28 text

Decoupling Database Tests ❄ Improve unit tests by decoupling and mocking database calls ❄ Don't confuse integration or API tests with unit tests

Slide 29

Slide 29 text

Caching For frequently accessed content

Slide 30

Slide 30 text

Caching Guidelines ❄ Cache frequently accessed content ☆ Especially if the content doesn't change often ❄ Useful for "aggregated" content ☆ e.g. content that requires multiple DB queries to assemble ❄ Always provide a fallback in case caching fails ❄ Make sure to wrap appropriate exception handling logic around your cache calls

Slide 31

Slide 31 text

Using the Laravel cache + fallback to populate

Slide 32

Slide 32 text

Cache entire Laravel responses with Spatie's response cache package

Slide 33

Slide 33 text

❄ Great for caching entire responses ☆ Considers input parameters when caching ❄ Caching on a per-endpoint basis ❄ Not too much flexibility in busting caches ☆ All-or-nothing approach Spatie Response Cache

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

❄ Save calls to the database for commonly accessed immutable data ❄ Only first call to a singleton entity should incur a performance hit ❄ Retrieve further entities from memory directly ❄ Similar to APC cache Singleton Entities

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Expensive Calls Not all function calls are made equal

Slide 38

Slide 38 text

"Performance problems in ecommerce are almost always due to making too many calls rather than the response time of any given call." — Kelly Goetsch, eCommerce in the Cloud

Slide 39

Slide 39 text

Host-to-host communication is expensive Source: Geeks Hangout, The OSI Model

Slide 40

Slide 40 text

Start Low Level ❄ Start from the bottom and then work your way up ☆ Database ☆ Laravel MVC Framework ■ Data/persistence layer (with Eloquent ORM/Doctrine ODM) ■ Domain layer (models) ■ Middleware ■ Controllers ☆ Templates and Views (Frontend)

Slide 41

Slide 41 text

❄ Improve performance by serving up assets closer to your user base ❄ Reduce load on your web servers ❄ Automatic mobile image optimizations ❄ Leverage gains from GZIP compression and HTTP/2 server push Content Delivery Networks

Slide 42

Slide 42 text

Performance gains from using Cloudflare CDN

Slide 43

Slide 43 text

Some Things We've Tried ❄ Swapping out Hash::check bcrypt calls with native SHA1 hashing via hash() ☆ Hashing operation went from 192ms to 4ms ❄ Enabling APCu caching for Doctrine metadata: ☆ Saved ~60ms per request

Slide 44

Slide 44 text

❄ Replacing splat type-hints (Class … $val) syntax with plain array setting ☆ This ended up being 3X faster ❄ Removing magic setters and getters ☆ ~0.0009ms - not worth it! Some Things We've Tried

Slide 45

Slide 45 text

Testing & Dev Processes Other areas for optimizations

Slide 46

Slide 46 text

"Only conducting performance testing at the conclusion of system or functional testing is like conducting a diagnostic blood test on a patient who is already dead." — Scott Barber

Slide 47

Slide 47 text

Performance Testing ❄ Performance testing would be ideal to integrate into your CI ❄ Log ms before and after ❄ Maintain a specific level of performance

Slide 48

Slide 48 text

Speeding Up your Testing ❄ Extract out your database calls ❄ Mock expensive or difficult to reproduce calls (esp. third party) ❄ Run tests in parallel ❄ Build in performance into your development considerations ☆ Overall speed up of your CI process

Slide 49

Slide 49 text

Improve testing performance with Paratest

Slide 50

Slide 50 text

Save your life with hirak/prestissimo

Slide 51

Slide 51 text

Save your Life with prestissimo ❄ Makes composer installs at least ten times faster ❄ Just type: composer global require hirak/prestissimo ☆ There's no turning back ❄ Our installs went from 15+ minutes to 17 seconds ❄ TODO: Buy this guy a beer

Slide 52

Slide 52 text

There's no turning back once installed

Slide 53

Slide 53 text

Recap Use APMs and profilers to help you identify performance issues Apply indexing and caching techniques & avoid expensive calls Profit! (even more than usual!)

Slide 54

Slide 54 text

Thanks! Questions?

Slide 55

Slide 55 text

Happy Holidays and a Happy New Year! From your @LaravelTO friends

Slide 56

Slide 56 text

❄ Feb 27, 2018: Presentation TBA ❄ Apr 25, 2018: Video Chat with Taylor Otwell ❄ Jun 20, 2018: Workshop with Adam Wathan Upcoming Meetups