SlideShare a Scribd company logo
1 / 58
1?GJQ?AFGLE 
 JCV?LBPS*CQXCE 
	2MDRU?PC#CTCJMNCP/(3$'
/+42
 
2 / 58
3FGQGQ1?GJQ
FMUF?PBA?LGR@C 
3 / 58
3FGQGQ1?GJQ
FMUF?PBA?LGR@C 
% cache @user do % 
%= render partial: 'user' % 
% end % 
4 / 58
3F?LIWMSDMPWMSPRGKC 
5 / 58
3./(2 
6 / 58
3./(2 
6'8 
DP?EKCLRA?AFGLE 
20+A?AFGLE 
'33/?AFGLE 
CVNGP?RGML 
7 / 58
6'8 
8 / 58
6'8 
9 / 58
%P?EKCLR?AFGLE 
cache small pieces of information instead of full pages 
10 / 58
#MLMRCVNGPCICWQ 
,MBCJ?QQMAG?RGMLQEMTCPLCVNGPW 
-CQRCBA?AFGLEGQ@CQR 
11 / 58
#MLMRCVNGPCICWQ 
12 / 58
A?AFC=ICW 
SQCP4QCPDGPQR 
= User id: 1, updated_at: 2014-10-02 18:12:57 
SQCPA?AFC=ICW 
= users/1-20141002181257446781000 
13 / 58
A?AFC=ICW 
SQCP4QCPDGPQR 
= User id: 1 , updated_at: 2014-10-02 18:12:57 
SQCPA?AFC=ICW 
= users/1-20141002181257446781000 
14 / 58
% cache @user do % 
%= render partial: 'user' % 
% end % 
15 / 58
% cache @user do % 
%= render partial: 'user' % 
% end % 
%GPQRRGKCUCJM?BRFCN?EC 
Read fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
Write fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
 JJMRFCPN?ECJM?BQ 
Read fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
16 / 58
,MBCJ?QQMAG?RGMLQEMTCPLCVNGPW 
17 / 58
class Project 
has_many :todo_lists 
class TodoList 
belongs_to :project, touch: true 
has_many :todos 
class Todo 
belongs_to :todo_list, touch: true 
UFCLQMKCRFGLEAF?LECQ
GRQBGPCARN?PCLRGQ?JQMAF?LECB 
18 / 58
-CQRCBA?AFGLEGQ@CQR 
19 / 58
- @projects.each do |project| 
- cache ['project', project] do 
...project 
- project.todo_lists.each do |todo_list| 
- cache ['todo_list', todo_list] do 
...todo list 
- todo_list.todos.each do |todo_list| 
- cache ['todo', todo] do 
...todo 
UFCLQMKCRFGLEAF?LECQ
UCBMLRF?TCRMPCECLCP?RCRFCCLRGPC 
N?EC 
20 / 58
!CDMPC1?GJQ 
- @projects.each do |project| 
- cache ['v1', 'project', project] do 
21 / 58
1?GJQQMJTCQRFGQNPM@JCKUGRFA?AFCBGECQRQ 
A call to #cache in your views will now suffix a digest of the template and its 
dependencies. No longer will you need to worry about fragment cache 
dependencies and versioning! 
user.cache_key 
= users/1-20141002181257446781000 
Read fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
22 / 58
1?GJQQMJTCQRFGQNPM@JCKUGRFA?AFCBGECQRQ 
A call to #cache in your views will now suffix a digest of the template and its 
dependencies. No longer will you need to worry about fragment cache 
dependencies and versioning! 
user.cache_key 
= users/1-20141002181257446781000 
Read fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
23 / 58
1?GJQQMJTCQRFGQNPM@JCKUGRFA?AFCBGECQRQ 
A call to #cache in your views will now suffix a digest of the template and its 
dependencies. No longer will you need to worry about fragment cache 
dependencies and versioning! 
user.cache_key 
= users/1-20141002181257446781000 
Read fragment views/users/1-20141002181257446781000/ 
95a652b13f0fc5b7bc8785ac31b6b8b9 (1.2ms) 
There's a gem for that 
rails/cache_digests 
24 / 58
$VCPAGQC 
25 / 58
26 / 58
27 / 58
/CPQNCARGTCB?R? 
Or how to make your cache useless 
28 / 58
MLQGBCPRFCGKN?ARMD?QGLEJC@SRRML 
29 / 58
.col-sm-12.no-lr-padding.ticket-info 
.col-price-block 
%span.top-line 
From 
%span.ticket-price.bottom-line 
= formated_cheapest_ticket_price(activity) 
.col-tickets-left-block 
- unless activity.hide_remaining_tickets? 
%span.color-default.top-line 
Tickets left: 
%span.bottom-line 
= activity_tickets_left(activity) 
.col-attendees-block 
%span.top-line 
Attendees: 
%span.bottom-line 
= activity_attendees_count(activity) 
.user-buttons-block 
%a.btn.btn-wishlist.btn-85 
%span.event_wishlist_span 
= wishlisted_label(activity, current_user) 
30 / 58
hit rate? 
cache ['event', event] do 
turns into: 
cache ['event', event, current_user] do 
Hit rate: 1 / Event.count * User.count 
*probably should avoid 
31 / 58
2MJSRGMLQ 
32 / 58
2MJSRGMLQ 
,MTCGRAJGCLRQGBC 
.event-pod{data-wishlisted=#{ 
wishlisted_label(activity, current_user)}} 
$('.event-pod').each(function(){ 
$(this).find('.wishlisted_button').html( 
$(this.data('wishlisted')) 
); 
}) 
??? 
This is good if you want to decouple the usere data or generate it in 
Also good for edge caching. 
*extra complexity 
33 / 58
3FCPCQECKDMPRF?R 
34 / 58
neighborland/cache_rocket 
= render_cached 'outer', replace: 'inner' 
outer.html.haml 
- cache 'outer' do 
.lots 
.of 
.htmls 
= cache_replace_key 'inner' 
inner.html.haml 
= uncacheable_content 
35 / 58
36 / 58
@CLCDGRQ 
A?AFCKMPCQRSDD 
more hits 
faster pages 
JCQQQRSDDGLA?AFC 
more hits 
less RAM used 
37 / 58
3FCD?QRCQRAMBCGQLMAMBC 
38 / 58
3FCD?QRCQRAMBCGQLMAMBC 
+CTCP?ECRFC@PMUQCPA?AFC 
39 / 58
def show 
@article = Article.find(params[:id]) 
if stale?(:etag = @article, :last_modified 
= @article.created_at.utc) 
@statistics = @article.really_expensive_call 
respond_to do |format| 
# all the supported formats 
end 
end 
end 
40 / 58
def show 
@article = Article.find(params[:id]) 
if stale?(:etag = @article, :last_modified 
= @article.created_at.utc) 
@statistics = @article.really_expensive_call 
respond_to do |format| 
# all the supported formats 
end 
end 
end 
41 / 58
def show 
@article = Article.find(params[:id]) 
if stale?(:etag = @article, :last_modified 
= @article.created_at.utc) 
@statistics = @article.really_expensive_call 
respond_to do |format| 
# all the supported formats 
end 
end 
end 
= 304 Not Modified 
42 / 58
$BECA?AFGLE 
Cloudfront 
Akamai 
fastly 
Varnish... 
43 / 58
%MJJMURFCQCPSJCQ 
CTCPWRFGLEAMKKMLGQQCPTCBGLRFCGLGRG?JPCOSCQR 
NCPQNCARGTCB?R?BMLCUGRFHQGL?BGDDCPCLRFRRNPCOSCQR 
CVNGP?RGMLGQF?LBJCB@W'33/FC?BCPQ 
44 / 58
Cache-Control: public - Any cache can store a copy of the content. 
Cache-Control: private - Don't store, this is for a single user. 
Cache-Control: no-cache - Re-validate before serving this content. 
Cache-Control: no-store - Don't store this content. Ever. At all. Please. 
Cache-Control: public, max-age=[seconds] - Caches can store this content for n 
seconds. 
Cache-Control: s-maxage=[seconds] - Same as max-age but applies specifically 
to proxy 
45 / 58
6F?R?@MSRKWKMBCJQ 
46 / 58
class SuggestionsController 
def show 
@users = Rails.cache.fetch(['users', params['page']]) do 
# we need to call .all to hit the database otherwise 
# we cache only the ruby query object 
User.suggestions.page(params['page']).all 
end 
end 
end 
*all is for rails3 
47 / 58
'MUBMGCVNGPCRF?R 
48 / 58
'MUBMGCVNGPCRF?R 
49 / 58
3FCPCQ?ECKDMPRF?R 
ahawkins/cashier 
50 / 58
3?E@?QCBA?AFGLE 
Instead of using updated_at to cause a cache miss, record where your objects 
are cached 
cache @something, tag: ['dashboard', 'settings'] 
@users = Rails.cache.fetch(['users', params['page']], 
tag: 'users') do 
# we need to call .all to hit the database otherwise 
# we cache only the ruby query object 
User.suggestions.page(params['page']).all 
end 
... 
User#after_commit 
... 
Cashier.expire users 
51 / 58
!SRGU?LRFMSPJWSNB?RCQMLKWFMKCN?EC
 
MFNJC?QCUGJJWMSFCJNKC 
52 / 58
!SRGU?LRFMSPJWSNB?RCQMLKWFMKCN?EC
 
MFNJC?QCUGJJWMSFCJNKC 
cache 'homepage', expires_in: 1.hour do 
53 / 58
3FGQRFGLEBMCQLRSNB?RC
GU?LR?@SRRML 
RMLSICCTCPWRFGLE 
class NukesController 
def create 
expire_fragment('homepage'); 
end 
end 
54 / 58
'MUUCJJGQGRUMPIGLEDMPSQ 
55 / 58
6FCPCRMEMDPMKFCPC 
?AFGLEUGRF1?GJQ LMTCPTGCU 
(BCLRGRW?AFC 
,SJRGDCRAF%P?EKCLRQ 
2CAMLB+CTCJ?AFC 
56 / 58
3F?LIWMS 
57 / 58

More Related Content

PPTX
Angular Deep Directive
PDF
Rupicon 2014 Action pack
PDF
Rupicon2014 useful design patterns in rails
PDF
Rupicon 2014 solid
PPTX
Ror caching
PDF
Real World Caching with Ruby on Rails
PPTX
Rails caching
PDF
Kickin' Ass with Cache-Fu (without notes)
 
Angular Deep Directive
Rupicon 2014 Action pack
Rupicon2014 useful design patterns in rails
Rupicon 2014 solid
Ror caching
Real World Caching with Ruby on Rails
Rails caching
Kickin' Ass with Cache-Fu (without notes)
 

Similar to Rupicon 2014 caching (20)

PPT
Caching By Nyros Developer
PDF
Caching your rails application
PPTX
Accelerating Rails with edge caching
PDF
Como construir uma Aplicação que consuma e produza updates no Twitter usando ...
PDF
Rails Caching: Secrets From the Edge
PDF
Rails Caching Secrets from the Edge
PDF
Memcached Presentation @757rb
PPTX
Day 7 - Make it Fast
PDF
Rails 4.0
PDF
What's new in Rails 4
PDF
Wiktor Schmidt, RuPy 2008, Caching in Rails
PDF
Performance on Rails
PDF
Caching/Expiring in Rails
PDF
Scaling Twitter
PDF
Caching on the web
PDF
Scaling Twitter 12758
PDF
Caching and Scaling WordPress using Fragment Caching
PPTX
Mini-Training: To cache or not to cache
PDF
杨卫华:微博cache设计浅谈
PDF
Tup2 新浪杨卫华
Caching By Nyros Developer
Caching your rails application
Accelerating Rails with edge caching
Como construir uma Aplicação que consuma e produza updates no Twitter usando ...
Rails Caching: Secrets From the Edge
Rails Caching Secrets from the Edge
Memcached Presentation @757rb
Day 7 - Make it Fast
Rails 4.0
What's new in Rails 4
Wiktor Schmidt, RuPy 2008, Caching in Rails
Performance on Rails
Caching/Expiring in Rails
Scaling Twitter
Caching on the web
Scaling Twitter 12758
Caching and Scaling WordPress using Fragment Caching
Mini-Training: To cache or not to cache
杨卫华:微博cache设计浅谈
Tup2 新浪杨卫华
Ad

Rupicon 2014 caching