How we have improved Drupal site performance with Cloudflare

Do you wonder how to easily improve performance of your Drupal - and even non-Drupal - website without even touching the site itself, only by using modern infrastructure solutions? In this article I'll show you how we did that for one of our clients.

The client called us one day and asked for help with his website. He had serious problems with performance. Page load times were unacceptable. Furthermore, the client expected high traffic peak in a few days, as their webpage was about to be promoted in mainstream media. We were more than happy to help.

The site was based on Drupal 7 and built with many contributed modules. This caused major performance issues. We weren't able to improve the performance without rebuilding some of the features, and we weren't able to rebuild them, because the timing was very tight.

That's why we have decided not to alter existing website and to focus on infrastructure solutions instead. After some discussion with the client, we have identified the most important webpages - like home page - we will focus on. Fortunately, we were able to limit our work to static, rarely changed content, accessed by anonymous users. It has allowed us to use aggressive caching policy.

Our solution

The tool of our choice was Cloudflare - a Content Delivery Network (CDN), working in "reverse proxy" mode. This means that users connect to Cloudflare's servers instead of our client's server. CDN servers check if they have a cached version of requested resource (page, image, css file, javascript file, attachment files etc.); if so, it serves that resource without sending any request to our client's server. If the resource is not present on CDN server, it is downloaded from client's server to CDN server and then served to the user. In effect, much of the traffic is served by CDN, and client's server load is much smaller.


This solution has some important drawbacks. First of all, as this is based on caching of pages, it's not suitable for dynamic content. We can minimize impact here by defining some complex cache expiration policies, including expiration of resources stored by CDN server. This can be done on Drupal level - but, as we didn't want to modify the site, we had to create some Cloudflare rules that have overriden default Drupal cache expiration parameters. For example, we have forced the CDN to store a cached copy of home page for at least 30 minutes, despite headers sent by Drupal. With tricks like this, we were able to tune the CDN to fit the needs of our client.

Another limitation you should be aware of is that - since majority of requests don't reach the server, any traffic statistics gathered on server and Drupal level cannot be trustworthy. Fortunately, stats gathered by tools like Google Analytics are not affected. In addition, the Cloudflare gave us access to some of its own statistics, like number of served requests and amount of saved bandwidth.

Caching of images in CDN can also give a significant performance increase. Unfortunately, the site we worked on was using Drupal modules (like Adaptive Image Styles) which scale the images on the fly to match the resolutions of mobile devices; this is generally a good idea, but makes caching of these images much harder. We didn't manage to solve that without modifying the site. To avoid future issues with performance of image scaling, I would recommend not using these modules; you should use your infrastructure to optimize resolution of images (for example, Cloudflare mirage).

Some numbers

We made some benchmarks of performance before and after implementation of our optimizations. All our tests were performed with ab tool, sending 2000 requests to open front page in 10 concurrent connections. 

BEFORE our optimizations the performance was as following:

  • Requests per second: 3.35 [#/sec] (mean)
  • Time per request: 1492.336 [ms] (mean)
  • Time per request: 298.467 [ms] (mean, across all concurrent requests)


AFTER our optimizations the performance gain was really significant:

  • Requests per second: 116.09 [#/sec] (mean)
  • Time per request: 43.070 [ms] (mean)
  • Time per request: 8.614 [ms] (mean, across all concurrent requests)


Impressive, isn't it? We got from 3 requests per second to over 100! 

Of course, each project is different and you should consider a variety of tools that might - or might not - get you satisfying results. So if you need some help and expertise to improve performance of of your website, contact us.

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.