Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
How Shopify Scales Rails
Search
John Duff
April 29, 2013
Technology
150
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
How Shopify Scales Rails
This talk goes into detail about how Shopify has been using and scaling rails up to now.
John Duff
April 29, 2013
More Decks by John Duff
See All by John Duff
Scaling a Payments Platform
jduff
0
98
Riding Rails for 10 Years
jduff
0
39
Other Decks in Technology
See All in Technology
AI × アーキテクト 第1・2章|生成AIの課題とアーキテクトの素養
daidaidai
0
170
遠藤な_めぐろLT #38 「社内のAI活用推進」@麻布台_20261009
endonanana
0
130
AI駆動開発の時代になったのでトヨタ生産方式から見直す
terurou
7
6k
AIがコードを書く時代に、エンジニアは何で自分の価値を証明するのか / In an era where AI writes code how do engineers prove their value
carta_engineering
3
1.1k
DevelopersIO 2026 知識の地図を描く ─ オントロジーとは何か?
ishikawa_satoru
1
1.7k
夫婦で子育てするための育児標準化
codmoninc
PRO
0
330
実践! SRE × AI - ABEMA における AIOps -
tetsuya28
8
3.1k
USB PDを使ってスマホを労わりたい
raspython3
0
180
Temporal 最高!でも改めて「日付」について調べたら人類の負債すぎる件
riyaamemiya
0
140
Refining Active Record
shugo
0
150
Kiro Crewをはじめよう
kizawa2020
1
160
宣言型部分更新は何を解決しどこへ向かうのか
shuta13
1
450
Featured
See All Featured
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
2
360
Abbi's Birthday
coloredviolet
4
10k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
Raft: Consensus for Rubyists
vanstee
142
7.8k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
330
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Building AI with AI
inesmontani
PRO
1
1.3k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Transcript
shopi fy How Shopify Scales Rails John Duff
What is Shopify?
None
None
None
The Stack
• Ruby 1.9.3-p327 • Rails 3.2 • Percona MySQL 5.5
• Unicorn 4.5 • Memcached 1.4.14 • Redis 2.6 The Stack
The Stack • 33 App Servers • 1172 Unicorn Workers
• 5 Job Servers • 370 Job Workers Nginx Unicorn Rails 3.2 Ruby 1.9.3- p327
The Stack Firewall Load Balancer App Servers Redis Job Servers
Database Memcached Search
• 55,873 Lines of application code • 81,892 Lines of
test code • 211 Controllers • 468 Models The Stack
Current Scale
9.9 M Orders An order every 3.2 seconds
2,008 Sales per Minute Cyber Monday
50,000 RPM 45 ms response time
13.3 billion requests
Looking Back, to Look Ahead
• First line of code written in 2004 • Shopify
released July, 2005 • Same codebase • Over 9 years of Rails upgrades, improvements and changes Looking Back, to Look Ahead
Looking Back, to Look Ahead • 6,702 Lines of application
code (55,873) • 4,386 Lines of test code (81,892) • 38 Controllers (211) • 77 Models (468)
Looking Back, to Look Ahead • Ruby 1.8.2 • Rails
0.13.1 • MySQL 4.1 • Lighttpd • Memcached
Know The System
One Request, One Process
RPM = W * 1/R
RPM = 1172 * 60 / 0.072
976,666 = 1172 * 60 / 0.072
↑ Workers ↓ Response Time
Know The System • Avoid network calls during requests •
Speed up unavoidable network calls • The Storefront and Checkout • The Chive
RPM Chive Flash Sale
Measure ALL THE THINGS
Measure ALL THE THINGS • New Relic • Splunk •
StatsD • Cacti • Conan
New Relic
Splunk
None
None
Caching
cacheable
cacheable • https://github.com/Shopify/cacheable • serve gzip’d content • generational caching
• no explicit expiry
cacheable class PostsController < ApplicationController def show response_cache do @post
= @shop.posts.find(params[:id]) respond_with(@post) end end def cache_key_data { :action => action_name, :format => request.format, :params => params.slice(:id), :shop_version => @shop.version } end end
requests Caching 404s
Identity Cache
Identity Cache • cache full model objects in memcached •
can include associated objects in cache • must opt in to the cache • explicit, but automatic expiry
Identity Cache class Product < ActiveRecord::Base include IdentityCache has_many :images
cache_index [:shop_id, :id] cache_has_many :images, :embed => true end @product = Product.fetch_by_shop_id_and_id(shop_id, id) @images = @product.fetch_images
Identity Cache
Get Out of My Process
Delayed Job • Jobs stored in the db • Workers
run in their own process • Workers poll for jobs periodically • https://github.com/collectiveidea/delayed_job
Resque • Redis backed • No more db contention •
Faster (300 jobs/sec vs 120 jobs/sec) • Extensible • https://github.com/defunkt/resque
Resque • Sending Email • Processing Payments • Geolocation •
Import / Export • Indexing for Search • 86 Other things...
Background Payment Processing ms
Resque class AddressGeolocationJob max_retries 3 def self.perform(params) object = params[:model].constantize.find(params[:id])
object.latitude, object.longitude = Geocoder.geocode(object) object.save! end end Resque.enqueue(AddressGeolocationJob, :id => 1, :model => 'Address')
Redis • Inventory reservation system • Sessions • Theme uploads
• Throttling • Sequenced Column
All Roads Lead To MySQL
MySQL Hardware • 4 x 8 Core Processor • SSD
• 256 GB Ram • Full working set in memory
MySQL Query Optimization • pt-query-digest • Avoid queries that generate
temp tables • Adding the right indexes • Forcing / Ignoring Indexes
MySQL Tuning • disable innodb_stats_on_metadata • increase table_open_cache • replace
glibc memory allocator with tcmalloc • innodb_autoinc_lock_mode=‘interleaved’
after_commit db transactions best friend
after_commit • After transaction has been committed • Webhooks •
Cache expiry • Update associated objects
after_commit class OrderObserver < ActiveRecord::Observer observe :order def after_save(order) if
order.changes.keys.include?(:financial_status) order.flag_for_after_commit(:update_customer) end end def after_commit(order) if order.flagged_for_after_commit?(:update_customer) Resque.enqueue(UpdateCustomerJob, :id => order.id) end end end
Services
Services • Split out standalone services as needed • Independently
scaled • Segmented metrics • Overall system is more complex • Limit to what is necessary
Imagery
Adapt and Evolve as Needed Using data and knowledge of
the system to drive decisions
Thanks. @johnduff |
[email protected]