From a146b39eef94de8b7f0683a085e976902b87d61a Mon Sep 17 00:00:00 2001 From: Tommy Parnell Date: Wed, 13 Apr 2022 21:00:42 -0400 Subject: [PATCH] hosting craft on heroku --- .../Posts/Hosting-craft-on-heroku.md | 6 +-- .../Posts/Speeding-up-CraftCMS-on-Heroku.md | 50 ++++++++++++++++++ .../img/Speeding-up-CraftCMS-on-Heroku/.keep | 0 .../img/Speeding-up-CraftCMS-on-Heroku/1.png | Bin 0 -> 15662 bytes .../Speeding-up-CraftCMS-on-Heroku/1.png.webp | Bin 0 -> 12492 bytes 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 src/TerribleDev.Blog.Web/Posts/Speeding-up-CraftCMS-on-Heroku.md create mode 100644 src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/.keep create mode 100644 src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/1.png create mode 100644 src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/1.png.webp diff --git a/src/TerribleDev.Blog.Web/Posts/Hosting-craft-on-heroku.md b/src/TerribleDev.Blog.Web/Posts/Hosting-craft-on-heroku.md index c1ce257..af8a35b 100644 --- a/src/TerribleDev.Blog.Web/Posts/Hosting-craft-on-heroku.md +++ b/src/TerribleDev.Blog.Web/Posts/Hosting-craft-on-heroku.md @@ -88,13 +88,13 @@ In our case, the button didn't provide any support for uploaded files. We went f Heroku requires a Procfile to launch apps. -``` +```shell web: vendor/bin/heroku-php-nginx -C nginx_app.conf web worker: ./craft queue/listen --verbose release: ./bin/release.sh ``` `release.sh` will run a db migration -```sh +```shell if /usr/bin/env php /app/craft install/check then /usr/bin/env php /app/craft up --interactive=0 @@ -103,7 +103,7 @@ fi A `nginx_app.conf` nginx config for heroku's php buildpack. -```conf +```nginx if ($http_x_forwarded_proto != "https") { return 301 https://$host$request_uri; } diff --git a/src/TerribleDev.Blog.Web/Posts/Speeding-up-CraftCMS-on-Heroku.md b/src/TerribleDev.Blog.Web/Posts/Speeding-up-CraftCMS-on-Heroku.md new file mode 100644 index 0000000..2f3556b --- /dev/null +++ b/src/TerribleDev.Blog.Web/Posts/Speeding-up-CraftCMS-on-Heroku.md @@ -0,0 +1,50 @@ +title: Speeding up CraftCMS on Heroku +date: 2022-04-13 07:55 +tags: +- nginx +- craftcms +- craft +--- + +So, I previously [blogged about how we hosted CraftCMS](/Hosting-craft-on-heroku/) on Heroku. When we built the marketing site for [Quala](https://www.quala.io) the twig templates were built for maximum authoring flexibility at the cost of some TTFB problems. We knew this going into the project. In an ideal world we would use GatsbyJS to build the frontend, but we very limited in time. When we went live, we saw a dramatic improvement to First Contentful paint, but a huge decrease to Time To First Byte, averaging at 1.3 seconds. + + + +The initial thinking that was bounced around was *we just need caching* as our previous wordpress site had cached all renderings in memory. However, we wanted to start rendering CSRF tokens to the browser, and collecting form data. Furthermore, I struggled to come to terms with this being a solution. Simply put, I'm not a fan of PHP, and I know that the Yii framework is known to be slow even in the PHP community, but I couldn't believe that it should be *that* slow. We did sprinkle some cache tags around our twig templates, and it did improve things, but not enough to brag about. So I started digging into the docs of Heroku, Nginx, and FastCGI. + +## Heroku's buildpack + +So [Heroku's buildpack docs](https://devcenter.heroku.com/articles/php-support#php-fpm-configuration) contains a lot of very good information. Props to them for docs! I ran into this one quote. + +> PHP-FPM is set up to automatically spawn a suitable number of worker processes depending on dyno size and the configured PHP memory_limit + +This made me go look at another article I found by them regarding [php concurrency](https://devcenter.heroku.com/articles/php-concurrency). This article boils down to, different dynos have different memory limits. They allocate 128mb to a php process and divide that by the total memory on a machine and that is used to determine how many threads to have on a single dyno. They also look for a `.user.ini` file if you want to override the memory defaults. So first I realized our `.user.ini` file had specified `memory_limit = 256M` which was causing us to have half as many processes per dyno, so I set this back to 128. Ok great, this did improve things a little. I then read that you could override the concurrency default behavior by setting the environment variable `WEB_CONCURRENCY` to be whatever you wanted. This did come with a warning. + +> When setting WEB_CONCURRENCY manually, make sure that its value multiplied by your memory_limit does not exceed the amount of RAM available on your dyno type. + +Now I started doing some load testing of my own, and while it would over subscribe the dyno, I gave us 10 on a 2x dyno which theoretically would cause us to OOM but with some basic load testing didnt seem like it would happen. This gave us some boost, but not as much as we hoped. I was still very stuck, and I had a suspicion that maybe there was some problem between PHP and Nginx which was slowing things down. I used the craft diagnostic tools, and I couldn't find more than 400ms being wasted in sql queries which didn't account for the almost 1 second page load I still had. + +## Nginx configs + +Ok, so I started looking around, and I found a [TON of great CraftCMS content by nystudio107](https://nystudio107.com/). I don't quite remember which article, but I stumbled across several that implied I needed better fastcgi settings in Nginx. So, I [forked the heroku buildpack](https://github.com/qualaio/heroku-buildpack-php) and got to work. I ended up making these settings. + +```nginx +fastcgi_buffers 256 16k; +fastcgi_buffer_size 128k; +fastcgi_connect_timeout 10s; +fastcgi_send_timeout 120s; +fastcgi_read_timeout 120s; +fastcgi_busy_buffers_size 256k; +fastcgi_temp_file_write_size 256k; +reset_timedout_connection on; +``` + +## Brotli + +While I was in the config, I decided *what the hell, lets get brolti working*. [Brotli](https://github.com/google/brotli) is a compression format that is more compact than gzip. Over the wire assets are usually 5-10% smaller than gzipped. So, sending brotli if the browser supports it, is a big win. Turns out there is an [issue filed in 2019 with heroku](https://github.com/heroku/heroku-buildpack-php/issues/356) to add it, but its not gone anywhere. Ultimately, I found someone else [figured out how to add it](https://github.com/seyallin/heroku-brotli-nginx). I made some changes and added it to our fork. You can view all of our changes in [github's compare view](https://github.com/heroku/heroku-buildpack-php/compare/main...qualaio:main#diff-ff7b43f722c67a80d4c82bf656918b3bf96f553a5ad1f62ef185dff16582f033R24-R31). + +## Results + +So the results was a **huge** drop in TTFB, which overall improved our ligthhouse score by 30 points. The other thing that's great is, we're moderately fast without caches, which means caches can only improve the situation further. + +![A graph showing a drop in response time from over 1 second to less than one](1.png) diff --git a/src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/.keep b/src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/.keep new file mode 100644 index 0000000..e69de29 diff --git a/src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/1.png b/src/TerribleDev.Blog.Web/wwwroot/img/Speeding-up-CraftCMS-on-Heroku/1.png new file mode 100644 index 0000000000000000000000000000000000000000..6a781486c0bbcbd3e11be769efd2d454f63ce46f GIT binary patch literal 15662 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