Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cheating Your Way to Webscale
Search
Matt Robenolt
May 02, 2014
Programming
13
1.4k
Cheating Your Way to Webscale
Python Nordeste, May 2nd 2014
Matt Robenolt
May 02, 2014
Tweet
Share
More Decks by Matt Robenolt
See All by Matt Robenolt
Everything is broken and I don't know why.
mattrobenolt
0
44
I am bad at my job.
mattrobenolt
0
200
Everything is broken, and I don't know why. Python edition.
mattrobenolt
1
200
Everything is broken, and I don't know why. Python edition.
mattrobenolt
2
580
Varnish: How We Do It
mattrobenolt
1
220
Everything is broken, and I don't know why.
mattrobenolt
7
1.5k
HTTP for Great Good
mattrobenolt
85
200k
Caching is Hard: Varnish @ Disqus
mattrobenolt
52
2.1M
Developing & Deploying "Large" Scale Web Applications
mattrobenolt
25
1.3k
Other Decks in Programming
See All in Programming
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
300
kiroとCodexで最高のSpec駆動開発を!!数時間で web3ネイティブなミニゲームを作ってみたよ!
mashharuki
0
940
あなたとKaigi on Rails / Kaigi on Rails + You
shimoju
0
190
Blazing Fast UI Development with Compose Hot Reload (droidcon London 2025)
zsmb
0
260
登壇は dynamic! な営みである / speech is dynamic
da1chi
0
360
モテるデスク環境
mozumasu
3
1.3k
Building, Deploying, and Monitoring Ruby Web Applications with Falcon (Kaigi on Rails 2025)
ioquatix
4
2.5k
なんでRustの環境構築してないのにRust製のツールが動くの? / Why Do Rust-Based Tools Run Without a Rust Environment?
ssssota
14
46k
Reactive Thinking with Signals and the Resource API
manfredsteyer
PRO
0
120
What's new in Spring Modulith?
olivergierke
1
170
CSC509 Lecture 07
javiergs
PRO
0
250
フロントエンド開発のためのブラウザ組み込みAI入門
masashi
7
3.6k
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
57
5.9k
Bash Introduction
62gerente
615
210k
The Art of Programming - Codeland 2020
erikaheidi
56
14k
Designing for humans not robots
tammielis
254
26k
Reflections from 52 weeks, 52 projects
jeffersonlam
354
21k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
620
Understanding Cognitive Biases in Performance Measurement
bluesmoon
31
2.7k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
A designer walks into a library…
pauljervisheath
209
24k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
Stop Working from a Prison Cell
hatefulcrawdad
272
21k
Transcript
Python Nordeste May 2nd 2014 Matt Robenolt Cheating Your Way
to #webscale
Hello < me irl
Lead Operations Engineer
Core Contributor
So what is #webscale?
10 million requests per second 4ms mean response time asynchronous
io mongodb
10 million requests per second 4ms mean response time asynchronous
io mongodb NOPE
Disqus only does 150 req/s per web server. * we
also write some bad code
150 12,960,000 388,800,000 per second per day per month real
world #webscale
Scale is about hiding the fact that your application is
actually really slow.
If your application feels fast, then it’s probably good enough.
Users hate waiting for shit.
So how do we do it?
Cheating 101
When a user asks for new data, let’s give them
old data instead.
When a user asks for new data, let’s give them
old data instead. Caching
When telling us to do something, let’s say we did
and maybe do it later.
When telling us to do something, let’s say we did
and maybe do it later. Queueing
Rule #1 Don’t get caught.
Rule #2 Don’t get caught.
Rule #3 Don’t get caught.
HTTP Caching
Introducing
tl;dr Varnish sits between your application and your users Internet
Let’s talk about HTTP. Hypertext Transport Protocol
$ curl -v disqus.com
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Request
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Method
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Path
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Version
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Headers
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Response
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Status
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 Headers
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 For 300 seconds, all users will get the same response without talking to our application.
> GET / HTTP/1.1 > User-Agent: curl/7.24.0 > Host: disqus.com
> Accept: */* > < HTTP/1.1 200 OK < Server: nginx < Date: Fri, 02 May 2014 06:38:37 GMT < Content-Type: text/html; charset=utf-8 < Content-Length: 10453 < Last-Modified: Fri, 30 Aug 2013 00:32:14 GMT < Vary: Accept-Encoding < Expires: Fri, 02 May 2014 06:43:36 GMT < Cache-Control: public, max-age=300 With power comes great responsibility.
GET / INTERNET Varnish Web servers
GET / INTERNET Varnish Web servers CACHED! “Cache-Control: max-age=300”
GET / INTERNET Varnish Web servers
GET / INTERNET Varnish Web servers CACHED!
BUT WAIT… THERE’S MORE
COLLAPSING REQUEST
GET / INTERNET Varnish Web servers
INTERNET Varnish Web servers GET /
INTERNET Varnish Web servers GET / If multiple users request
the same object, Varnish makes one fetch and returns to all users.
Queueing
Do as little work as possible, and return a promise
that this work will be done.
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo Workers can rate limit, debounce, increment counters, generate a fast materialized view, etc.
INTERNET Web servers Task workers Slow/Fast Data store Queue POST
/foo Make sure your tasks finish before a user tries to read the data back.
Final Thoughts
Understand your application. Where can you cheat without disrupting user
experience? Is seeing a few seconds old data going to damage a product?
Cheating should only enhance user experience.
Cheat any way you can, just don’t get caught.
Django & Varnish & RabbitMQ & Celery & PostgreSQL &
Redis & Cassandra & Riak Thanks
Questions? I have answers. ^ github.com/mattrobenolt @mattrobenolt some