Content personalization
and paywalls
with
WordPress and Varnish
Stanislav Khromov�WordCamp Norrköping 2015
About me
(part of Schibsted Media Group)
Let’s talk about WordPress
What makes WordPress good?
...and what doesn’t?
...and what doesn’t?
What makes WordPress slow?
The problem
Scaling at high traffic levels
(>1 million daily pageviews)
The truth about traffic
Daily traffic�1 000 000 = 11.6 requests/s�5 000 000 = 57.9 requests/s�10 000 000 = 116 requests/s�
But mean traffic values aren’t completely accurate.
We have to be prepared for traffic spikes.
A 4-day example
Traffic patterns
Traffic patterns
Traffic patterns
Sleep!
At work!
Going home...
The “After-lunch slump”
Late-night browsing
The truth about traffic
A more realistic example
“Expected” peaks can easily be 2x of mean traffic�1 000 000 = 23.2 requests/s�5 000 000 = 115.8 requests/s�10 000 000 = 232 requests/s
Requests to WordPress vs assets
Full-page caching
On the web server...
On the web server...
Regular user
On the web server...
Cache plugin
Anonymous visitor
Anonymous visitor
Cache plugin
Logged in visitor
Logged in
visitor
Cache plugin
(bypassed)
As a separate process:
As a separate process:
As a separate process:
Varnish Cache
rules
As a separate process:
Varnish Cache
rules
Anonymous visitor
As a separate process:
Logged in
visitor
Varnish Cache
rules bypassed due to cookies
Varnish basics
Understanding the Varnish Request / Response cycle
Understanding the Varnish Request / Response cycle
Varnish <3 WordPress
Problems with cache
Edge Side Includes
to the rescue!
What are Edge Side Includes?
What are Edge Side Includes?
What are Edge Side Includes?
A simple example
Breaking it down
What we need
Enable ESI support in Varnish
Whitelist our ESI from caching
Create a WordPress Widget
Create a WordPress Widget
The interesting part - outputting the widget:
Create a simple ESI
A simple PHP file: /esi/lucky-number.php
Edge Side Includes are handled in vcl_fetch by parsing the returned HTML from the backend
Edge Site Includes pass the cache
Varnish Cache
rules
Anonymous visitor
Edge Side Include
Independent caching policies for ESI and backend request
WordPress
backend
ESI call
Always pass
Cache
Do you wanna build paywall?
What do we want?
Breaking it down
Breaking it down
What we need
Independent caching policies for ESI and backend request
WordPress
backend
ESI call
Always pass
Cache
Varnish Cache
rules
Logged in
Subscriber
Edge Side Include: Login form
Cache
inside ESI
ESI Authenticates user based on is_subscriber cookie
is_subscriber
Cookie
is_subscriber
(via Header)
Non-dynamic part
gets cached here
Get login or
logout form from backend
Throw away cookies
Problem: All cookies are gone, how are we going to pass them to the ESI?
Solution: Rewrite cookie to HTTP header
Send user cookie to ESI
Solution: Rewrite cookie to HTTP header
Create ESI to show login / logout box
Would be nice if WordPress could generate that for use while still using an ESI...
Authenticating the ESI
We can authenticate the request by looking at the headers
Contacting the backend
We can grab the login form from the backend URL
Backend response
Grabbing the post content
Varnish Cache
rules
Subscriber
Edge Side Include: Content
Edge Side Include: Login form
Case Study - Aftonbladet Plus locking
What we’ve learned
Sources & credits
May the traffic be with you!
ESI vs AJAX
The problem:
Scaling at high traffic levels
What do we want?
A typical high-traffic setup: Hardware
Database cluster
Load-balancing & caching proxy
Web servers
NoSQL storage
HTTP
MySQL
Other
A typical high-traffic setup: Software
MySQL
Varnish
nginx /
php-fpm
Memcached
HTTP
MySQL
Other
WordPress generation time