< Return to Video

RailsConf 2014 - You'll Never Believe Which Web Framework Powers Upworthy

  • 0:17 - 0:21
    LUIGI MONTANEZ: So, thank you everyone for
    coming.
  • 0:21 - 0:25
    It's late on Friday and I really appreciate
  • 0:25 - 0:31
    all of you sticking around. Obviously Tenderlove
    is next. So-
  • 0:31 - 0:32
    AUDIENCE: Talk louder!
  • 0:32 - 0:36
    L.M.: Talk louder? All right. That's be- is
    that
  • 0:36 - 0:40
    better? All right. So, before I get started,
    I
  • 0:40 - 0:43
    just want to actually do a quick plug, cause
  • 0:43 - 0:45
    I saw that the session behind me is actually
  • 0:45 - 0:48
    on the impostor syndrome. And since you folks
    are
  • 0:48 - 0:50
    not gonna be there to, to see that, I
  • 0:50 - 0:52
    just wanted to actually tell you a little
    bit
  • 0:52 - 0:54
    about it, cause actually it's a, it's a really
  • 0:54 - 0:57
    important concept. So, essentially, the impostor
    syndrome is when
  • 0:57 - 1:02
    successful people like software developers
    feel like they might
  • 1:02 - 1:05
    not deserve all the success they've gotten.
    And it's
  • 1:05 - 1:08
    actually very common. When I learned about
    it a
  • 1:08 - 1:09
    few years ago, it was actually really helpful
    for
  • 1:09 - 1:11
    me and my career. So when you go to
  • 1:11 - 1:14
    conferences like these and you see members
    of the
  • 1:14 - 1:17
    Rails core team or the Ember core team or
  • 1:17 - 1:20
    all the speakers and you think, wow, I am
  • 1:20 - 1:22
    not worthy, actually you are. You, you really
    do
  • 1:22 - 1:26
    belong here, and, and people who are successful
    usually
  • 1:26 - 1:29
    do deserve it. So Google the impostor syndrome
    when
  • 1:29 - 1:32
    you get home or, or watch the video when
  • 1:32 - 1:33
    it gets posted.
  • 1:33 - 1:37
    So to our talk. So. You will never believe
  • 1:37 - 1:41
    which web framework powers Upworthy. I, I
    can't believe
  • 1:41 - 1:46
    the conference organizers have made everyone
    wait all week
  • 1:46 - 1:50
    to figure this out, to find this out. So,
  • 1:50 - 1:52
    at Upworthy we aim to please. So we're just
  • 1:52 - 1:56
    gonna spill the beans right away. Obviously
    the answer
  • 1:56 - 1:57
    is Java Struts.
  • 1:57 - 1:59
    AUDIENCE: [applause]
  • 1:59 - 2:05
    L.M.: Awesome. Now. So. To introduce myself,
    my name's
  • 2:05 - 2:07
    Luigi. I'm the founding engineer at Upworthy.
    I was
  • 2:07 - 2:12
    the first engineer hired. I've always been
    a software
  • 2:12 - 2:15
    developer involved in politics and advocacy.
    I got really
  • 2:15 - 2:18
    into this guy who screened Howard Dean. And
    so
  • 2:18 - 2:21
    I worked for his political campaign. There
    was this
  • 2:21 - 2:24
    political action committee. I worked for other
    campaigns and
  • 2:24 - 2:26
    non-profits, and then before coming to Upworthy
    I worked
  • 2:26 - 2:30
    for the Sunlight Foundation, which is a great
    non-profit
  • 2:30 - 2:34
    in D.C. that focuses on transparency and government,
    and
  • 2:34 - 2:35
    open, open government data.
  • 2:35 - 2:38
    RYAN RESELLA: I'm Ryan Resella. I'm the senior
    engineer
  • 2:38 - 2:40
    at Upworthy. Before this in 2011 I was a
  • 2:40 - 2:43
    Code for America fellow, the first class of
    fellows.
  • 2:43 - 2:45
    I came on as technical lead full time staff
  • 2:45 - 2:48
    there. And then last year I was on the
  • 2:48 - 2:53
    Obama for America tech team, or, I guess 2012,
  • 2:53 - 2:56
    working as a software engineer. And I ran
    out
  • 2:56 - 2:58
    of for America organizations to work for so
    I
  • 2:58 - 2:59
    joined Upworthy.
  • 2:59 - 3:04
    L.M.: So, at Upworthy, our mission, and we,
    this
  • 3:04 - 3:06
    is something we truly really believe at the
    company
  • 3:06 - 3:09
    is to drive massive amounts of attention to
    the
  • 3:09 - 3:13
    topics that matter most. And that will kind
    of
  • 3:13 - 3:16
    inform the engineering decisions we made as
    the, as
  • 3:16 - 3:18
    the tech team. So, just to kind of give
  • 3:18 - 3:22
    people a little peak at what Upworthy does,
    for
  • 3:22 - 3:25
    those who aren't too familiar, so this might
    be
  • 3:25 - 3:26
    a bit hard to read, but when we say
  • 3:26 - 3:29
    that topics that matter most, these are kind
    of
  • 3:29 - 3:31
    the topics we've covered in the last year,
    the
  • 3:31 - 3:33
    topics that have gotten the most attention.
    So I'll
  • 3:33 - 3:35
    just read some of them aloud.
  • 3:35 - 3:39
    There's a lot of women's issues, like body
    image,
  • 3:39 - 3:44
    gender inequality, standards of beauty, a
    lot of economic
  • 3:44 - 3:49
    issues like income inequality, health policy.
    We also cover
  • 3:49 - 3:51
    a lot of stuff about disability, mental health.
    Also
  • 3:51 - 3:57
    bullying, bigotry, racial profiling and, and
    race issues. And
  • 3:57 - 3:59
    when we say that we want to drive massive
  • 3:59 - 4:03
    amounts of attention to these things, what
    we really
  • 4:03 - 4:07
    mean as web developers, as web engineers is
    we
  • 4:07 - 4:11
    want to drive massive amounts of traffic.
  • 4:11 - 4:14
    So here's a look at our growth for the
  • 4:14 - 4:16
    last two years. So we launched a little over
  • 4:16 - 4:23
    two years ago. We started off at, around one
  • 4:24 - 4:31
    point seven million uniques per month. That
    was in
  • 4:31 - 4:37
    our first ever month in April 2012. And then
  • 4:37 - 4:42
    we went up to, in November of 2013, 190
  • 4:42 - 4:46
    million page views. So, this has made us probably
  • 4:46 - 4:49
    around the top forty, a top forty site in
  • 4:49 - 4:53
    the U.S. We're maybe one of the larger Rails,
  • 4:53 - 4:57
    more trafficked Rails apps out there.
  • 4:57 - 4:58
    To give you a sense of what kind of
  • 4:58 - 5:00
    traffic we actually deal with, here's a twenty-four
    hour
  • 5:00 - 5:03
    graph of what our page view data looks like.
  • 5:03 - 5:05
    So starting at midnight all the way on the
  • 5:05 - 5:08
    left, and then ending midnight the next day,
    you
  • 5:08 - 5:10
    can kind of say how during the, when the
  • 5:10 - 5:13
    daytime happens, when, when work hours start,
    we get
  • 5:13 - 5:18
    these spikes, these peaks of, of, of traffic.
    This
  • 5:18 - 5:24
    is essentially viral, the viral cycle being
    visualized.
  • 5:24 - 5:31
    So, we have handled, at most, about 130,000
    concurrent
  • 5:31 - 5:35
    visitors. This is a screenshot from Google
    analytics during
  • 5:35 - 5:38
    one of the traffic spikes. So, you know, we,
  • 5:38 - 5:40
    we are handling large amounts of traffic in
    very
  • 5:40 - 5:44
    spiky ways.
  • 5:44 - 5:46
    So here is a example post from Upworthy. This
  • 5:46 - 5:50
    was really popular about, a few months ago,
    in
  • 5:50 - 5:53
    the fall really. Who here remembers this post?
    Just
  • 5:53 - 5:56
    curious. Cool. A few of you.
  • 5:56 - 6:00
    So this is what Upworthy content looks like.
    So
  • 6:00 - 6:01
    it's really just static content. So See Why
    We
  • 6:01 - 6:04
    Have An Absolutely Ridiculously Standard of
    Beauty in Just
  • 6:04 - 6:07
    37 Seconds. It's a video about how a, a
  • 6:07 - 6:13
    woman, a model gets photoshopped and looks
    essentially like
  • 6:13 - 6:15
    something, like the standard of beauty that
    doesn't really
  • 6:15 - 6:18
    exist. So that, that's kind of the content,
    or
  • 6:18 - 6:20
    angle we were going for. And here you see,
  • 6:20 - 6:24
    we have the content, which is basically static
    content
  • 6:24 - 6:26
    on the left side of the screen. We have
  • 6:26 - 6:29
    this sidebar with recommended content on the
    right side
  • 6:29 - 6:31
    of the screen. And then scrolling down, we
    have
  • 6:31 - 6:35
    what we call asks. We, we also do kind
  • 6:35 - 6:39
    of some testing on different kinds of content,
    different
  • 6:39 - 6:42
    kinds of headlines. You see that down there
    with
  • 6:42 - 6:45
    that John Stewart video. And then we have
    asks
  • 6:45 - 6:48
    around, do you want to subscribe to our email
  • 6:48 - 6:50
    list? Do you want to like us on Facebook?
  • 6:50 - 6:53
    We also have kind of pop-ups that happen after
  • 6:53 - 6:57
    you watch a video, after you share, also asking
  • 6:57 - 6:59
    you to do stuff.
  • 6:59 - 7:02
    So those are the things we, we, the technical
  • 7:02 - 7:05
    things we, the technical concerns we have
    at Upworthy.
  • 7:05 - 7:08
    We're pretty much a static site. We're a public
  • 7:08 - 7:11
    site. And then we have a CMS backing that,
  • 7:11 - 7:14
    and then we have this system of dynamic pop-ups
  • 7:14 - 7:18
    and asks around the site that kind of optimize
  • 7:18 - 7:20
    our subscriber base, get us more subscribers,
    get, get
  • 7:20 - 7:24
    folks to share content.
  • 7:24 - 7:28
    So, the topic of this talk will really be
  • 7:28 - 7:32
    about managing the growth of our start up's
    web
  • 7:32 - 7:37
    app in the face of very high traffic. And
  • 7:37 - 7:41
    I actually remember maybe five years ago sitting
    at
  • 7:41 - 7:44
    a RailsConf, maybe it was in Baltimore, and
    I
  • 7:44 - 7:46
    was sitting where you're sitting and it was
    a
  • 7:46 - 7:48
    talk, it was a talk by the guys from
  • 7:48 - 7:52
    YellowPages dot com. And YellowPages dot com
    was and
  • 7:52 - 7:55
    still is one of the larger Rails sites in
  • 7:55 - 7:58
    the world. Obviously YellowPages is such a
    strong brand.
  • 7:58 - 8:00
    Everyone goes to the YellowPages, a lot of
    people
  • 8:00 - 8:03
    still use YellowPages dot com to find out
    local
  • 8:03 - 8:05
    businesses and stuff like that. And they were
    talking
  • 8:05 - 8:08
    about how they scaled their app, their Rails
    app.
  • 8:08 - 8:10
    And I was thinking, I was sitting there in
  • 8:10 - 8:12
    the audience, thinking well, this is really
    interesting, but
  • 8:12 - 8:15
    I'm not sure this is ever gonna apply to
  • 8:15 - 8:16
    me. I don't really, I work on these small
  • 8:16 - 8:19
    things. No one ever really sees them. But
    fast
  • 8:19 - 8:21
    forward a few years and, you know, here I
  • 8:21 - 8:24
    am. I'm, I'm working on this, this app that
  • 8:24 - 8:27
    millions of people see every day. So it can
  • 8:27 - 8:30
    really happen to you too.
  • 8:30 - 8:36
    So, let's start from the beginning. We launched
    in
  • 8:36 - 8:41
    early 2012, March 26th, 2012 to be exact.
    And
  • 8:41 - 8:44
    at the time there was one engineer, me, and
  • 8:44 - 8:48
    our CTO who is a programmer, but was not
  • 8:48 - 8:52
    really a Ruby or Rails developer. And we actually
  • 8:52 - 8:55
    launched not on Rails but on Padrino. Who
    here
  • 8:55 - 8:59
    is familiar with Padrino? Cool. Who here has
    production
  • 8:59 - 9:05
    apps in Padrino? No one. OK. That's what I
  • 9:05 - 9:05
    thought.
  • 9:05 - 9:07
    So Padrino, this is, it's, it kind of builds
  • 9:07 - 9:11
    itself as the elegant web framework. It is
    essentially
  • 9:11 - 9:15
    just Sinatra with more Rails-like things on
    top of
  • 9:15 - 9:18
    it. So he, who here has used Sinatra? More
  • 9:18 - 9:21
    hands. Of course. And who here actually has
    Sinatra
  • 9:21 - 9:24
    in production? A few, a few hands. Yeah.
  • 9:24 - 9:27
    So, essentially, when you're working with
    Sinatra, it's a,
  • 9:27 - 9:32
    it's a more low-level library. More closer
    to Rack.
  • 9:32 - 9:36
    And Padrino, essentially, adds the things
    that you miss
  • 9:36 - 9:43
    from Rails into Sinatra. It also freely borrowed
    some
  • 9:44 - 9:49
    really great ideas from Djando. The first
    one being
  • 9:49 - 9:53
    first-class mountable apps. So in Rails we
    have engines.
  • 9:53 - 9:55
    But it seems like not, people don't really
    use
  • 9:55 - 9:57
    engines that often. Like, you might use it
    for
  • 9:57 - 10:02
    Rails admin. It's, you kind of might have
    a
  • 10:02 - 10:05
    larger Rails app and then break it up by
  • 10:05 - 10:11
    putting it into separate engines. But with
    Padrino, all
  • 10:11 - 10:13
    code actually lives in a mountable app. So
    you
  • 10:13 - 10:16
    have to use this mountable app system to use
  • 10:16 - 10:19
    it.
  • 10:19 - 10:22
    It's also middleware centric. So, those of
    you who
  • 10:22 - 10:24
    are familiar with Rack, know that there's
    a lot
  • 10:24 - 10:26
    of kind of, there's this concept of middleware
    -
  • 10:26 - 10:29
    it's also in Rails - where you can kind
  • 10:29 - 10:33
    of write these small bits of code that are
  • 10:33 - 10:36
    Rack compatible, that sit on the stack of
    what
  • 10:36 - 10:40
    you do, of how requests and responses come
    into
  • 10:40 - 10:43
    your Rails app, or your Sinatra app or any
  • 10:43 - 10:45
    Rack app.
  • 10:45 - 10:49
    And there's also this built-in Admin area.
    And that
  • 10:49 - 10:53
    Admin area is actually an app. That's just
    another
  • 10:53 - 10:56
    mountable app. So this is, this is something
    that
  • 10:56 - 10:59
    Django has. I know we have Rails Admin here
  • 10:59 - 11:02
    in, in the Rails world. But with Padrino,
    this
  • 11:02 - 11:03
    is a thing that is built into the framework
  • 11:03 - 11:05
    itself.
  • 11:05 - 11:09
    So, why Padrino? Why did I use Padrino in
  • 11:09 - 11:14
    the beginning? Essentially, at the time, I
    was a
  • 11:14 - 11:17
    seasoned Rails developer. I was probably developing
    for about
  • 11:17 - 11:21
    five years on Rails. And during that time
    I
  • 11:21 - 11:24
    started to form my own opinions about Rails.
    And
  • 11:24 - 11:28
    some of those opinions were not compatible
    with what
  • 11:28 - 11:32
    the, the, the Rails way prescribed. And I
    saw
  • 11:32 - 11:35
    Sinatra and Padrino as this way that I could
  • 11:35 - 11:39
    still write Ruby, still, I still loved writing
    Ruby,
  • 11:39 - 11:44
    but I could also make my own choices. And
  • 11:44 - 11:51
    there's this kind of epiphany that seasoned
    web developers
  • 11:51 - 11:54
    kind of ultimately have, which is, I'm writ-
    I'm
  • 11:54 - 11:56
    using this web framework, whether it be Rails
    or
  • 11:56 - 12:00
    Django or Sinatra or Node, that all it's doing
  • 12:00 - 12:03
    at the end, is it's just, it's really just
  • 12:03 - 12:05
    a web server. Cause at the very end, you're
  • 12:05 - 12:09
    just getting in responses, you're just emitting
    HTML or
  • 12:09 - 12:13
    CSS or JSON, if it's an API, or JavaScript.
  • 12:13 - 12:14
    That's all you're really doing. And all this
    talk
  • 12:14 - 12:21
    about TDD and good object-ori- domain, object-driven
    design, they're,
  • 12:23 - 12:27
    they're very important. They help us manage
    complexity. But
  • 12:27 - 12:30
    in the end, what does the framework physically
    do
  • 12:30 - 12:33
    in the air quote physical way is it, it
  • 12:33 - 12:38
    really just takes in HTTP responses, or, excuse
    me,
  • 12:38 - 12:42
    takes in HTTP requests and then responds with
    HTTP
  • 12:42 - 12:42
    responses.
  • 12:42 - 12:46
    So, while Rails will give you the full foundation
  • 12:46 - 12:51
    of how to build, build a skyscraper, Padrino
    gives
  • 12:51 - 12:53
    you a foundation, but it also lets you choose
  • 12:53 - 12:56
    some of the plumbing and make some choices
    for
  • 12:56 - 13:00
    yourself. So the good parts about Padrino
    are, is,
  • 13:00 - 13:02
    it really is just Ruby. It's just Rack. And
  • 13:02 - 13:05
    if you're a fan of thinking in that mindset,
  • 13:05 - 13:10
    you'll, you'll really enjoy it. There is less
    magic.
  • 13:10 - 13:16
    Things are more explicit. It's unopinionated.
    All the generators,
  • 13:16 - 13:18
    when you, when you generate a Padrino app,
    you
  • 13:18 - 13:23
    specifically say what you want. That you want
    ActiveRecord
  • 13:23 - 13:28
    versus DataMapper versus Monoid or you want
    Sass versus
  • 13:28 - 13:33
    Lest versus ERB. Whatever, whatever you want,
    you can
  • 13:33 - 13:35
    specify it.
  • 13:35 - 13:38
    I actually enjoy the process of writing middleware.
    I
  • 13:38 - 13:40
    like thinking about web apps like that. I
    think
  • 13:40 - 13:42
    it's a much more performant way to think about
  • 13:42 - 13:46
    writing web apps. And Padrino itself, unlike
    Rails is,
  • 13:46 - 13:49
    it's light, it's performant. It's really just
    Sinatra with
  • 13:49 - 13:53
    a few more libraries on top of it.
  • 13:53 - 13:56
    So this is what our architecture looked like
    when
  • 13:56 - 13:58
    we launched. So the whole big box is a
  • 13:58 - 14:05
    Padrino, is the Padrino app. And we had two
  • 14:05 - 14:07
    mounted apps inside it: main, the public site;
    so
  • 14:07 - 14:10
    when you visited Upworthy dot com, this is
    what
  • 14:10 - 14:14
    the public would see, those, those content
    pages; and
  • 14:14 - 14:17
    then we had the admin tool, the built-in Admin
  • 14:17 - 14:23
    app in Padrino, which essentially functioned
    as our CMS.
  • 14:23 - 14:26
    And keep in mind that we, we were hoping
  • 14:26 - 14:28
    that we're gonna launch this thing and then
    we're
  • 14:28 - 14:32
    gonna get lots of traffic. So we needed to
  • 14:32 - 14:34
    figure out how to scale it right away, right
  • 14:34 - 14:35
    from the get go.
  • 14:35 - 14:42
    So, I kind of devised this, this idea called
  • 14:42 - 14:47
    explicit caching, and I remembered back in
    the early
  • 14:47 - 14:50
    2000s, there was this blogging framework called,
    or blogging
  • 14:50 - 14:53
    tool called Moveable Type. And Moveable Type
    was what
  • 14:53 - 14:57
    all the big, those early blogs used. And Moveable
  • 14:57 - 15:00
    Type essentially, the way it worked is, it
    was
  • 15:00 - 15:02
    a CMS. So when you saved your post to
  • 15:02 - 15:07
    the database, Moveable Type would actually
    save, obviously, see
  • 15:07 - 15:10
    that you saved something to the database.
    And then
  • 15:10 - 15:13
    it render the HTML right then, and then write
  • 15:13 - 15:18
    the HTML to disc. So when your, when people
  • 15:18 - 15:20
    visited your blog that was hosted on Moveable
    Type,
  • 15:20 - 15:23
    they weren't hitting that Perl app and going
    through
  • 15:23 - 15:26
    the database. They were actually just hitting
    these rendered
  • 15:26 - 15:31
    HTML files and CSS, JavaScript, that were
    just living
  • 15:31 - 15:34
    on the file system of your server.
  • 15:34 - 15:36
    So I, I actually was drawn to that idea.
  • 15:36 - 15:40
    I liked that idea. So I kind of re,
  • 15:40 - 15:42
    re-made it a little bit here in Padrino. So
  • 15:42 - 15:45
    in the Admin app, there was this publisher
    object.
  • 15:45 - 15:49
    And the publisher object essentially did that,
    where once
  • 15:49 - 15:51
    anything was saved to the CMS, any content
    was
  • 15:51 - 15:54
    saved to the CMS, the publisher object would
    see
  • 15:54 - 15:58
    that. It would actually make a request to
    the
  • 15:58 - 16:03
    Main app, which was actually rendering the
    public site,
  • 16:03 - 16:10
    and it would write that rendered response
    to Redis.
  • 16:10 - 16:12
    And so RedisCache was a middleware layer - I
  • 16:12 - 16:15
    talked about middleware earlier - that sat
    very close
  • 16:15 - 16:18
    to the front of this Padrino app.
  • 16:18 - 16:21
    So, when we had a million or so pages
  • 16:21 - 16:23
    in that first month, they were all really
    being
  • 16:23 - 16:27
    served from Redis. Essentially the website
    was just in
  • 16:27 - 16:30
    memory in Redis. And so that worked, you know,
  • 16:30 - 16:33
    it scaled well.
  • 16:33 - 16:39
    So, around this time, June, 2012, we hired
    a
  • 16:39 - 16:44
    second Rails engineer, Josh French. So, he
    kind of
  • 16:44 - 16:47
    joined the team, and then a few weeks later
  • 16:47 - 16:50
    he said guys, I think we should switch to
  • 16:50 - 16:53
    Rails. And he was, he was probably right.
    Because
  • 16:53 - 16:55
    there were pain points that were not related,
    really,
  • 16:55 - 16:58
    to the technical performance of Padrino, but
    actually more
  • 16:58 - 17:02
    about social aspects of it. The first one
    being
  • 17:02 - 17:05
    that the ecosystem for libraries, while, while
    pretty good,
  • 17:05 - 17:09
    because, again, Padrino is just Sinatra, just
    Rack, was
  • 17:09 - 17:12
    not as strong as Rails. There's just libraries
    for
  • 17:12 - 17:14
    everything you want to do in Rails. We, there
  • 17:14 - 17:18
    were many things we could do in Padrino, but
  • 17:18 - 17:22
    the, the kind of quality of those libraries
    was
  • 17:22 - 17:25
    not as high. A part of that is because
  • 17:25 - 17:28
    Padrino isn't as popular, it wasn't very frequently
    maintained.
  • 17:28 - 17:31
    The actual Admin app was not very pleasant
    to
  • 17:31 - 17:34
    look at. It was its own HTML, CSS styling.
  • 17:34 - 17:36
    I put a star here because, literally, once,
    the
  • 17:36 - 17:39
    sec, the day we moved off of Padrino fully,
  • 17:39 - 17:43
    they released a new, a new release which was,
  • 17:43 - 17:45
    which had the Admin system in Bootstrap, which
    was
  • 17:45 - 17:49
    what we wanted all along. And there was no
  • 17:49 - 17:53
    community and, as a start up, it's like actually
  • 17:53 - 17:55
    easier to hire Rails developers, cause we
    can't really
  • 17:55 - 17:58
    go hey, we know you're a great Rails developer
  • 17:58 - 17:59
    but you're gonna have to work on this thing
  • 17:59 - 18:06
    called Padrino. That wasn't really a, a strong
    sell.
  • 18:07 - 18:10
    So we decided to move. We wanted to move
  • 18:10 - 18:12
    to Rails. But at the same time, we're, we're
  • 18:12 - 18:15
    a growing start up. We're getting lots of
    traffic.
  • 18:15 - 18:18
    So how do we kind of balance this desire
  • 18:18 - 18:24
    to move to, move our architecture while still,
    you
  • 18:24 - 18:27
    know, maintaining a running app, while still
    having to
  • 18:27 - 18:29
    maintain a stable, running app that is serving
    a
  • 18:29 - 18:34
    growing traffic base. And Ryan's gonna continue.
  • 18:34 - 18:40
    R.R.: So, we started our Rails migration in
    October
  • 18:40 - 18:43
    of 2012, and so this is a timeline. This
  • 18:43 - 18:48
    is October 2012. And basically the way it
    started,
  • 18:48 - 18:52
    we generated a new Rails app, moved all the,
  • 18:52 - 18:54
    we mounted it inside the routes.rb, so we
    just
  • 18:54 - 18:57
    basically mounted, and you can do the same
    thing
  • 18:57 - 19:00
    with Sinatra, since it's Rack. And then we
    slowly
  • 19:00 - 19:04
    the migrated the models and utilities into
    the app.
  • 19:04 - 19:06
    So, when I joined, we were kind of in
  • 19:06 - 19:09
    this weird hybrid state. I joined in January
    of
  • 19:09 - 19:12
    2013, after taking a nice long siesta, re-electing
    the
  • 19:12 - 19:18
    president stuff. And so, we had to figure
    out,
  • 19:18 - 19:20
    how could we accelerate and just, you know,
    get
  • 19:20 - 19:22
    us over the file hurdle and just move us
  • 19:22 - 19:24
    onto Rails completely and get out of Padrino.
    So
  • 19:24 - 19:28
    the first step that I did was migrating assets,
  • 19:28 - 19:30
    and so we activated the Rails asset pipeline
    which
  • 19:30 - 19:33
    had been turned off in our app. Migrated the
  • 19:33 - 19:36
    frontend assets, the backend assets. That
    took us about
  • 19:36 - 19:39
    a week in February, 2013. The next step was
  • 19:39 - 19:42
    deciding if we wanted to do the admin area
  • 19:42 - 19:45
    or our frontend area first. So we decided
    to
  • 19:45 - 19:48
    do the hard part first and do the frontend.
  • 19:48 - 19:50
    So we migrated all the frontend code. The
    views
  • 19:50 - 19:54
    and controllers, which took another two weeks.
    And then
  • 19:54 - 19:59
    lastly we, we did the entire backend CMS system
  • 19:59 - 20:02
    as a final push, and we added, we changed
  • 20:02 - 20:04
    it to bootstrap. Moved all the Rails controllers.
    That
  • 20:04 - 20:06
    took us another two weeks.
  • 20:06 - 20:10
    So, here at this point, the entire migration
    is
  • 20:10 - 20:13
    eight months. But it's really, it really ends
    up
  • 20:13 - 20:16
    getting accelerated in the last few weeks
    just because
  • 20:16 - 20:19
    we wanted to get to that, that final push.
  • 20:19 - 20:22
    And at this point, we're at three Rails developers:
  • 20:22 - 20:26
    me, myself, Luigi, and, sorry, myself, Josh,
    and Luigi,
  • 20:26 - 20:30
    and our CTO goes back to actually doing CTO
  • 20:30 - 20:33
    work, which is great.
  • 20:33 - 20:35
    So now here we are. We're in a monolith.
  • 20:35 - 20:38
    We're in a big huge monorail for the entire
  • 20:38 - 20:40
    2013, we were able to do things the Rails
  • 20:40 - 20:43
    way. We were able to increase our velocity
    and
  • 20:43 - 20:46
    just able to add lots of features. We were
  • 20:46 - 20:49
    able to program the way we wanted to and
  • 20:49 - 20:51
    really get things moving. We didn't have to
    rebuild
  • 20:51 - 20:55
    helpers that weren't, weren't existing. So
    we could just
  • 20:55 - 20:58
    have this one huge monolithic Rails app. We
    had
  • 20:58 - 20:59
    the backend CMS, and then we had our frontend
  • 20:59 - 21:03
    and we had all our Ajax endpoints.
  • 21:03 - 21:05
    But one of the things, when you're looking
    at
  • 21:05 - 21:10
    this monorail, is how are you scaling for
    virility?
  • 21:10 - 21:13
    So on the campaign, there was a lot of
  • 21:13 - 21:16
    traffic, and it was pretty easy to know that,
  • 21:16 - 21:18
    you know, in November is gonna be really busy,
  • 21:18 - 21:20
    or in October there's a voter deadline so
    it's
  • 21:20 - 21:23
    gonna be very specific of when traffic's gonna
    hit.
  • 21:23 - 21:25
    You could, you could tell. In, in the virile
  • 21:25 - 21:27
    media world, you don't know if your post is
  • 21:27 - 21:29
    gonna be a hit or not. You don't know
  • 21:29 - 21:31
    when it's gonna get traction. And so you can't
  • 21:31 - 21:34
    have someone sitting there monitoring twenty-four
    hours a day,
  • 21:34 - 21:37
    when to scale, when to not scale. So, we
  • 21:37 - 21:39
    had to think about how we were gonna do
  • 21:39 - 21:39
    that.
  • 21:39 - 21:41
    So a lot of it was just pretty simple
  • 21:41 - 21:44
    basic stuff here. We added action caching.
    So we
  • 21:44 - 21:47
    took, we removed the homegrown publisher system,
    just turned
  • 21:47 - 21:50
    on action caching in Rails, and it's backed
    by
  • 21:50 - 21:52
    memcache. So people would hit the page, you
    would
  • 21:52 - 21:54
    hit the memcached instance of the page instead
    of
  • 21:54 - 21:57
    going out, hitting our database, pulling in
    the page.
  • 21:57 - 21:59
    We were able to just do that.
  • 21:59 - 22:02
    The second part was just moving our assets
    on
  • 22:02 - 22:05
    S3 and Cloudfront, so our app is hosted on
  • 22:05 - 22:07
    Heroku. There's actually, it's a really easy
    tutorial on
  • 22:07 - 22:09
    Heroku on how to do this. You just set
  • 22:09 - 22:13
    up a Cloudfront instance and then you just
    point
  • 22:13 - 22:16
    your config host for the, the CDM for your
  • 22:16 - 22:19
    assets to that and it magically works. It's
    great.
  • 22:19 - 22:22
    And then the third thing is, we have lots
  • 22:22 - 22:24
    of Heroku dynos. So at the time we were
  • 22:24 - 22:27
    running up to forty Heroku dynos, and these
    were
  • 22:27 - 22:30
    1x dynos at the time.
  • 22:30 - 22:33
    So mainly these are for our Ajax requests
    so
  • 22:33 - 22:35
    that those asks, those popups, and the different
    things
  • 22:35 - 22:38
    that ask you around the site, we were able
  • 22:38 - 22:42
    to scale with those. So we ran this for
  • 22:42 - 22:46
    awhile, and we, we had some slowness on the
  • 22:46 - 22:49
    site sometimes, so we tried to figure out
    what
  • 22:49 - 22:52
    could we do to make sure that our site
  • 22:52 - 22:56
    would be stable and not have to worry about
  • 22:56 - 22:58
    these viral traffic spikes, having to scale
    up and
  • 22:58 - 23:01
    down. So we actually implemented a CDN in
    front
  • 23:01 - 23:03
    of it. We took some time and tried to
  • 23:03 - 23:05
    figure out what CDN we wanted. Because we
    wanted
  • 23:05 - 23:08
    to do faster posts and just different things,
    and
  • 23:08 - 23:10
    at the time we ended up on Fastly. So
  • 23:10 - 23:14
    Fastly is a reverse proxy. It runs on Varnish.
  • 23:14 - 23:17
    It's made, you guys could check it out. It's
  • 23:17 - 23:18
    great.
  • 23:18 - 23:23
    We, we moved all of that to, all our
  • 23:23 - 23:26
    HTML, CSS, and images to Fastly, and then
    we
  • 23:26 - 23:30
    turned off the Rails action caching. And the
    way
  • 23:30 - 23:33
    Fastly works is, is it reads your headers
    on
  • 23:33 - 23:37
    your page, so you just set, set expire four
  • 23:37 - 23:40
    hours from now. So our site could literally
    be
  • 23:40 - 23:42
    down for four hours and Fastly would continue
    to
  • 23:42 - 23:45
    serve the pages.
  • 23:45 - 23:47
    From there, we were able to dial down our
  • 23:47 - 23:49
    Heroku dynos. So we went to, we switched to
  • 23:49 - 23:53
    the 2x dynos, and we only needed about half
  • 23:53 - 23:57
    as many dynos, because we were only serving,
    off
  • 23:57 - 23:59
    the Heroku dyno for Ajax requests.
  • 23:59 - 24:03
    Probably the biggest thing that we learned
    from Fastly
  • 24:03 - 24:07
    was the mobile performance gain. So Fastly
    has all
  • 24:07 - 24:11
    these different locations around the world.
    If I'm in
  • 24:11 - 24:14
    California requesting a page from Upworthy
    dot com, it's
  • 24:14 - 24:16
    gonna go to the closest point of presence,
    the
  • 24:16 - 24:19
    CDN location in California instead of going
    out to
  • 24:19 - 24:21
    Heroku in Virginia, pulling from the data
    center and
  • 24:21 - 24:24
    bringing it back. So the, the load times went
  • 24:24 - 24:28
    way down, and we're able to fully cache the
  • 24:28 - 24:31
    site, and we have, we've had zero downtime
    since
  • 24:31 - 24:34
    implementing Fastly. So it's just been a great
    performance
  • 24:34 - 24:37
    gain for us.
  • 24:37 - 24:43
    So, with having a big monorail, there's huge
    pain
  • 24:43 - 24:47
    points that come along with it. We have, so
  • 24:47 - 24:50
    we have one app that deals with our www
  • 24:50 - 24:51
    service, Upworthy dot com, and then we have
    a
  • 24:51 - 24:55
    backend CMS that our, our curators log into
    and
  • 24:55 - 24:58
    do their work. So we had to figure out
  • 24:58 - 25:00
    the concerns with that. So it's, it's really
    painful
  • 25:00 - 25:02
    there.
  • 25:02 - 25:05
    When there's traffic spikes on the public
    site, it
  • 25:05 - 25:08
    could basically, it makes our CMS unstable,
    so the
  • 25:08 - 25:10
    curator would log into our site, try to do
  • 25:10 - 25:13
    their work, and they couldn't navigate and
    we'd just
  • 25:13 - 25:14
    have to tell them, you know, come back later
  • 25:14 - 25:17
    or come and do the work later. And when
  • 25:17 - 25:19
    the traffic spike comes down you'll be able
    to
  • 25:19 - 25:23
    use it. And as our team grows, the code
  • 25:23 - 25:25
    base was becoming very large. So the classes
    would
  • 25:25 - 25:28
    get huge and, you know, the frontend didn't
    care
  • 25:28 - 25:30
    about some of the stuff the backend did. So
  • 25:30 - 25:33
    it just got harder and harder to maintain.
  • 25:33 - 25:36
    So, of course, what did we do? We break
  • 25:36 - 25:39
    up here. Fun fact. This is actually a film
  • 25:39 - 25:47
    in Chicago. In December, 2013, our buddy Josh
    French
  • 25:47 - 25:49
    has another great idea. He says hey, I think
  • 25:49 - 25:52
    we should really start splitting up the Rails
    app.
  • 25:52 - 25:54
    And so, if you look how this timeline is,
  • 25:54 - 25:56
    it's pretty evenly spaced. We didn't just
    jump into
  • 25:56 - 26:00
    different things and start building them.
    We like took
  • 26:00 - 26:03
    some time on each of these sections and really
  • 26:03 - 26:07
    focused on, on that narrow gap.
  • 26:07 - 26:10
    So, one of the things, when you're trying
    to
  • 26:10 - 26:14
    decide how to break up your Rails app into
  • 26:14 - 26:16
    services, how do you do it? There's plenty
    of
  • 26:16 - 26:18
    different ways you can do it. This is the
  • 26:18 - 26:19
    way we did it. This is not the perfect
  • 26:19 - 26:22
    prescription for everybody. I think you have
    to look
  • 26:22 - 26:24
    at your app and see, like, where the clear
  • 26:24 - 26:27
    dividing lines are. So we basically, we just
    chose
  • 26:27 - 26:28
    two right now.
  • 26:28 - 26:30
    So we have our www site and we have
  • 26:30 - 26:33
    our backend CMS. So there's a clear dividing
    line
  • 26:33 - 26:35
    between the two. What we ended up doing is
  • 26:35 - 26:39
    cloning each repo into its own separate repository,
    so
  • 26:39 - 26:41
    we could maintain the git repo history, and
    then
  • 26:41 - 26:45
    from there we started breaking everything
    up, right. So
  • 26:45 - 26:46
    this is what we need for this side and
  • 26:46 - 26:47
    this is what we need for this side and
  • 26:47 - 26:49
    let's start chopping.
  • 26:49 - 26:51
    Which was, ended up being a lot of deleting
  • 26:51 - 26:58
    and removing namespaced objects. So, once
    we did that,
  • 26:58 - 27:01
    we deployed each of these apps to, to separate
  • 27:01 - 27:04
    Heroku applications. The nice thing about
    Heroku is, they
  • 27:04 - 27:06
    have this function called Heroku fork, so
    they'll just
  • 27:06 - 27:08
    take your current app, it'll fork it into
    another
  • 27:08 - 27:10
    Heroku app, pull over all your plugins, everything
    you
  • 27:10 - 27:13
    need. So we did that. We forked the app,
  • 27:13 - 27:17
    our main, our main app into two separate applications.
  • 27:17 - 27:19
    Removed the plugins that we didn't need on
    each
  • 27:19 - 27:21
    side, and then we pushed out our applications
    to
  • 27:21 - 27:25
    those Heroku sites. Everything's working great.
    And all we
  • 27:25 - 27:28
    had to do was switch our Fastly endpoint to
  • 27:28 - 27:30
    point at the new Heroku app at origin and
  • 27:30 - 27:36
    we're done. So. Zero downtime really helped
    there.
  • 27:36 - 27:39
    And then we continued to de-duplicate the,
    the two
  • 27:39 - 27:42
    apps. So we created this core gem that is
  • 27:42 - 27:45
    holding a lot of the code that shares between
  • 27:45 - 27:49
    the two apps. So, our CMS runs on about
  • 27:49 - 27:52
    two, two 2x Heroku dynos, and now our frontend
  • 27:52 - 27:57
    app runs about twenty-five to thirty 2x dynos.
  • 27:57 - 27:59
    This is pretty much what this looks like.
    So
  • 27:59 - 28:01
    we just have an app called www, and then
  • 28:01 - 28:03
    we have an app called CMS. And then this
  • 28:03 - 28:06
    gem shares the code between it. People will
    hit
  • 28:06 - 28:13
    the Fastly endpoint between www and, and our
    app.
  • 28:13 - 28:18
    So, what are the real benefits of service
    oriented
  • 28:18 - 28:20
    architecture? I think there's, there's plenty
    if you look
  • 28:20 - 28:23
    and think about it. One of the big things
  • 28:23 - 28:27
    is, we talked about the instability. You know,
    if
  • 28:27 - 28:31
    our curators couldn't do their work, they,
    you know,
  • 28:31 - 28:33
    we can't have like articles go out, so it
  • 28:33 - 28:37
    gets kind of annoying. So if there's a problem
  • 28:37 - 28:40
    on one app, it's, it's easier to fix and
  • 28:40 - 28:43
    maintain.
  • 28:43 - 28:45
    Each of them have different scaling needs.
    So the
  • 28:45 - 28:47
    interesting thing is, our CMS, you know, when
    we
  • 28:47 - 28:51
    have like twenty users that use our CMS, so
  • 28:51 - 28:54
    we could you know have is at 2x dynos,
  • 28:54 - 28:57
    instead of like having thirty dynos serving
    all these
  • 28:57 - 29:00
    different pages. So the scaling needs was
    really beneficial
  • 29:00 - 29:01
    here.
  • 29:01 - 29:05
    And that also divides our teamwork more naturally.
    So,
  • 29:05 - 29:07
    we can have people, we can have engineers
    on
  • 29:07 - 29:10
    a team decide to, you know, work on different
  • 29:10 - 29:12
    parts or features, and we don't have to wait
  • 29:12 - 29:13
    for something to ship or something else to
    finish.
  • 29:13 - 29:16
    But of course, there's, you know, there's
    a bunch
  • 29:16 - 29:19
    of drawbacks running an SOA. If you're on
    the
  • 29:19 - 29:21
    full stack and you want to make a feature
  • 29:21 - 29:23
    on our CMS that needs to carry all the
  • 29:23 - 29:25
    way through the funnels of our frontend, you
    have
  • 29:25 - 29:27
    to have both, all three environments running
    on our
  • 29:27 - 29:30
    system to make sure that, you know, your change
  • 29:30 - 29:33
    goes and it funnels all the way through.
  • 29:33 - 29:36
    Coordinating deploys is also a huge pain.
    So if
  • 29:36 - 29:37
    you need something that's in the core gem
    plus
  • 29:37 - 29:41
    the CMS plus the www app, that means you
  • 29:41 - 29:43
    have to deploy each three, coordinate them
    and make
  • 29:43 - 29:44
    sure that all of them are happening at the
  • 29:44 - 29:46
    same time, or all of them go in a
  • 29:46 - 29:49
    certain order, which, when you're on the monolith,
    it's
  • 29:49 - 29:51
    really easy to just push one big Rails app
  • 29:51 - 29:53
    out.
  • 29:53 - 29:55
    And then migrating to a fully DRY set of
  • 29:55 - 29:59
    codebases, it's really tedious. Trying to
    figure out what,
  • 29:59 - 30:01
    what needs to go where and where we put
  • 30:01 - 30:05
    stuff is, it's just been a really hard thing
  • 30:05 - 30:07
    to do.
  • 30:07 - 30:09
    So, some of the future work that we're gonna
  • 30:09 - 30:12
    continue to do on the SOA. We're gonna continue
  • 30:12 - 30:15
    to add stuff to our core gem. Remove dupli-
  • 30:15 - 30:17
    de-duplication, which is, it's kind of a pain
    sometimes
  • 30:17 - 30:20
    to figure out where, you know, what things
    go
  • 30:20 - 30:24
    where. And then we're considering making,
    breaking up the
  • 30:24 - 30:26
    app even more. So, right now we have two
  • 30:26 - 30:28
    apps. We have this third app that actually
    uses
  • 30:28 - 30:30
    up almost all our Heroku dynos. So we're thinking
  • 30:30 - 30:33
    about making that its own separate app and
    service,
  • 30:33 - 30:36
    and we can ping that.
  • 30:36 - 30:37
    And then, you know, they all communicate with
    these
  • 30:37 - 30:39
    different data stores. Should we just use,
    a lot
  • 30:39 - 30:42
    of times an SOA has that service layer, and
  • 30:42 - 30:44
    everything communicates with that service
    layer. So maybe we
  • 30:44 - 30:46
    should move to that.
  • 30:46 - 30:51
    L.M.: Cool. So. Just to wrap up here, some
  • 30:51 - 30:58
    lessons learned. So, first really, when you're,
    when you're
  • 30:59 - 31:02
    working on an app for a company and you're,
  • 31:02 - 31:04
    you're, there's a feature request and there's
    all these
  • 31:04 - 31:07
    other things going on in your company, really
    do
  • 31:07 - 31:11
    wait to make these big technical architectural
    changes until
  • 31:11 - 31:13
    everything starts to really, really hurt.
    Until you really
  • 31:13 - 31:17
    feel the pain. And once you do decide to
  • 31:17 - 31:20
    make these changes, it's OK to take a really
  • 31:20 - 31:24
    long time. We're probably gonna take eight
    months to
  • 31:24 - 31:27
    do that fully SOA system that we envisioned
    back
  • 31:27 - 31:29
    in the beginning of the year. And that's just
  • 31:29 - 31:32
    because we have other feature requests from
    the rest
  • 31:32 - 31:37
    of the company to fulfill. And luckily as,
    since
  • 31:37 - 31:40
    we're on Ruby, it kind of makes it easier
  • 31:40 - 31:41
    to do that. It really made it easier when
  • 31:41 - 31:47
    we were moving from Padrino to Rails.
  • 31:47 - 31:48
    Serve everything you possibly can from a CDN.
    I
  • 31:48 - 31:52
    don't think people use CDN's enough. They're
    just hugely
  • 31:52 - 31:56
    beneficial to the performance of your system.
    They're great
  • 31:56 - 32:00
    for end users, particularly mobile users.
    At Upworthy, we
  • 32:00 - 32:03
    have well over fifty percent of our traffic
    comes
  • 32:03 - 32:07
    from phones and tablets. And CDNs really,
    really help
  • 32:07 - 32:10
    there.
  • 32:10 - 32:13
    So remember that you're just dealing with
    HTML, CSS,
  • 32:13 - 32:15
    JavaScript, JSON, maybe, at the end of the
    day.
  • 32:15 - 32:18
    Right. That's all you're serving. So think
    about how
  • 32:18 - 32:21
    you can most efficiently serve those resources
    from your
  • 32:21 - 32:25
    app. And if you are, you're doing your own
  • 32:25 - 32:26
    start up, if you're working on your own project,
  • 32:26 - 32:29
    I hope you can also experience this kind of
  • 32:29 - 32:32
    high traffic growth, because it's been a hugely
    fun
  • 32:32 - 32:35
    and rewarding experience for the both of us.
  • 32:35 - 32:41
    So, with that, I'm Luigi, he's Ryan. Our slides
  • 32:41 - 32:44
    and our write up is already on our GitHub
  • 32:44 - 32:47
    engineering blog. And we will be happy to
    answer
  • 32:47 - 32:48
    questions.
Title:
RailsConf 2014 - You'll Never Believe Which Web Framework Powers Upworthy
Description:

more » « less
Duration:
33:15

English subtitles

Revisions