One of Varnish's key strengths is its ability to quickly look up an object by hash in memory or on disk and return it as fast as possible. However, that object must originate from somewhere—usually a backend that Varnish fetches from. We can also directly insert cache content (with a POST request, for example), using synthbackend.
This opens up a lot of interesting applications, like using Varnish as a key/value store or even an object store. One of the simplest ways to use this is to serve live video streams.
To understand why this makes sense, let’s first look at how this works:
This minimal example will:
After the cache insert, Varnish follows the default route of delivering the cache hit, which in this case will send the response back to the requester. Of course, the interesting thing is that when we GET that endpoint, we now retrieve the content we previously pushed.
Here’s a simple test of that behavior:
But, how is that useful in video delivery?
Of course, it all depends on your encoder, but if it is based on ffmpeg or similar, then you can set that to push video with POST (or default, PUT) requests straight to a web server or a cache.
Here’s an example ffmpeg command you can try to stream a test video into this test instance:
You can they play it back why it’s actively encoding:
What happens is that ffmpeg (the first long command) will push video segments, and continuously update the master.m3u8 manifest file, straight into cache, and it will immediately be playable by clients, as if there was a backend.
The huge benefit here is that the new data is available immediately. In a regular setup, we’d have to wait for the manifest TTL to expire before the caching layer realizes it needs to refresh it (it works, of course, but this is objectively better, without the need to actively purging the cache).
To make this more useful, we can make some Quality-of-Life change to this minimal example:
vcl_backend_error
.With those, our VCL evolves to:
Now the same stream segments will linger for 2 hours before they are deleted. And our live video will be playable and updated live as long as the encoder is pushing.
Depending on the specs and the network card of the Varnish node, you can now serve live video to hundreds or tens of thousands of users.
This basis can easily be extended, for example, we can:
With these, the VCL becomes a bit too long for such a blog post, but we have it available on Github for you to check if you’d like.
Live video stream is obviously only one of the many use cases, but blog posts are short and the possibilities are infinite. Every time you need fast access to ephemeral content, this concept provides a quick and efficient way to deliver your content, without having to organize the whole pipeline of pushing the content and then remembering to garbage collect it.
That’s it for me, I hope you enjoyed this post as much as I had crafting the code. Varnish is an amazing toolbox that allows us, and you the users, to solve cache and load-balancing problems that may seem outside of our usual perimeter in a quick and elegant way.