You’ll Never Believe Which Web
Framework Powers Upworthy
Luigi Montanez, Founding Engineer
Ryan Resella, Senior Engineer
!
RailsConf 2014
Slide 2
Slide 2 text
No content
Slide 3
Slide 3 text
Luigi Montanez
Founding Engineer
@1uigi
Slide 4
Slide 4 text
Ryan Resella
Senior Engineer
@ryanresella
Slide 5
Slide 5 text
Mission: To drive massive
amounts of attention to the
topics that matter most.
Slide 6
Slide 6 text
“topics that
matter most”
Slide 7
Slide 7 text
“massive amounts of attention”
really means
“massive amounts of traffic”
Slide 8
Slide 8 text
Monthly Uniques
Slide 9
Slide 9 text
Quantcast Ranking
Slide 10
Slide 10 text
24 Hour Traffic Graph
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
No content
Slide 13
Slide 13 text
No content
Slide 14
Slide 14 text
No content
Slide 15
Slide 15 text
Our topic: Managing the
growth of a startup’s web app
in the face of very high traffic*
* Yes, it can happen to you!
Slide 16
Slide 16 text
In the beginning…
Slide 17
Slide 17 text
February
2012
April
2014
Initial
commit
March
2013
Launch!
Slide 18
Slide 18 text
“The elegant web framework”
Slide 19
Slide 19 text
What is Padrino?
• Sinatra++
• Stole great ideas from Django
• First-class mountable apps
• Middleware-centric
• Built-in Admin area
Slide 20
Slide 20 text
Why Padrino?!
Slide 21
Slide 21 text
All web
frameworks
fundamentally
exist to:
Emit HTML,
CSS, JSON, &
JavaScript
Slide 22
Slide 22 text
Padrino: The Good Parts
• It’s just Ruby. It’s just Rack.
• Less magic.
• Unopinionated.
• Writing middleware is fun!
• It’s light and performant.
Slide 23
Slide 23 text
Padrino: Architecture
Main
(Public)
Admin
(CMS)
RedisCache
Content
Request
Publisher
Slide 24
Slide 24 text
February
2012
April
2014
Initial
commit
March
2013
2nd Rails engineer
Slide 25
Slide 25 text
Padrino Pain Points
• Ecosystem for libraries not as strong as Rails.
• Infrequently maintained.*
• Admin system was ugly.*
• No real community.
• Easier to hire Rails developers than Padrino developers.
Slide 26
Slide 26 text
The Big Move
Slide 27
Slide 27 text
February
2012
April
2014
Initial
commit
March
2013
Create Rails app,
mount Padrino inside
Slide 28
Slide 28 text
Padrino Rails
1. Generate Rails app. Stick Padrino app in lib/upworthy & mount it in
routes.rb.
2. Migrate models and utilities.
3. Migrate assets.
4. Migrate front-end views and controllers.
5. Migrate CMS views to Bootstrap and use Rails controllers.
Slide 29
Slide 29 text
February
2012
April
2014
Initial
commit
March
2013
Create Rails app,
mount Padrino inside
Delete final
Padrino code
Slide 30
Slide 30 text
Rails: Architecture
Slide 31
Slide 31 text
Scaling The Monorail,
Phase 1
• Action caching for content pages, backed by memcached.
• Assets on S3 & Cloudfront.
• Lots of Heroku dynos (AJAX requests). Up to 40 during traffic spikes.
Slide 32
Slide 32 text
Scaling The Monorail,
Phase 2
• Move all HTML, CSS, JS, & images to Fastly CDN.
• Turn off Rails action caching. Manually set cache headers.
• Dial down Heroku dynos. Only needed for AJAX requests. (We currently
use 2X dynos.)
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
Monorail Pain Points
• One Rails app that dealt with both front-end and back-end concerns.
• Traffic spikes on public site could render CMS unusable.
• Codebase becomes very large. God objects starting to appear.
Slide 35
Slide 35 text
The
Breakup
Slide 36
Slide 36 text
February
2012
April
2014
Initial
commit
March
2013
Create Rails app,
mount Padrino inside
Delete final
Padrino code
Split up
Rails monolith
Slide 37
Slide 37 text
Monorail Services
1. Decide on how many services to split into. We chose two: www and cms.
2. Clone monorail into separate git repos to maintain history.
3. Split up controllers, views, assets and concerns.
Slide 38
Slide 38 text
Monorail Services
!
!
!
4. Deploy each app to separate Heroku applications.
5. Switch Fastly to point at new www app. Resulted in zero downtime.
6. De-duplicate code between the two apps, creating a core gem (mostly
models) to keep code DRY.
Slide 39
Slide 39 text
Service-Oriented Architecture
Fastly
www
core
cms
Public
Visitor
!
CMS
User
Slide 40
Slide 40 text
SOA Benefits
• Instability in one app doesn’t affect the other app.
• Apps have different scaling needs.
• Divides teamwork more naturally. Less blocking on features.
Slide 41
Slide 41 text
SOA Drawbacks
• Must run N apps in development to exercise the full system.
• Coordinate deploys amongst N apps.
• Migrating to a fully DRY set of codebases is tedious.
• “What goes where?”
Slide 42
Slide 42 text
Future Work
• Continue adding code to core gem and removing duplication from the
apps.
• Consider breaking up apps even more. For example, www can be split
into a static site generator and an AJAX API service.
• Apps communicate by sharing data stores. Should they communicate via
RESTful APIs instead?
Slide 43
Slide 43 text
Lessons Learned
• Wait to make changes to your technical architecture until it really hurts.
• It’s okay to take a really long time to migrate to the better technology.
• Serve everything you possibly can from a CDN.
• Remember: it’s just HTML, CSS, JavaScript, and JSON.
• It can happen to you!
Slide 44
Slide 44 text
Questions?
Luigi Montanez // @1uigi
Ryan Resella // @ryanresella
!
Slides & writeup: upworthy.github.io
The answers will surprise you.