Basecamp caches HTML to go fast

(written by lawrence krubner, however indented passages are often quotes). You can contact lawrence at: lawrence@krubner.com, or follow me on Twitter.

Interesting:

Stacker can only make things appear so fast. If actions still take 500ms to render, it’s not going to have that ultra snappy feel that Basecamp Next does. To get that sensation, your requests need to take less than 100ms. Once our caches are warm, many of our requests take less than 50ms and some even less than 20ms.

The only way we can get complex pages to take less than 50ms is to make liberal use of caching. We went about forty miles north of liberal and ended up with THE MAX. Every stand-alone piece of content is cached in Basecamp Next. The todo item, the todo lists, the block of todo lists, and the project page that includes all of it.

This Russian doll approach to caching means that even when content changes, you’re not going to throw out the entire cache. Only the bits you need to and then you reuse the rest of the caches that are still good.

This is illustrated in the picture above. If I change todo #45, I’ll have to bust the cache for the todo, the cache for the list, the cache for all todolists, and the cache for the page itself. That sounds terrible on the surface until you realize that everything else is cached as well and can be reused.

So yes, the todolist cache that contains todo #45 is busted, but it can be regenerated cheaply because all the other items on that list are still cached and those caches are still good. So to regenerate the todolist cache, we only pay the price of regenerating todo #45 plus the cost of reading the 7 other caches — which is of course very cheap.

The same plays out for the entire todolist section. We just pay to regenerate todolist #67 and then we read the existing caches of all the other todolist caches that are still good. And again, the same with the project page cache. It’ll just read the caches of discussions etc and not pay to regenerate those.

The entire scheme works under the key-based cache expiration model. There’s nothing to manually expire. When a todo is updated, the updated_at timestamp is touched, which triggers a chain of updates to touch the todolist and then the project. The old caches that will no longer be read are simply left to be automatically garbage collected by memcached when it’s running low on space (which will take a while).

Post external references

  1. 1
    https://signalvnoise.com/posts/3112-how-basecamp-next-got-to-be-so-damn-fast-without-using-much-client-side-ui
Source