{"id":513,"date":"2010-01-23T13:49:26","date_gmt":"2010-01-23T12:49:26","guid":{"rendered":"http:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/"},"modified":"2010-01-23T13:49:26","modified_gmt":"2010-01-23T12:49:26","slug":"my-opera-front-page-caching-and-varnish-hacking","status":"publish","type":"post","link":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/","title":{"rendered":"My Opera front page caching and Varnish hacking"},"content":{"rendered":"<h3>The My Opera front page<\/h3>\n<p><span class='imgright'><img alt='' src='http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif' \/><\/span> According to our internal statistics, the front page of My Opera makes up for a consistent part of the entire traffic we get on our servers. So it&#39;s normal we have been working to optimize it for a very long time.<\/p>\n<p>When we knew that <a href=\"http:\/\/www.opera.com\/mini\/next\/\" rel=\"nofollow\">Opera Mini 5.0<\/a> would <b>be released with our front page as one of the preloaded speed dials<\/b>, then we started to study the situation in more depth and plan what to do (and quickly!).<\/p>\n<p>Mini 5 is already out, and used by lots of people, and during the last months, we have been getting more and more front page views than ever. What I&#39;m going to tell you is the last (final?) step of the front page performance optimizations we worked on. If it works well, we could be able to apply it to other heavy parts of the site.<\/p>\n<h3>Enter Varnish&#8230;<\/h3>\n<p><a href=\"http:\/\/varnish.projects.linpro.no\/wiki\" rel=\"nofollow\">Varnish<\/a> is a reverse proxy cache software.<br \/>\nIf you know Varnish already, I suggest you take a look at this <a href=\"http:\/\/www.slideshare.net\/crucially\/varnish-oscon-2009\" rel=\"nofollow\">great presentation from OSCON 2009<\/a>.<\/p>\n<p>During October 2009, we deployed our first Varnish server for My Opera, for some very specific and mostly static content. At that time, for me it was very experimental. I hardly knew anything about Varnish :) and in fact, we had some problems here and there. Then we gradually acquired some experience, and so we thought of using Varnish also, and for the first time, for a dynamic request.<\/p>\n<h3>Front page caching<\/h3>\n<p>Caching a full HTML page presents more challenges than caching a picture. For pictures, you can ignore the User-Agent and the cookies. At least in our case. You can ignore user language preferences. You can also ignore the <code>Accept-Language<\/code> HTTP header. For My Opera, we also have the <b>Mobile view<\/b> feature.<\/p>\n<p>All of that means that if you&#39;re going to cache, say, the front page of My Opera, you can have:<\/p>\n<ul>\n<li>4 main types of browsers: Opera Mini, Opera Mobile, IE and the standards compliant;<\/li>\n<li>18 different languages, the ones in the language selector at the bottom, from Bulgarian to LOLCAT and Simplified Chinese, selected by either the sticky &quot;language&quot; cookie or by the <code>Accept-Language<\/code> header.<\/li>\n<li>2 views, mobile and full\/desktop view<\/li>\n<\/ul>\n<p>That makes a grand total of nearly 100 different versions of one single page.<br \/>\nOf course all of this is just for the logged out users. We don&#39;t want (and couldn&#39;t either) cache each single logged in user version of the frontpage (with the activity feed and all the rest).<\/p>\n<h3>Reducing the variations<\/h3>\n<p>For the caching to work properly, and be effective, we needed to find a way to reduce the possible number of versions of the front page. So in the Varnish VCL file, we match the <code>User-Agent<\/code> string, to reduce it to any of 4 predefined strings like &quot;operamini&quot;, &quot;operamobile&quot;, &quot;msie&quot;, or &quot;nomatch&quot;. So instead of having &amp;inf; user agent strings, we get only 4.<\/p>\n<p>Then another similar problem is the <code>Accept-Language<\/code> header. This header can be quite complex, depending on your browser settings, and there&#39;s no easy method to &quot;figure-out&quot; what language you want. From a string such as:<br \/>\n<code><\/p>\n<pre>\r\nde-DE,tr;q=0.999,en;q=0.75,fr;q=0.9,it;q=0.8,ja;q=0.2,ru;q=0.1\r\n<\/pre>\n<p><\/code>\n<\/p>\n<p>you have to build a list of prioritized language preferences and match them against the languages your site can offer.<\/p>\n<p>Failing to do that means, by default, having a different version of the frontpage for each different Accept-Language header, which is <b>very variable<\/b> across clients, even if there are very common values. A brief statistics gathering session showed 500 distinct values in about 10,000 browser requests.<\/p>\n<h3>accept-language.vcl<\/h3>\n<p>Varnish allows you to <b>embed C code inside a VCL file<\/b>. This is a pretty advanced feature that is not very much talked about. Given that using regexp to massage Accept-Language appeared to be messy, we discussed another crazy idea. <b>Writing a C function to parse <code>Accept-Language<\/code>, and then embed that function into the Varnish VCL config<\/b>.<\/p>\n<p>Let&#39;s say that your site has English and Japanese. Your user browsers will send every possible Accept-Language header on Earth. If you enable <code>Vary: Accept-Language<\/code> on Varnish or on your backends (and you should)<br \/>\nthe cache hit ratio will rapidly drop, because of the huge variations in Accept-Language contents. Varnish will store one version of the page for every different accept language string. That&#39;s bad.<\/p>\n<p>With this hack, the <code>Accept-Language<\/code> header will be &quot;rewritten&quot; to just &quot;en&quot; or &quot;ja&quot;, depending on your client settings. If no match occurs, a default language will be set (&quot;en&quot;). This brings the language variants down to exactly 2, the number of languages your site supports. In our case it&#39;s 18 versions, so down from ~500 to 18.<\/p>\n<p>It seems a bit weird that we&#39;re the only ones having this problem :)<\/p>\n<p>Most probably we&#39;re trying to solve this problem directly in Varnish, while usually this is dealt with at the backend level. Solving this inside Varnish is very nice, because it allows to scale more easily to other pages as well, with no modifications to the backends config or code.<\/p>\n<p>If you think this might be useful for you too, you&#39;re welcome to <a href=\"http:\/\/github.com\/cosimo\/varnish-accept-language\" rel=\"nofollow\">get the code<\/a> and try it out. It&#39;s on Github:<\/p>\n<p><a href=\"http:\/\/github.com\/cosimo\/varnish-accept-language\/\" rel=\"nofollow\">http:\/\/github.com\/cosimo\/varnish-accept-language\/<\/a><\/p>\n<p><b>Pay attention! It&#39;s experimental stuff, don&#39;t try it in production without extensive testing.<\/b> And let me know how it goes :)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The My Opera front page According to our internal statistics, the front page of My Opera makes up for a consistent part of the entire traffic we get on our servers. So it&#39;s normal we have been working to optimize it for a very long time. When we knew that Opera Mini 5.0 would be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[265,268,484,75,240,60],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>My Opera front page caching and Varnish hacking - Random hacking<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"My Opera front page caching and Varnish hacking - Random hacking\" \/>\n<meta property=\"og:description\" content=\"The My Opera front page According to our internal statistics, the front page of My Opera makes up for a consistent part of the entire traffic we get on our servers. So it&#039;s normal we have been working to optimize it for a very long time. When we knew that Opera Mini 5.0 would be [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\" \/>\n<meta property=\"og:site_name\" content=\"Random hacking\" \/>\n<meta property=\"article:published_time\" content=\"2010-01-23T12:49:26+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif\" \/>\n<meta name=\"author\" content=\"cosimo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"cosimo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\"},\"author\":{\"name\":\"cosimo\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"headline\":\"My Opera front page caching and Varnish hacking\",\"datePublished\":\"2010-01-23T12:49:26+00:00\",\"dateModified\":\"2010-01-23T12:49:26+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\"},\"wordCount\":901,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"image\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif\",\"keywords\":[\"accept-language\",\"cache\",\"front page\",\"performance\",\"scalability\",\"varnish\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\",\"name\":\"My Opera front page caching and Varnish hacking - Random hacking\",\"isPartOf\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage\"},\"thumbnailUrl\":\"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif\",\"datePublished\":\"2010-01-23T12:49:26+00:00\",\"dateModified\":\"2010-01-23T12:49:26+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage\",\"url\":\"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif\",\"contentUrl\":\"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"My Opera front page caching and Varnish hacking\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#website\",\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/\",\"name\":\"Random hacking\",\"description\":\"Assume nothing. Code defensively. Keep it simple, stupid!\",\"publisher\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1\",\"name\":\"cosimo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g\",\"caption\":\"cosimo\"},\"logo\":{\"@id\":\"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"My Opera front page caching and Varnish hacking - Random hacking","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/","og_locale":"en_US","og_type":"article","og_title":"My Opera front page caching and Varnish hacking - Random hacking","og_description":"The My Opera front page According to our internal statistics, the front page of My Opera makes up for a consistent part of the entire traffic we get on our servers. So it&#39;s normal we have been working to optimize it for a very long time. When we knew that Opera Mini 5.0 would be [&hellip;]","og_url":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/","og_site_name":"Random hacking","article_published_time":"2010-01-23T12:49:26+00:00","og_image":[{"url":"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif"}],"author":"cosimo","twitter_card":"summary_large_image","twitter_misc":{"Written by":"cosimo","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#article","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/"},"author":{"name":"cosimo","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"headline":"My Opera front page caching and Varnish hacking","datePublished":"2010-01-23T12:49:26+00:00","dateModified":"2010-01-23T12:49:26+00:00","mainEntityOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/"},"wordCount":901,"commentCount":0,"publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"image":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage"},"thumbnailUrl":"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif","keywords":["accept-language","cache","front page","performance","scalability","varnish"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/","url":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/","name":"My Opera front page caching and Varnish hacking - Random hacking","isPartOf":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage"},"image":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage"},"thumbnailUrl":"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif","datePublished":"2010-01-23T12:49:26+00:00","dateModified":"2010-01-23T12:49:26+00:00","breadcrumb":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#primaryimage","url":"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif","contentUrl":"http:\/\/files.myopera.com\/cstrep\/blog\/varnish-logo-red-64.gif"},{"@type":"BreadcrumbList","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/2010\/01\/my-opera-front-page-caching-and-varnish-hacking\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.streppone.it\/cosimo\/blog\/"},{"@type":"ListItem","position":2,"name":"My Opera front page caching and Varnish hacking"}]},{"@type":"WebSite","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#website","url":"https:\/\/www.streppone.it\/cosimo\/blog\/","name":"Random hacking","description":"Assume nothing. Code defensively. Keep it simple, stupid!","publisher":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.streppone.it\/cosimo\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/c443bedbf6ecf99550d6395620801df1","name":"cosimo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cb1d938720df45a2720724aae99e3bfc?s=96&r=g","caption":"cosimo"},"logo":{"@id":"https:\/\/www.streppone.it\/cosimo\/blog\/#\/schema\/person\/image\/"},"url":"https:\/\/www.streppone.it\/cosimo\/blog\/author\/cosimo\/"}]}},"_links":{"self":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/513"}],"collection":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/comments?post=513"}],"version-history":[{"count":0,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/posts\/513\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/media?parent=513"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/categories?post=513"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.streppone.it\/cosimo\/blog\/wp-json\/wp\/v2\/tags?post=513"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}