Performance Tuning your Laravel & PHP Applications

8046fc8cd3d5444617c3d311921b2cde?s=47 David Chang
December 13, 2017

Performance Tuning your Laravel & PHP Applications

Do you find your applications have started to become sluggish over time due to software bloat? Are your APIs taking seconds to return a response? In this month's talk, David Chang from Chefs Plate will be focusing on how to get started with addressing performance issues within your applications, and will talk about lessons they've learnt while improving their average API response times from over a second to sub-200 milliseconds.

8046fc8cd3d5444617c3d311921b2cde?s=128

David Chang

December 13, 2017
Tweet

Transcript

  1. 2.

    Hello! I'm David I'm the Backend Team Lead at Chefs

    Plate. You can find me on Twitter and GitHub at @davidchchang
  2. 3.

    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
  3. 5.

    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
  4. 8.

    Speed Matters ❄ Better customer experiences ❄ Determines scalability ❄

    Build and iterate faster ❄ Slower performance means more computing resources needed = more expensive
  5. 10.

    “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
  6. 11.

    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
  7. 14.

    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?
  8. 15.

    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
  9. 16.
  10. 17.
  11. 22.

    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
  12. 24.

    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
  13. 27.

    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
  14. 28.

    Decoupling Database Tests ❄ Improve unit tests by decoupling and

    mocking database calls ❄ Don't confuse integration or API tests with unit tests
  15. 30.

    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
  16. 33.

    ❄ 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
  17. 34.
  18. 35.

    ❄ 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
  19. 36.
  20. 38.

    "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
  21. 40.

    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)
  22. 41.

    ❄ 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
  23. 43.

    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
  24. 44.

    ❄ 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
  25. 46.

    "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
  26. 47.

    Performance Testing ❄ Performance testing would be ideal to integrate

    into your CI ❄ Log ms before and after ❄ Maintain a specific level of performance
  27. 48.

    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
  28. 51.

    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
  29. 53.

    Recap Use APMs and profilers to help you identify performance

    issues Apply indexing and caching techniques & avoid expensive calls Profit! (even more than usual!)
  30. 56.

    ❄ Feb 27, 2018: Presentation TBA ❄ Apr 25, 2018:

    Video Chat with Taylor Otwell ❄ Jun 20, 2018: Workshop with Adam Wathan Upcoming Meetups