How good is Cloudflare's Always Online™ technology?

If your site goes down, exactly how good is Cloudflare’s Always Online™ technology at bailing you out?

Rather good. But…

We’ll get to the “but” in a minute. Let’s deal with the “rather good” first. Here’s arcade.ly‘s homepage when the site is down:

The arcade.ly homepage when the site is down. Note that Cloudflare is still serving it up, which is great.

By down, in this case I mean the service that runs the site is down, although the instance it normally runs on is up.

Now apart from that banner, which is basically an ad that says, “Cloudflare is awesome and you should use it!”, everything looks normal. I could probably get rid of that by giving Cloudflare more money, and maybe one day I will. Nevertheless, my dodgy web design skills aside (and this page is going to get a makeover), everything that should be on the homepage has loaded and is working fine because Cloudflare has been able to serve it up from its cache.

So can I play the games?

Yes, I can. My Asteroids remake, Shoot the Rocks, works fine. Here you can see it loading as if nothing is amiss:

Shoot the Rocks loading like nothing's wrong - awesome.

The main menu looks a bit gimpy because the banner messes with the layout a bit, which might be more problematic on iOS than on desktop or Android, but everything still works:

The Shoot the Rocks menu is slightly messed up but still works.

And the game itself runs flawlessly, and weirdly without the banner:

Shoot the Rocks running flawlessly, thanks to Cloudflare.

Well, bless Cloudflare is all I can say to that.

There was that “but” though, so we should take a look at that because it doesn’t always work out so well. Here’s what happened when I tried to run Star Citadel, my take on Star Castle:

Argh! Star Citadel doesn't work - I just get this nasty error.

That’s a less happy, although completely understandable, outcome: Cloudflare simply didn’t have the page in its cache. If your site was up for a while before it went down, or you get a decent amount of traffic around the world, hopefully this doesn’t happen.

I say all around the world because, being a CDN, Cloudflare can cache your site on edge servers all over the globe but won’t cache it anywhere until somebody accesses it. This means that pages will be cached on servers located geographically nearer to people who use them (in general), but not on servers located geographically further away.

Thus in places where your site gets used a lot, hopefully people get to carry on using it even whilst your back end services or infrastructure are burning, but people in other areas won’t get the same experience, and will instead see an error.

Again, if I paid more I think could probably replace the above with some sort of branded custom error page, so choose an appropriate plan for your use case.

What will and won’t work offline?

So this all works because of the way I’ve architected the site. Almost everything you see when you visit a page or play a game on arcade.ly is static content served up by my web server or, more likely, Cloudflare. As little as possible happens on the server, which is why Cloudflare can bail me out.

If all my content were dynamically generated server side it would be a different story: I might still see a static version of the pages as last seen by Cloudflare, but nothing would really work.

In reality most sites sit somewhere in between these two extremes, and even for arcade.ly, there are things that wouldn’t work.

For example, the as yet publicly unavailable hiscore service where you can record your performance in each game for posterity and bragging rights to your friends? Totally not going to work because there’s back end infrastructure in there:

  • A service to record high scores - in fact ideally I’d record scores from all games and build up a gigantic league table for each game, as played in modern and classic modes, split by device, and so on,

  • A data store to put all of this in: right now I’m thinking SQL Azure because we’re talking about a big table of data, for which SQL is absolutely perfect (this definitely is not a document shaped problem at any rate),

  • A service to expose that hiscore data, or a league table if you like (or possibly we’re talking about two different views on the same data), to clients, which might be the games themselves, or other stats pages on the site, possibly in the future even dedicated mobile apps.

If the two services are deployed separately to the main website they might still be available but, if not, or if there’s a problem with the hosting infrastructure not in a million years will the above work.

That doesn’t mean you can’t record a player’s score in the meantime. There is, of course, LocalStorage or IndexedDB, so if you’ve built your site for an offline first experience, your user’s might not even notice that there’s a problem, particularly if hiscore data was loaded before the site/service went down. You can just record the player’s score and submit it later when the site is back online.

There are, of course, caveats. Any data you put into LocalStorage as plain text is incredibly easy to tamper with using tools such as the HTML5 Storage Manager All In One Chrome extension. You can use a library like lz-string to compress any data you add to LocalStorage to render it no longer human-readable, but somebody who’s committed can always copy and paste it out, decompress, edit, recompress, and then paste it back in to LocalStorage. How much you’re worried about that is something you should consider.

You can also encrypt the data using, for example, this JavaScript AES implementation. This will certainly discourage the casual hacker, but remember that the merits of cryptography in JavaScript are extremely questionable (see also here for a slightly more recent perspective). JS encryption certainly isn’t going to stop somebody who’s committed to tampering with the data.

As far as I know there’s no (supported) mechanism for accessing IndexedDB except by the site that wrote the data but, remember, this is data stored on the client so you may want to consider it suspect anyway.

LocalStorage and IndexedDB work well when whatever you store in them will eventually undergo strong validation on the server-side. It does not work so well when this isn’t the case - perhaps because the data is collected or generated in such a way that validation is very hard - and you can’t trust your users (because they want a ludicrously high score for bragging rights, for example).

Anyway, to drag this back to the point: you can offer a decent offline experience, and this will prove especially useful in scenarios where strong validation later on, when your web client can once again connect to your services, is suitable.

In some situations you’re just going to have to tell the user that certain functionality isn’t available at the moment but it will be back online soon. For example, I’d like to offer some sort of player history and stats service. I’d really like to offer people the ability to compare with their friends, and perhaps compete directly with them. Clearly, this won’t work offline, but graceful failure is an option I’ll happily embrace.

So, the verdict on Cloudflare Always Online™? Pretty good - just be aware of the limitations:

  • Consider where your users are: will they be able to access the pages they need? Can you use a service such as pingdom to ensure Cloudflare caches the necessary pages? (Actually, thinking about it, maybe this is something Cloudflare already offer in their Business or Enterprise plans.)

  • Consider how you can build an offline first experience for functionality with online requirements: can you hold data for later? Or perhaps limit functionality? Or can you at least make it unavailable gracefully by telling the user what’s going on, rather than just breaking?

And that’s it. As always, hope this was useful, and please do leave questions or comments below.

Thanks for reading!