Why is my site slow?

Like most things involving computers, the answer is “it’s complicated.”

Website performance is a combination of many factors including your environment, your site’s specific implementation and volume of traffic. This article will cover the main areas to review and will point you to some great resources about modern web application performance. Ultimately, Craft is a web app, and fine tuning it is similar to fine-tuning any other PHP-based, database-backed application.


The Templates #

Craft is a very open-ended CMS, allowing for a flexible content architecture. Craft users have 100% control of the HTML output of the front-end of their site. Because of this, Craft will do whatever your templates tell it to do, which can be a common bottleneck for performance.

That includes executing 1,000,000 queries in a request or trying to output 1,000,000 entries onto a page at one time. Unless you have significant resources in place to support that type of request, you’ll run into performance issues.

If your templates are telling Craft to generate image transforms for 100MB worth of images as well as send out 40MB of images, then it will take some time.

There are some template performance gotchas to avoid in Craft: https://craftcms.stackexchange.com/questions/59/what-are-the-most-common-template-performance-gotchas-to-avoid

If you’re running into the dreaded N+1 SQL database query problem in your templates, you should be taking advantage of Craft’s eager loading support: https://craftcms.com/docs/templating/eager-loading-elements

Craft’s {% cache %} template tag is another tool in your quest to tame the performance dragon.

It’s also good to know when to use the cache tag and when not tohttps://craftcms.com/docs/templating/cache#when-to-use-cache-tags

Sometimes it is good to know how the code you use actually operates: https://nystudio107.com/blog/the-craft-cache-tag-in-depth

To keep the cache tag happy, make sure you don’t have any stalled tasks, either! https://craftcms.com/support/stuck-tasks#debugging-stuck-delete-stale-template-caches-tasks


The Database #

In a poorly configured database server, database queries aren’t going to execute as fast as they could in an optimized environment. If your database is configured properly, but doesn't have enough resources assigned to it to handle the load of your site (common in shared hosting environments), you can run into the same execution time issues. If a web request is generating a few hundred queries, that excess execution time adds up to an overall slower request.

Your database server must be properly tuned and have the resources it needs to handle the SQL queries that it receives.

In Craft 2, if you enable devMode, this will output a plethora of profiling and debugging information into craft/storage/runtime/logs as well as to the browser’s console. In Craft 3, you get to use the Debug Toolbar as well as the logs in craft/storage/logs to get this information. All of this information can be used to help debug database performance issues.

In the log files, you’ll see code profiling log entries and executed database queries for the request. Each will have a timestamp you can use to determine what code is holding up the request, and will also point you to the exact line it is located on.

In the browser’s console or the Debug Toolbar, you’ll see database profiling output for the request, including the number of queries executed, their execution times and the SQL for those queries. These are sorted in ascending order with slowest performing at the top.


The Plugins #

Not only are Craft’s templates and content architecture flexible, but Craft also allows plugins to get involved at nearly every step in the process of a request. Because of this, plugins can be a potential source of performance issues depending on what they try to do in a request.

To minimize the impact they might have, consider 1) using only plugins absolutely necessary for the site 2) make sure you’re running the latest versions and 3) consider using well-established, tested and actively developed plugins.


The Load #

Another important thing to determine is when does the slowdown occurs. Can you reproduce it on every single request? Does it only happy when your site gets hit with traffic? How much traffic does it take? Does it happen at a specific time of the day, every day or only on Tuesday?

There are plenty of commercial and free load testing tools you can use to help identify load issues in staging and development before you go live.


The Environment #

Make sure your webserver(s), database, network, disk drives, load balancers, routers, etc. are all properly tuned and have enough resources to handle the traffic that your site is expecting. If you’re not in charge of the environment to that level, make sure you’ve chosen a good host that knows what they are doing.

Run PHP 7 instead of PHP 5 on your server. It’s super low-hanging performance fruit because it runs much faster and consumes less memory than PHP 5.

If you have the option, consider using nginx in place of (or in front of) Apache. It handles high concurrency much better than Apache and with fewer resources: https://help.dreamhost.com/hc/en-us/articles/215945987-Web-server-performance-comparison

There are other practical things to consider when deciding Apache vs. nginx, too: https://www.digitalocean.com/community/tutorials/apache-vs-nginx-practical-considerations

Consider going all in on https and http2, not just for privacy, but for the speed:

https://www.httpvshttps.com/

https://www.troyhunt.com/i-wanna-go-fast-https-massive-speed-advantage/

Look into output compression to send less data in your web server responses:

https://httpd.apache.org/docs/current/mod/mod_deflate.html

https://nginx.org/en/docs/http/ngx_http_gzip_module.html

Investigate how to use a load balancer to distribute requests equally across multiple web servers.

https://www.nginx.com/resources/glossary/load-balancing/


The Cache #

Smart caching can speed things up at all levels of a request for your site.

Whether it’s something like Varnish that acts as a caching HTTP reverse proxy, or through services like Cloudflare, or any of the other numerous CDN services around the world, they can all speed up requests to your site.

At the web server level, you can enable PHP byte-caching extensions like Opcache or pick your favorite flavor of PHP caching extensions.

Your templates should take advantage of browser caching for their resources.

For a better understanding of the different caching options available in a Craft installation, see: https://craftcms.stackexchange.com/a/13383/57


Additional Resources #

General website performance

Targeted towards Craft