Cache WooCommerce Currency from CloudFlare GeoIP with Varnish 4

Aelia Currency Switcher for WooCommerce allows shop owners to set different currencies based on customer geolocation. This technology is known as GeoIP location detection and is provided by the MaxMind databases. Automatic currency detection based on country adds extra polish to your store, however it can add extra loading time because PHP must be used to look up the visitor's IP in the GeoIP database.

When we combine CloudFlare's GeoIP detection and Varnish‘s flexible vcl language, we can cache each currency separately, completely bypassing the PHP handler backend for subsequent visitors who share the same currency settings. This means if you use USD for visitors from the USA, only the first visitor from the USA will get an uncached versions, all other USA visitors will get the cached version.

Note: You must have signed up for and enabled CloudFlare and have a Varnish 4 configuration that you are able to modify for WooCommerce.

WooCommerce Currency Switcher Speed Tests

For this test I set up a Digital Ocean VPS with nginx, PHP7, MariaDB and Varnish 4 with WooCommerce and added 10 products with the Product Generator.

I installed the Aelia WooCommerce Currency Switcher plugin and set 3 different currencies: EUR, USD and GBP.

I used the Varnish configuration outlined below and ran the tests with and without cache.

WooCommerce Currency Speed without Varnish Cache

Page load time from Sweden without Varnish was 882 ms

WooCommerce Currency Speed with Varnish Cache

Page load time from Sweden with Varnish was 279 ms

This is a 300% WooCommerce speed improvement for your different currencies, read on to configure it.

Cache WooCommerce Currency from GeoIP with CloudFlare + Varnish 4

Installation overview

  • Enable CloudFlare's free GeoIP service
  • Then set your custom currency and country mapping logic in the Aelia plugin
  • Configure Varnish to use the CloudFlare header and map the currency and country logic

Configure CloudFlare GeoIP Header

Log in to your CloudFlare account.

Choose the Network Tab and toggle IP Geolocation to On

cloudflare-configure-enable-geoip-detection-min

Now you will have a CF-IPCountry header set for all visitors coming through CloudFlare.

Configure Aelia WooCommerce Currency Switcher

Make sure you go to WooCommerce Currency Switcher > Geolocation tab > check Enable automatic selection of Currency depending on Visitors' location

Set any custom currency information with Aelia's guide, I used Pluginception to create the custom plugin containing the custom currency and country logic.

Configure Varnish 4 Cache for GeoIP Header from CloudFlare

You must have the std module imported in the beginning of your Varnish 4 vcl if you wish to view the countries and currencies set in Varnishlog.

Open your Varnish vcl

sudo nano /etc/varnish/default.vcl

Now modify the the following Varnish sections.

sub vcl_recv

Here we set a custom header based on the CloudFlare GeoIP header CF-IPCountry.

We use that custom header X-Country to set the X-Currency header.

We hash the Aelia custom query strings and the Aelia currency cookie set by the Aelia WooCommerce Currency Switcher plugin.

sub vcl_recv {

#set country header based on CloudFlare's GeoIP
if (req.http.CF-IPCountry) {
    set req.http.X-Country = req.http.CF-IPCountry;
}

#set currency based on country header
if (req.http.X-Country == "SE") {
    set req.http.X-Currency = "EUR";
} else if (req.http.X-Country == "US") {
    set req.http.X-Currency = "USD";
}

#set currency more specifically for multiple countries that share same currency
if (req.http.X-Country ~ "DK|FO") {
    set req.http.X-Currency = "EUR";
}

#cache aelia currency cookie
if (req.http.cookie ~ "aelia_cs_selected_currency") {
    return(hash);
  }

#cache aelia query strings explicitly
if (req.url ~ "\?aelia_(cs_currency|customer_country|customer_state)=")
    return(hash);
}

sub vcl_hash

In the sub vcl_hash section we are caching different versions of each page based on the X-Currency header.

sub vcl_hash {
    if (req.http.cookie ~ "aelia_cs_selected_currency") {
        hash_data(req.http.cookie);
    }

#hash based on currency header Varnish sets
    if (req.http.X-Currency) {
        hash_data(req.http.X-Currency);
    }
}

Ctrl+X, Y and Enter to Save.

Test the Varnish GeoIP Configuration for WooCommerce and CloudFlare

This command will verify the Varnish vcl syntax is valid

varnishd -C -f /etc/varnish/default.vcl

Now reload the Varnish service

sudo service varnish reload

Using the command line on two different DigitalOcean VPS's from the same region, we can verify if Varnish is caching our custom currency shop and product pages by using cURL.

sudo apt-get install curl -y

Now curl the shop URL or a product page. Using the -I switch which returns the response headers from a HEAD request.

curl -I https://wp-bullet.online/shop/

At first you will probably see the X-Cache: MISS header since it is the first visit from that specific continent.

HTTP/1.1 200 OK
Date: Sat, 27 Aug 2016 07:52:43 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=dd68b58232cba6c1f53425d33bd2677741472284363; expires=Sun, 27-Aug-17 07:52:43 GMT; path=/; domain=.wp-bullet.online; HttpOnly
Link: <https://wp-bullet.online/wp-json/>; rel="https://api.w.org/"
Vary: Accept-Encoding
X-Varnish: 491537 32774
Age: 33489
Via: 1.1 varnish-v4
X-Cache: MISS
Server: cloudflare-nginx
CF-RAY: 2d8df21881550c05-AMS

Repeat the same cURL command

curl -I https://wp-bullet.online/shop/

Now you will see an X-Cache: HIT showing Varnish has cached the WooCommerce currency page based on the headers we set.

HTTP/1.1 200 OK
Date: Sat, 27 Aug 2016 07:52:53 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=dd68b58232cba6c1f53425d33bd2677741472284363; expires=Sun, 27-Aug-17 07:52:43 GMT; path=/; domain=.wp-bullet.online; HttpOnly
Link: <https://wp-bullet.online/wp-json/>; rel="https://api.w.org/"
Vary: Accept-Encoding
X-Varnish: 491537 32774
Age: 33491
Via: 1.1 varnish-v4
X-Cache: HIT
Server: cloudflare-nginx
CF-RAY: 2d8df21881550c05-AMS

On another VPS in the same continent or country you can run the cURL test again. This should show you an X-Cache HIT immediately.

You can use pingdom to test from different locations. This will give you a small screenshot you can open to verify the currency is set correctly.

If you need help leave a comment or get in touch, I’m always happy to make WooCommerce faster :).