SlideShare a Scribd company logo
1 of 173
Slow websites
SUCK
WEB PERFORMANCE IS AN ESSENTIAL
PART OF THE USER EXPERIENCE
SLOW~DOWN
THROWING
SERVERS
ATTHEPROBLEM
MO' MONEY
MO' SERVERS
MO' PROBLEMS
IDENTIFY SLOWEST PARTS
OPTIMIZE
AFTER A WHILE YOU HIT THE LIMITS
CACHE
HI, I'M THIJS
I'M THE TECH
EVANGELIST
AT
10,000,000 WEBSITES
21% OF THE TOP 10K WEBSITES
I'M @THIJSFERYN
CACHING
WHY
CACHE
HIGHER
CONCURRENCY
HIGHER
THROUGHPUT
LOWER LATENCY
IMPROVE QUALITY OF EXPERIENCE
WHY
RECOMPUTE
IF THE DATA
HASN'T
CHANGED?
DIFFERENT KINDS OF CACHING
✓ LOCAL KEY-VALUE STORE
✓ FILE CACHE
✓ DISTRIBUTE CACHE
✓ BROWSER CACHE
✓ REVERSE CACHING PROXY
✓ CONTENT DELIVERY NETWORK
USER SERVER
USER SERVER
BROWSER CACHE
USER SERVER
SERVER CACHE
USER PROXY SERVER
USER PROXY SERVER
REVERSE
CACHING
PROXY
USER PROXY SERVER
THE EDGE
USER VARNISH SERVER
THE EDGE
USER VARNISH SERVER
THE ORIGIN
EVERY
IMPLEMENTATION
HAS ITS OWN
CACHE POLICY
CONFIGURATION
HTTP HAS CONVENTIONAL
BUILT-IN CACHING
MECHANISMS
Expires: Mon, 20 Feb 2023 21:31:06 GMT
LIMITED OPTIONS
Cache-Control: public, max-age=500
Cache-Control: private, no-cache, no-store
KEY CACHING CONCEPTS
CACHING
HOLD THE RESPONSE AND SERVE IT AGAIN UPON
SUBSEQUENT REQUESTS
PRIVATE CACHE
A CACHE THAT EXISTS IN THE CLIENT.
E.G. A LOCAL DEVICE OR BROWSER CACHE.
STORES DATA FOR A SINGLE USER.
SHARED CACHE
A CACHE THAT SERVES MULTIPLE USERS.
USUALLY A CACHING PROXY OR CDN.
YOU SHOULD AVOID STORING PERSONALIZED DATA.
TIME TO LIVE
THE AMOUNT OF SECONDS AN OBJECT IS
CONSIDERED FRESH.
FRESH CONTENT
CACHED OBJECT HASN'T EXPIRED YET.
RESPONSE CAN BE REUSED FOR SUBSEQUENT
REQUESTS.
STALE CONTENT
EXPIRED CONTENT THAT SHOULD BE REVALIDATED
BEFORE SERVING. IS NOT DIRECTLY REMOVED FROM
THE CACHE.
REVALIDATE CONTENT
ASK THE ORIGIN SERVER IF THE REQUESTED OBJECT
IS STILL FRESH.
CACHE-CONTROL RESPONSE DIRECTIVES
✓ PRIVATE
✓ PUBLIC
✓ IMMUTABLE
✓ MAX-AGE
✓ S-MAXAGE
✓ NO-CACHE
✓ NO-STORE
✓ NO-TRANSFORM
✓ MUST-REVALIDATE
✓ PROXY-REVALIDATE
✓ MUST-UNDERSTAND
✓ STALE-WHILE-REVALIDATE
✓ STALE-IF-ERROR
Cache-Control: public
Cache-Control: public
CACHING ALLOWED, BOTH BY PRIVATE & SHARED CACHES
Cache-Control: public
CACHING ALLOWED, BOTH BY PRIVATE & SHARED CACHES
PROXY
SERVERS
BROWSER
USER PROXY SERVER
PUBLIC
CACHE
PRIVATE
CACHE
Cache-Control: private
Cache-Control: private
CACHING ALLOWED, BUT ONLY BY PRIVATE CACHES
Cache-Control: private=Set-Cookie
Cache-Control: private=Set-Cookie
CACHING ALLOWED BY ALL CACHES, UNLESS A SET-COOKIE
HEADER IS SET. THEN THE RESPONSE IS ONLY HANDLED BY
PRIVATE CACHES
Cache-Control: public, max-age=100
Cache-Control: public, max-age=100
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 100 SECONDS.
Cache-Control: private, max-age=100
Cache-Control: private, max-age=100
ONLY PRIVATE CACHES ALLOWED.
CONTENT IS FRESH FOR 100 SECONDS.
Cache-Control: public, s-maxage=100
Cache-Control: public, s-maxage=100
ALL CACHES ALLOWED.
CONTENT IN SHARED CACHES IS FRESH FOR 100 SECONDS.
Cache-Control: public, max-age=60, s-maxage=100
Cache-Control: public, max-age=60, s-maxage=100
ALL CACHES ALLOWED.
CONTENT IN PRIVATE CACHES IS FRESH FOR 60 SECONDS.
CONTENT IN SHARED CACHES IS FRESH FOR 100 SECONDS.
Cache-Control: public, max-age=60
Age: 40
AGE HEADER DESCRIBES THE TIME IN SECONDS
THE OBJECT WAS IN A PROXY CACHE.
Remaining TTL = TTL - Age
REVALIDATION
USER PROXY ORIGIN
IS THE
CONTENT STILL
FRESH?
PROXY ORIGIN
GET / HTTP/1.1
HTTP/1.1 200 OK
CONDITIONAL REQUESTS
HTTP/1.1 304 Not Modified
CONDITIONAL REQUESTS
HTTP/1.1 200 OK
Host: localhost
Etag: 7c9d70604c6061da9bb9377d3f00eb27
Content-type: text/html; charset=UTF-8
Hello world output
GET / HTTP/1.1
Host: localhost
CONDITIONAL REQUESTS
HTTP/1.1 304 Not Modified
Host: localhost
Etag: 7c9d70604c6061da9bb9377d3f00eb27
GET / HTTP/1.1
Host: localhost
If-None-Match: 7c9d70604c6061da9bb9377d3f00eb27
CONDITIONAL REQUESTS
HTTP/1.1 200 OK
Host: localhost
Last-Modified: Fri, 22 Jul 2016 10:11:16 GMT
Content-type: text/html; charset=UTF-8
Hello world output
GET / HTTP/1.1
Host: localhost
CONDITIONAL REQUESTS
HTTP/1.1 304 Not Modified
Host: localhost
Last-Modified: Fri, 22 Jul 2016 10:11:16 GMT
GET / HTTP/1.1
Host: localhost
If-Last-Modified: Fri, 22 Jul 2016 10:11:16 GMT
VALIDATE
QUICKLY
EARLY
STORE &
RETRIEVE
ETAG
ASYNCHRONOUS
REVALIDATION
USER PROXY ORIGIN
ASYNC FETCH
SEND STALE
RESPONSE WHILE
FETCHING
Cache-Control: public, max-age=3600, stale-
while-revalidate=100
Cache-Control: public, max-age=3600, stale-
while-revalidate=100
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
STALE CONTENT CAN BE SERVED UP TO 100 SECONDS PAST
THE TTL WHILE DOING AN ASYNCHRONOUS REVALIDATION.
USER PROXY ORIGIN
FETCH FAILED
SEND STALE
RESPONSE WHILE
FETCHING FAILS
Cache-Control: public, max-age=3600, stale-
if-error=86400
Cache-Control: public, max-age=3600, stale-
if-error=86400
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
STALE CONTENT CAN BE SERVED UP TO 1 DAY PAST THE TTL
WHILE THE ORIGIN IS UNREACHABLE.
Fresh = TTL > 0
Async revalidation = TTL + stale > 0
Synchronous revalidation = TTL + stale <= 0
Fresh = TTL > 0
Async revalidation = TTL + stale > 0
Synchronous revalidation = TTL + stale <= 0
REVALIDATION
CAN BE DONE
CONDITIONALLY
Cache-Control: public, max-age=3600, must-revalidate
Cache-Control: public, max-age=3600, must-revalidate
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
SERVING STALE CONTENT NOT ALLOWED.
Cache-Control: public, max-age=3600, proxy-revalidate
Cache-Control: public, max-age=3600, proxy-revalidate
SAME AS MUST-
REVALIDATE BUT FOR
PROXY SERVERS
Cache-Control: public, max-age=3600, must-understand
Cache-Control: public, max-age=3600, must-understand
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
ONLY STORE THE RESPONDS IF THE CACHE UNDERSTANDS
THE REQUIREMENTS BASED ON THE STATUS CODE
CACHEABLE STATUS CODES
✓200
✓203
✓204
✓300
✓301
✓304
✓404
✓410
✓414
Cache-Control: must-understand, no-store
USE NO-STORE AS A BACKUP IN CASE MUST-UNDERSTAND
IS NOT SUPPORTED BY THE CACHE
Cache-Control: public, max-age=86400, immutable
Cache-Control: public, max-age=86400, immutable
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
CONTENT WILL NOT BE UPDATED WHILE FRESH
Cache-Control: public, max-age=86400, immutable
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
CONTENT WILL NOT BE UPDATED WHILE FRESH
USEFUL FOR
BROWSER CACHING
Cache-Control: public, immutable
DATA IS
IMMUTABLE, ASSUME
HIGH TTL IN PROXY
CONTEXT
Cache-Control: public, max-age=3600, no-tranform
Cache-Control: public, max-age=3600, no-tranform
ALL CACHES ALLOWED.
CONTENT IS FRESH FOR 1 HOUR.
CONTENT CANNOT BE TRANSFORMED
BY INTERMEDIARY CACHES
Cache-Control: public, max-age=3600, no-tranform
EDGE COMPUTE
Cache-Control: no-cache
Cache-Control: no-cache
STORE OBJECT IN CACHE
BUT REVALIDATE BEFORE EVERY REUSE
Cache-Control: no-cache=Set-Cookie
STORE OBJECT IN CACHE
BUT REVALIDATE BEFORE EVERY REUSE
IF THE SET-COOKIE HEADER IS SET
Cache-Control: no-store
Cache-Control: no-store
DON'T STORE OBJECT IN THE CACHE
Cache-Control: private, no-cache, no-store
TYPICAL ONE
CACHE VARIATIONS
Vary: Accept-Language
‣ http://test.com/page1
-Accept-Language: nl
-Accept-Language: en
-Accept-Language: fr
‣ http://test.com/page2
-Accept-Language: nl
-Accept-Language: en
-Accept-Language: fr
GET /page1 HTTP/1.1
Host: test.com
Accept-Language: fr
GET /page2 HTTP/1.1
Host: test.com
Accept-Language: en
Vary: Accept-Encoding, Accept-Language,
X-Forwarded-Proto
SURROGATES
THE EDGE
CONTENT
DELIVERY
NETWORK
Surrogate-Control: max-age=300
Surrogate-Control: max-age=300+100
Surrogate-Control: max-age=300+100
STALENESS
Surrogate-Control: no-store
Surrogate-Control: no-store-remote,
max-age=3600
SURROGATE CAPABILITY
Surrogate-Capability: key="ESI/1.0"
Surrogate-Control: content="ESI/1.0"
Surrogate-Capability: varnish="ESI/1.0"
Surrogate-Control: max-age=60, max-
age=86400;varnish, max-age=3600;cdn,
content="ESI/1.0";varnish
FOR
MORE ABOUT
ESI & SURROGATES
WHAT IS SUPPORTED BY
VARNISH ?
WHAT IS SUPPORTED BY VARNISH
✓ EXPIRES
✓ VARY
✓ ETAG & IF-NONE-MATCH
✓ LAST-MODIFIED & IF-MODIFIED SINCE
✓ CACHE-CONTROL MAX-AGE & S-MAXAGE
✓ CACHE-CONTROL PRIVATE, NO-CACHE & NO-STORE
✓ CACHE-CONTROL STALE-WHILE-REVALIDATE
✓ SURROGATE-CONTROL: NO-STORE
LOOKING AT FULL SUPPORT OF
CACHE-CONTROL FOR THE
NEXT MAJOR RELEASE
(NO GUARANTEES)
VARNISH DOESN'T CACHE IF ...
✓ IF THE REQUEST METHOD IS NOT GET OR HEAD
✓ IF AN AUTHORIZATION HEADER IS IN THE REQUEST
✓ IF A COOKIE IS PART OF THE REQUEST
✓ IF MAX-AGE OR S-MAXAGE IS ZERO
✓ IF EXPIRES IS IN THE PAST
✓ IF NO-CACHE, NO-STORE OR PRIVATE IS SET IN
CACHE-CONTROL
VARNISH DOESN'T CACHE IF ...
✓ SURROGATE-CONTROL HAS NO-CACHE
✓ IF A SET-COOKIE HEADER IS PART OF THE RESPONSE
✓ IF VARY IS *
DOESN'T ALWAYS WORK
IN THE REAL WORLD
FOR YOUR EYES ONLY
NOT CACHED
VARNISH CONFIGURATION LANGUAGE
VCL CAPABILITIES
✓ REQUEST HANDLING
✓ REQUEST ROUTING
✓ RESPONSE MANIPULATION
✓ BACKEND SELECTION
✓ CONTROLLING THE CACHE
✓ DECISION-MAKING "ON THE EDGE"
vcl 4.1;
backend default {
.host = "127.0.0.1";
.port = "8080";
}
sub vcl_recv {
if(req.url ~ "^/admin(/.*|$)") {
return(pass);
}
unset req.http.Cookie;
}
I ANSWER TO #VARNISH
ON STACKOVERFLOW
OR FIND ME ON TWITTER
@THIJSFERYN
THE EDGE
SERVING CONTENT
ON THE EDGE
COMPUTING
ON THE EDGE
PERSONAL
DATA
NO CACHE
PLACEHOLDERS
SEPARATE
HTTP REQUEST
AJAX
EDGE-SIDE INCLUDES ESI
<esi:include src="/header" />
ESI
✓ PLACEHOLDER
✓ PARSED BY VARNISH
✓ OUTPUT IS A COMPOSITION OF BLOCKS
✓ STATE PER BLOCK
✓ TTL PER BLOCK
VARNISH Surrogate-Capability: key="ESI/1.0"
Surrogate-Control: content="ESI/1.0"
<esi:include src="/header" />
APPLICATION
Parse ESI placeholders
VARNISH
sub vcl_recv {
set req.http.Surrogate-Capability = "key=ESI/1.0";
}
sub vcl_backend_response {
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
<!DOCTYPE html>
<html>
<body>
<esi:include src="/header" />
<p>Welcome</p>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<p>The current time is 21:07:53.</p>
<p>Welcome</p>
</body>
</html>
HOW DO YOU IDENTIFY AN
OBJECT IN CACHE?
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
return (lookup);
}
HTTP/1.1 200 OK
Host: localhost
Content-Language: en
GET / HTTP/1.1
Host: localhost
Accept-Language: en
HTTP/1.1 200 OK
Host: localhost
Content-Language: en
GET / HTTP/1.1
Host: localhost
Accept-Language: nl
Vary: Accept-Language
YOU CAN DO ALL OF THIS IN VCL TOO
sub vcl_recv {
set req.http.Surrogate-Capability = "key=ESI/1.0";
}
sub vcl_backend_response {
set beresp.ttl = 1h;
set beresp.grace = 2h;
set beresp.http.Vary = "Accept-Language,
Accept-Encoding, X-Forwarded-Proto";
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_esi = true;
}
}
THIS IS JUST THE TIP OF THE ICEBERG
HTTPS://VARNISH-SOFTWARE.COM/DEVELOPERS
HTTP headers that will make your website go faster
HTTP headers that will make your website go faster

More Related Content

More from Thijs Feryn

More from Thijs Feryn (9)

Distributed Load Testing with k6 - DevOps Barcelona
Distributed Load Testing with k6 - DevOps BarcelonaDistributed Load Testing with k6 - DevOps Barcelona
Distributed Load Testing with k6 - DevOps Barcelona
 
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
Core web vitals meten om je site sneller te maken - Combell Partner Day 2023
 
Distributed load testing with k6
Distributed load testing with k6Distributed load testing with k6
Distributed load testing with k6
 
HTTP logging met Varnishlog - PHPWVL 2022
HTTP logging met Varnishlog - PHPWVL 2022HTTP logging met Varnishlog - PHPWVL 2022
HTTP logging met Varnishlog - PHPWVL 2022
 
Build your own CDN with Varnish - Confoo 2022
Build your own CDN with Varnish - Confoo 2022Build your own CDN with Varnish - Confoo 2022
Build your own CDN with Varnish - Confoo 2022
 
How Cloud addresses the needs of todays internet - Korazon 2018
How Cloud addresses the needs of todays internet - Korazon 2018How Cloud addresses the needs of todays internet - Korazon 2018
How Cloud addresses the needs of todays internet - Korazon 2018
 
Developing cacheable PHP applications - PHPLimburgBE 2018
Developing cacheable PHP applications - PHPLimburgBE 2018Developing cacheable PHP applications - PHPLimburgBE 2018
Developing cacheable PHP applications - PHPLimburgBE 2018
 
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
 
Developing cacheable PHP applications - Confoo 2018
Developing cacheable PHP applications - Confoo 2018Developing cacheable PHP applications - Confoo 2018
Developing cacheable PHP applications - Confoo 2018
 

Recently uploaded

Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
UXDXConf
 

Recently uploaded (20)

AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024What's New in Teams Calling, Meetings and Devices April 2024
What's New in Teams Calling, Meetings and Devices April 2024
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
Syngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdfSyngulon - Selection technology May 2024.pdf
Syngulon - Selection technology May 2024.pdf
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAK
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Optimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through ObservabilityOptimizing NoSQL Performance Through Observability
Optimizing NoSQL Performance Through Observability
 
A Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System StrategyA Business-Centric Approach to Design System Strategy
A Business-Centric Approach to Design System Strategy
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
The UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, OcadoThe UX of Automation by AJ King, Senior UX Researcher, Ocado
The UX of Automation by AJ King, Senior UX Researcher, Ocado
 
IESVE for Early Stage Design and Planning
IESVE for Early Stage Design and PlanningIESVE for Early Stage Design and Planning
IESVE for Early Stage Design and Planning
 
THE BEST IPTV in GERMANY for 2024: IPTVreel
THE BEST IPTV in  GERMANY for 2024: IPTVreelTHE BEST IPTV in  GERMANY for 2024: IPTVreel
THE BEST IPTV in GERMANY for 2024: IPTVreel
 
The Metaverse: Are We There Yet?
The  Metaverse:    Are   We  There  Yet?The  Metaverse:    Are   We  There  Yet?
The Metaverse: Are We There Yet?
 
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi IbrahimzadeFree and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
Free and Effective: Making Flows Publicly Accessible, Yumi Ibrahimzade
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
Choosing the Right FDO Deployment Model for Your Application _ Geoffrey at In...
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
Integrating Telephony Systems with Salesforce: Insights and Considerations, B...
 

HTTP headers that will make your website go faster