Caching is one of the most important factors in scaling any website, but especially busy eCommerce sites. Recently I had the opportunity to launch an Odoo 16.0 instance in a clean Cloudflare Pro account and was able to monitor in real time what resources where being loaded dynamically from the server and optimize for extra caching. I was surprised by a lack of go-to resources on this topic, so let me get everyone started on what I've been using and measuring real 50% cache improvements on a real ecommerce Odoo 16 cut over from an existing Opencart site.
See below where over the course of a couple of hours, caching was tuned to the point where during a planned announcement spike was no problem at all.
This is the kind of first-hand stuff you need in a world of keyword-stuffed AI-generated content!
Why the Need for Additional cache rules?
Simple, some routes are highly cachable, but do not always look cachable to Cloudflare out of the box. Things like /website/image/.. route can be cached by Cloudflare, as it is common and the responses only depend on query string but Cloudflare doesn't assume that because the route doesn't traditionally look like an image like .jpg or .png and thus can assume the users session has something to do with what asset, image, or resource is returned.
What should my caching configuration be for these routes?
Well that is highly subjective, but I think it should be reasonably safe and highly performant to assume the following for all of my later example rules.
Cache eligibility - Eligible for cache - again we are not poking holes in cache we are enabling caching for these routes.
Edge TTL - Ignore cache-control header and use this TTL - 8 hours -- some starting numbers.
Browser TTL - Override origin and use this TTL - 8 hours ^^
From here on out, just enable Sort query string
Page Rules/Routes
Assume all of them are "URI Path" and "Starts with", but I will post what the query syntax should look like after every rule for you to compare to.
1. odoo /web/image/
(starts_with(http.request.uri.path, "/web/image/"))
2. odoo /website/translations/
(starts_with(http.request.uri.path, "/website/translations/"))
3. odoo /website/snipppet/
(starts_with(http.request.uri.path, "/website/snipppet/"))
4. odoo /website/theme_customize_data_get
(http.request.uri.path eq "/website/theme_customize_data_get")
5. odoo /freeze_header/static/src/scss/freeze.scss (equals)
(http.request.uri.path eq "/freeze_header/static/src/scss/freeze.scss")
6. odoo */static/* (contains)
(http.request.uri.path contains "/static/")
Security Rules
We have already observed bot traffic submitting the contact form. Odoo's contact form is "a bit different" and uses a generic form handler that gets the model it should interact with as POST data. So this security rule should save you from more than just the contact form!
Security -> WAF -> Rate limiting rules:
odoo /website/form/ (contact)
(http.request.uri.path eq "/website/form/")
Now the limit should be pretty low, use the "less than 10 seconds options" and maybe single digits rating (I don't want to share specific configuration).
Cloudflare IPs and Security
Remember that Cloudflare only works if cloudflare is proxying your site, and the security only works if you only trust Cloudflare IP addresses. How you can achive that will depend on your deployment topology. Kubernetes ingeress-nginx has out of the box IP whitelisting that works perfectly here as long as you get the real IP address from whatever Layer 4 and Layer 7 will give you. Make sure you test this out if you rely on this security layer.
Got any Cloudflare and Odoo tips? Love to hear from you in the comments!