Cache EDD Currency from GeoIP with CloudFlare + Varnish 4

Aelia Currency Switcher for Easy Digital Downloads allows digital store owners to set different currencies based on customer geolocation. The MaxMind databases provide GeoIP services so you can detect your visitor’s location. Automatic currency detection based on country adds extra convenience 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.

With CloudFlare’s GeoIP detection and the flexible Varnish vcl language, we can cache each currency separately completely bypassing the PHP handler backend for subsequent visitors who share the same currency settings based on their geolocation.

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

EDD Currency Switcher Speed Tests

For this test, I set up a Digital Ocean VPS with nginx, PHP7, MariaDB and Varnish 4.

I installed the Easy Digital Downloads plugin and added the Varnish carrot product.

I installed the aelia EDD WooCommerce Currency Switcher plugin and set 2 different currencies: EUR and USD.

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

EDD Currency Speed without Varnish Cache

Without Varnish this Easy Digital Downloads product page loads in 1.54 seconds

new_york_pingdom_before_varnish_edd

EDD Currency Speed with Varnish Cache

With Varnish this Easy Digital Downloads product page loads in 351 ms

new_york_pingdom_after_varnish_edd

This is a pretty significant performance boost, increasing the speed over 400% for Easy Digital Downloads with different currencies.

Cache EDD 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 EDD Currency Switcher

Make sure you go to Downloads > 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 with the currency and country mapping.

Configure Varnish 4 Cache for EDD 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.

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

We hash the aelia currency plugin custom query strings and the aelia currency cookie set by the Easy Digital Downloads 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";
}

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 EDD 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.

curl -I https://wp-bullet.online/downloads/varnish-carrot/

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: Thu, 08 Sep 2016 21:50:38 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=de919220180c6a9b4968f47b7a569dfad1473371438; expires=Fri, 08-Sep-17 21:50:38 GMT; path=/; domain=.wp-bullet.online; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Link: <https://wp-bullet.online/wp-json/>; rel="https://api.w.org/"
Link: <https://wp-bullet.online/?p=77>; rel=shortlink
Vary: Accept-Encoding
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
X-Cache: MISS
Server: cloudflare-nginx
CF-RAY: 2df59e01e14a2b7c-AMS

Repeat the same curl command

curl -I https://wp-bullet.online/downloads/varnish-carrot/

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: Thu, 08 Sep 2016 21:50:39 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Set-Cookie: __cfduid=d887db6a98a7f08a0253efaadb924027f1473371439; expires=Fri, 08-Sep-17 21:50:39 GMT; path=/; domain=.wp-bullet.online; HttpOnly
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Link: <https://wp-bullet.online/wp-json/>; rel="https://api.w.org/"
Link: <https://wp-bullet.online/?p=77>; rel=shortlink
Vary: Accept-Encoding
X-Varnish: 32770 3
Age: 1
Via: 1.1 varnish-v4
X-Cache: HIT
Server: cloudflare-nginx
CF-RAY: 2df59e0be7402c2a-AMS

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 Easy Digital Downloads faster :).