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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Matt Robenolt
May 02, 2014
Programming
1.4k
13
Share
Cheating Your Way to Webscale
Python Nordeste, May 2nd 2014
Matt Robenolt
May 02, 2014
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
230
Everything is broken, and I don't know why. Python edition.
mattrobenolt
1
220
Everything is broken, and I don't know why. Python edition.
mattrobenolt
2
620
Varnish: How We Do It
mattrobenolt
1
240
Everything is broken, and I don't know why.
mattrobenolt
7
1.6k
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
ソフトウェア設計の結合バランス #phperkaigi
kajitack
0
480
🦞OpenClaw works with AWS
licux
1
320
How We Practice Exploratory Testing in Iterative Development( #scrumniigata ) / 反復開発の中で、探索的テストをどう実施しているか
teyamagu
PRO
3
610
AIベース静的検査器の偽陽性率を抑える工夫3選
orgachem
PRO
4
410
ローカルLLMでどこまでコードが書けるか / How much code can be written on a local LLM
kishida
2
190
How Swift's Type System Guides AI Agents
koher
0
330
20年以上続くプロダクトでも使い続けられる静的解析ツールを求めて
matsuo_atsushi
0
130
リセットCSSを1行消したらアクセシビリティが向上した話
pvcresin
4
450
(Re)make Regexp in Ruby: Democratizing internals for the JIT
makenowjust
3
970
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
330
My daily life on Ruby
a_matsuda
2
160
セグメントとターゲットを意識するプロポーザルの書き方 〜採択の鍵は、誰に刺すかを見極めるマーケティング戦略にある〜
m3m0r7
PRO
0
730
Featured
See All Featured
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
170
エンジニアに許された特別な時間の終わり
watany
106
240k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
10k
How to Grow Your eCommerce with AI & Automation
katarinadahlin
PRO
1
180
GitHub's CSS Performance
jonrohan
1032
470k
Six Lessons from altMBA
skipperchong
29
4.2k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
410
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
380
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
560
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