I once had a client, who had very fluctuating traffic on a site in Episerver DXC. Most of the time the site had normal traffic, until a marketing campaign shot the traffic sky-high for some time.
Those campaigns naturally had to take the traffic with no extended load time.
Such requirements are both challenging and fun at the same time. This blog post is about how I solved it.
Requirements and scope
In short, my client had these requirements.
About the campaign:
- The campaign would lead to a single landing page.
- The campaign would be targeted toward specific geographic regions.
- The landing page should sustain, at least, 10,000+ page views, without slowing down the Commerce site noticeably.
- The landing page should be served at normal load time (or faster).
About the landing page:
- The landing page would be in a few different languages.
- The landing page would not be personalized.
- The landing page would only contain simple blocks and assets.
Two solutions to output caching
Based on the above-mentioned requirements, I thought about various solutions. Here are two of them.
The "simple solution"
The simplest solution I could come up with, was to keep the solution as it was, and just try to make it faster within the boundaries.
To implement I had to:
- Attempt to optimize the backend and frontend code as much as possible.
- Enable output caching on controller level.
- Ask Episerver Support to scale out the servers before each campaign.
- Not much code would need to be changed.
- Any content change would immediately clear the output cache item.
- It is both tiresome and inefficient to write to the hosting support, every time a campaign is going to start. Over time, they might not even continued doing this.
- There is still no way, the load time would be consistently low while not affecting the remaining parts of the site.
The "radical solution"
Because of the hard performance requirements, and the loose content requirements, I decided to try a more radical solution. A solution that trades off everything that Episerver is remarkably good at (especially personalization), for extreme performance.
Like in the simple solution, this solution relies on page output caching. But in this solution, the output caching happens in Cloudflare’s many datacenters, much closer to the visitors, and without most of the requests ever reaching Episerver.
To implement I had to:
- Make the landing page controller send a Cache-Control header.
- Implement an action filter to add the necessary cache headers to the response.
- Ask Episerver Support to create a Cloudflare page rule, which enables output caching for the landing page URL patterns.
- After the first request got cached, each request for the landing page was served in less than 200ms (consistently).
- The rest of the site was completely unaffected, since the landing page traffic was kept away from the CMS servers.
- Advanced personalization effectively gets turned off (but I have ideas to fix this).
- A content change to the landing page would not have immediate effect, if it was already cached. To refresh a landing page while it is cached, you will need to head to Episerver PaasPortal to purge the entire CDN cache.
As you can probably guess by now, I went with the "radical solution", because it had the highest pay-off.
No matter how much traffic such a marketing campaign generated to the landing page, the remaining website kept running as normal.