<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Twitch Engineering - Medium]]></title>
        <description><![CDATA[Learn about Engineering at Twitch - Medium]]></description>
        <link>https://medium.com/twitch-engineering?source=rss----e7f6a8ed8244---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>Twitch Engineering - Medium</title>
            <link>https://medium.com/twitch-engineering?source=rss----e7f6a8ed8244---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 22:30:16 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/twitch-engineering" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Twitch Hosts Global Ember Meetup Conference]]></title>
            <link>https://medium.com/twitch-engineering/twitch-hosts-global-ember-meetup-conference-d852c0d2488f?source=rss----e7f6a8ed8244---4</link>
            <guid isPermaLink="false">https://medium.com/p/d852c0d2488f</guid>
            <category><![CDATA[ember]]></category>
            <category><![CDATA[twitch]]></category>
            <category><![CDATA[meetup]]></category>
            <dc:creator><![CDATA[Jordan Hawker]]></dc:creator>
            <pubDate>Fri, 03 Jun 2016 16:01:02 GMT</pubDate>
            <atom:updated>2016-06-03T16:01:02.264Z</atom:updated>
            <content:encoded><![CDATA[<p>Twitch Hosts Global Ember Meetup Conference</p><p>On Saturday, May 21st, Twitch hosted the <a href="https://www.eventbrite.com/e/gemconf-san-francisco-global-ember-meetup-conference-tickets-22255622165">Global Ember Meetup Conference</a> (GEMConf) at our headquarters in San Francisco. <a href="https://twitter.com/embermeetup">Global Ember Meetup</a> is an organization that hosts Ember meetups online for developers who do not have a regional meetup group near them. They have held many remote meetups, as well as a few that brought together local attendees with remote viewers and presenters. This was Global Ember Meetup’s first full-day event and their first time streaming via Twitch, and we were very excited to host them! We love being part of the Ember community, and we’ve been lucky to have the opportunity to give back by providing a venue for events like this.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0nQ3vu3_At7OK2Zde75bEw.jpeg" /></figure><p>There were over 100 people in attendance at GEMConf, with viewers tuning in to the stream on Twitch from over a dozen countries! It was great to see such a strong turnout from remote attendees, since the Twitch platform is all about bringing live content creation to the global audience. I was especially excited to see the mix of on-site and remote presenters for the talks; the event switched back and forth between the two throughout the day.</p><p>The whole day was filled with great talks that really resonated with what we value in Twitch Engineering. All of the talks were excellent, and two stood out to me as particularly relevant to us at Twitch:</p><p>Juan Pablo Buritica’s presentation on “Building Excellent Engineering Culture” highlighted something that we’re really passionate about. We work very hard to engender engineering practices that create a web product of the highest quality and availability, through best practices, infrastructure, tooling, and by surrounding ourselves with engineers who share our vision of that culture.</p><p>“Building Real-Time Applications w/ EmberJS &amp; WebSockets” by Ben Limmer was also a great example of what we strive for. As a live content platform, it’s really important for us to leverage the best technology for creating a real-time experience for our users. In particular, our team has worked very hard to build a seamless chat experience enabled by our real-time distributed Go platform. You can read more about our platform architecture <a href="http://link.twitch.tv/engineering-overview">here</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*56CriXELU8gMBnfeM40xAQ.jpeg" /><figcaption>Jordan Hawker speaking about Ember User Activity</figcaption></figure><p>I was lucky enough to have the opportunity to present <a href="http://jhawk.co/eua-lightning-slides">my own talk</a> at GEMConf, and I spoke about an addon I built called <a href="http://jhawk.co/ember-user-activity">Ember User Activity</a> (EUA). EUA provides an event service bus for tracking global user actions in your application, such as <em>mousedown</em>, <em>keydown</em>, <em>scroll</em>, and more. One of its key use-cases at Twitch is for our new <a href="http://link.twitch.tv/gemconf-friends">Friends feature</a>, where we use EUA to determine whether a user is currently active on the page. The user-idle service that implements this functionality is also provided by the addon and can be configured to your app’s needs! I’ve done a lot of work lately to improve the performance of EUA, utilizing <em>requestAnimationFrame</em> and adding event throttling. Check out the <a href="http://jhawk.co/ember-user-activity-demo">demo</a> and play around with it, then let me know what you think!</p><p>I was also incredibly interested in the CSS layout performance talk by Chris Thoburn and Nathan Hammond’s lightning talk on accessibility. These are all topics that we strive to improve upon in our work at Twitch, and it was great to get community input and thought leadership from the speakers at GEMConf!</p><p>You can check out all the talks and their slides through the <a href="http://link.twitch.tv/gemconf-recap">GEMConf Recap</a>.</p><p>Overall, it was great to bring the Global Ember Meetup here to San Francisco and host the very first GEMConf! I can’t wait to see what more we can do with streaming meetups and conference talks on Twitch to enable remote participation in these great events. It’s really exciting to be able to build a product that can not only benefit the Ember community through our team’s upstream open-source contributions, but also to provide a platform that can enable the global spread of information and communication for our events as well!</p><p>If you’re in the Bay Area, be sure to join us for the next <a href="http://www.meetup.com/Ember-SF/events/231368426/">SF Ember meetup</a> at our downtown San Francisco HQ on Tuesday, July 26th!</p><p>To find out about all of our upcoming Tech events and more, follow us on Twitter at <a href="https://twitter.com/TwitchTech">@TwitchTech</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d852c0d2488f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/twitch-engineering/twitch-hosts-global-ember-meetup-conference-d852c0d2488f">Twitch Hosts Global Ember Meetup Conference</a> was originally published in <a href="https://medium.com/twitch-engineering">Twitch Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A Guide to Interviewing at Twitch]]></title>
            <link>https://medium.com/twitch-engineering/a-guide-to-interviewing-at-twitch-eb95fd98dbe0?source=rss----e7f6a8ed8244---4</link>
            <guid isPermaLink="false">https://medium.com/p/eb95fd98dbe0</guid>
            <category><![CDATA[twitch]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[interview]]></category>
            <dc:creator><![CDATA[James Richard]]></dc:creator>
            <pubDate>Sat, 26 Mar 2016 02:06:34 GMT</pubDate>
            <atom:updated>2016-03-29T23:04:56.165Z</atom:updated>
            <content:encoded><![CDATA[<blockquote>We want people interviewing at Twitch to have the best possible experience, so we’ve recently started giving them a few tips on how to be successful. Here it is, reprinted in full. If you’re not yet interviewing, check out our <a href="http://engineering.twitch.tv/">engineering site</a> and find a role that excites you.</blockquote><p>So you’re interviewing at Twitch? That’s great! Hopefully we can give you a few pointers that will make interviewing at Twitch a more fulfilling and successful experience.</p><h3>What we’re looking for:</h3><p>When we interview engineers, we’re looking for a few things that are important for everyone that works at Twitch:</p><ul><li>Enthusiasm for engineering and craftsmanship — you should enjoy the challenge of solving engineering problems, striving to improve your skills, and care deeply about the quality and polish of the products you build.</li><li>Practical coding skills and problem-solving ability — we want you to be able to work quickly and safely, as well as solve difficult problems.</li><li>Communication skills — yes, you’re going to be spending a lot of time writing code, but all of the important decisions that you make will usually require you to communicate clearly and effectively with a variety of people, both technical and non-technical.</li></ul><h3>Overall Interview Tips</h3><p>Here are a few tips as to how you can make the interview experience better for yourself (and us):</p><p>Ask us questions! Interviews are as much about you learning about us as us learning about you. If there are things that you would like to know about Twitch that will help you decide if we’re a good fit, ask them. Write down a list ahead of time if you’re not good at being spontaneous.</p><p>Don’t worry if you don’t know everything. We’re looking for folks who are able to succeed when given difficult challenges. Part of that is often seeing how you deal with things that may be out of your comfort zone or area of expertise.</p><p>Explain your thinking. If neither you nor the interviewer are speaking, that probably means that you could be conveying more information about how you’re approaching the problem that would allow us to evaluate you.</p><p>Be yourself! We aren’t robots, and we don’t want to hire robots. We are looking for the wealth of your experiences, and want to know what you would be like to work with on a day to day basis — let your personality and passion show!</p><h3>Phone Interview Tips</h3><p>Phone interviews in particular have lots of things that you can do in order to make your experience better. To wit: A great deal of what can go wrong in a phone screen is technical in nature.</p><ul><li>Find a quiet environment that doesn’t have distracting noises for both yourself and your interviewer.</li><li>If you’re using a cell phone, make sure that you are in a location with a reliable connection. Instead of a cell phone, consider using a landline or VOIP solutions like Skype or Google Hangouts with a headset to get especially good voice quality.</li><li>We will usually provide you with an URL for a shared editor environment like <a href="https://coderpad.io/">CoderPad</a>. Take a few minutes to familiarize yourself with the environment, and make sure that you can connect to the provided URL before the interview starts.</li></ul><h3>On-site Interview Tips</h3><p>Dress comfortably. Twitch is a casual environment, but if dressing sharp helps boost your confidence, do what works for you!</p><h3>Technical Interview Tips</h3><p>As mentioned above, we’re looking to challenge you and explore the boundaries of what you do and don’t know. So it’s more important that you feel comfortable thinking on your feet and describing your approach than knowing every little detail. If you haven’t interviewed for a while, get someone to throw a practice question at you so you can practice verbalizing your thoughts.</p><p>Interview questions that we give you may often seem like they’re vague or unclear. Hint: This is often by design! Real world engineering is messy — we’re looking to find people who are able to bring clarity and order to it. Ask questions to determine the scope of the problem so you can clean and tidy it up.</p><p>Iterate while answering questions! If you find an optimal solution first, that’s great! But it’s often better to solve the problem quickly first with a suboptimal solution and then follow up with a better solution later.</p><h3>Coding</h3><p>As an engineering candidate, it is expected that you will be able to demonstrate proficiency in day-to-day coding skills. We expect that you will be able to write correct, clean, and maintainable code on the fly. We suggest that you brush up on a language that lends itself well to rapid prototyping, like Python, Ruby, or JavaScript, so you can spend more time demonstrating your coding skills and less time writing uninteresting boilerplate. You should have an understanding of fundamental algorithms and data structures (Breadth-first search, depth-first search, hash tables, lists, binary trees, etc.), as well as their runtime characteristics and common applications. For frontend positions, we emphasize expertise programming for the Web (including an understanding of modern JS tooling and cross-browser compatibility issues) and sensibilities for design and UX over a strong algorithmic or CS background.</p><h3>Programming Language and Tools Expertise</h3><p>One of the things that you develop as a good engineer is expertise in the programming languages and tools that you use to accomplish your job. While we do not require that you know any particular programming language, you should be able to demonstrate that you have gained proficiency with at least one commonly used language such as JavaScript, Ruby, Go, Python, Java, C++, or C#. Expect to be asked about unique language features, commonly used libraries, and warts of the languages that you are proficient in.</p><h3>Design and Architecture</h3><p>Twitch engineering runs the gamut from crafting delightful user experiences on our platforms (Web, Xbox, PS4, iOS, etc.) to building large-scale distributed systems, so the scope of what you may be asked could be large depending on the position you’re applying for. We may ask you questions outside your past experience or comfort zone to see how you think on your feet and adapt to new problems. When designing solutions, we value simplicity, ease of maintenance, and durability more than algorithmic and design cleverness.</p><p>Distributed systems that communicate over HTTP are widely used at Twitch, so if you’re interviewing for a backend position, it’s helpful to have a basic understanding of common web architecture patterns and the various components that are used in building distributed systems, including databases and other data stores, load balancers, caches, and message queues.</p><h3>Final Thoughts</h3><p>We look forward to talking to every single one of our candidates — we’re always excited to be able to add a new member to the Twitch family! While interviews can be stressful, we hope that we’re able to do our best to make your experience as fun and informative as possible.</p><p>Good luck!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eb95fd98dbe0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/twitch-engineering/a-guide-to-interviewing-at-twitch-eb95fd98dbe0">A Guide to Interviewing at Twitch</a> was originally published in <a href="https://medium.com/twitch-engineering">Twitch Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Twitch Engineering: An Introduction and Overview]]></title>
            <link>https://medium.com/twitch-engineering/twitch-engineering-an-introduction-and-overview-36ceeb8875de?source=rss----e7f6a8ed8244---4</link>
            <guid isPermaLink="false">https://medium.com/p/36ceeb8875de</guid>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[twitch]]></category>
            <dc:creator><![CDATA[Douglas Soo]]></dc:creator>
            <pubDate>Wed, 20 Jan 2016 01:12:06 GMT</pubDate>
            <atom:updated>2016-01-20T01:12:06.579Z</atom:updated>
            <content:encoded><![CDATA[<p>If you’re a Twitch user, you probably know that Twitch is a pretty big site that streams live video, but you may not have an idea of the sheer scale and complexity of all of the different moving parts needed to hold everything together.</p><p>Among other things, we have:</p><ul><li>One of the largest live video distribution systems in the world</li><li>A real-time chat system</li><li>Web services that provide access to functionality and data</li><li>Data storage systems</li><li>Client applications on the web, and on a multitude of platforms — mobile and console in particular</li><li>Data science infrastructure</li><li>Internal tooling and systems — configuration management, deployment systems, hardware and software provisioning, testing and QA</li><li>Network infrastructure that keeps the bits between all of these systems and the end users flowing</li></ul><p>Each of these different components of Twitch has different challenges that need to be tackled — among them low-level optimization of video encoding, large scale system scaling, implementing products across multiple platforms and form factors, and improving our engineering efficiency via improved tooling.</p><p>Read More.</p><h3>Engineering at Scale</h3><p>Before we dive into what technology we currently use, it’s important to note that many of the decisions that we make surrounding technology are driven by the size of Twitch and how rapidly it is growing:</p><ul><li>We have over 30,000 people streaming video on Twitch simultaneously.</li><li>We have peaked at over 2 million concurrent video streams on our site.</li><li>Our chat service delivers over 10 billion messages a day.</li><li>Our web APIs handle over 50 thousand requests a second on average.</li><li>Over the last 3 years, the number of engineers at Twitch has grown by over 800%.</li></ul><p>This means that we have to scale at both an architectural and organizational level. As each individual systems grows, we expose different kinds of failure modes that aren’t problems in smaller systems, but become problematic as systems grow larger. This includes problems like hardware and network failures that are rare in small systems but commonplace in larger ones, and doing things like capacity planning to make sure that you can build and architect new infrastructure and systems before they are needed.</p><p>Beyond individual systems growing larger, we are also adding more systems to Twitch to make our product better. Each of these new systems adds more complexity to our overall system, which makes engineering more complex for everyone. And adding the extra engineers to build those systems also adds organizational complexity — communication and coordination is an O(n2) scaling problem if left alone. There have been many great articles written (and ideas) about how to try to solve these problems, but there isn’t enough room here to do them justice.</p><h3>Our Technology Stack (A 50 thousand foot view)</h3><p>There is way too much to talk about in depth here, but I’ll attempt a high-level overview of the the key pieces of technology that keep Twitch up and running.</p><h3>Video System</h3><p>The video system is responsible for getting video from the broadcaster to our viewers. This includes the following core components:</p><ul><li>Video ingest — We take RTMP video in, and then transport it to the transcode system.</li><li>Transcode system — We take the incoming RTMP stream from the broadcaster, and transcode it into multiple HLS streams. This is implemented via a combination of C/C++, and Go.</li><li>Distribution and Edge — Distribute the HLS streams to our geographically disparate POPs, such that you have the highest quality video streaming experience. Again, mostly written in Go.</li><li>VOD (Video on Demand) — we take all of our incoming video systems and archive them for our VOD system.</li></ul><h3>Chat</h3><p>Chat is a highly scalable real-time distributed system written in Go. It delivers hundreds of billions of messages per day to users who are watching video via our own protocols, as well as supporting IRC as a communication protocol, making it easy for developers to create IRC bots to add their own custom chat features. Core chat components include:</p><ul><li>Edge — Receives and distribute messages between clients and backend services. Edge speaks the IRC protocol over both raw TCP and WebSockets.</li><li>Pubsub — Distributes messages internally across Edge nodes. Pubsub and Edge combine to form a hierarchical message distribution system which executes massive fanout.</li><li>Clue — Perform analysis on user actions and send them through our business logic pipeline. Iis the user banned in the channel they’re speaking in? Are they a subscriber? Are they banned or exhibiting abusive behavior? To inform these decisions, Clue aggregates data across many sources, including databases, internal APIs and caches.</li><li>Room — Responsible for the viewer list. Room aggregates, stores, and queries membership data across all our edges to retrieve viewer lists for each channel’s chat room.</li></ul><h3>Web APIs and Data</h3><p>Besides our real-time services (video and chat) we also have a substantial number of services including, but not limited to:</p><ul><li>Web APIs that allow users to manage and customize their profiles and subscriptions</li><li>Search and Discovery services that help you to find the streams that you want.</li><li>Revenue systems — these are systems that allow us to manage advertising and subscriptions, and make sure that our partners get their income.</li><li>Administrative tools that help our support staff resolve your problems.</li></ul><p>This is all built on a mix of Rails, Go, and various different open-source applications that are used for routing, caching, and data storage. We have also been doing a lot of vertical and horizontal partitioning of our data and data APIs in order to make our systems scale better — both at a technical and organizational level.</p><h3>Web and Client Applications</h3><p>All of these services are lovely, but useless without easy to use client applications that create a good user experience. We have a multitude of different client applications that make it easy to access Twitch.</p><ul><li>Our desktop web application, which started off as a vanilla Rails application, but has evolved into an Ember app.</li><li>Native apps for the major mobile and tablet platforms (iOS and Android).</li><li>Various console applications, including XBox One, XBox 360 and Playstation 4.</li></ul><h3>Data Science Infrastructure</h3><p>Science Engineering builds data collection systems and analysis tools to study how our users interact with our products. These systems include:</p><ul><li>The data pipeline, which collects, cleans, and loads over a billion events a day into our data warehouse</li><li>Streaming aggregators to summarize metrics in near real-time for broadcasters.</li></ul><h3>Tools and Operational Infrastructure</h3><p>The above services directly support the application and product. However, the operational infrastructure that we need to manage these services is also extremely important. We have and maintain tools for:</p><ul><li>Testing all of these services by manual QA and automated testing — we currently use Jenkins for automated build and test.</li><li>Tools for rapid deployment and rollback of changes — we have a couple of home-grown tools here.</li><li>Monitoring and alerting systems that let us know when things are going wrong, and help us to diagnose and fix them. Currently a mix of tried and tested tools like ganglia, graphite, and Nagios.</li><li>Distributed trace. This is something new that we’ve been working on, to help us understand and debug our systems as we move further and further into the realm of distributed systems and microservices.</li></ul><p>At the physical level, we currently run an actually fairly large number of “bare metal” POP (points of presence) all over the world — this allows us to deliver higher quality video due to the unusual requirements of video delivery (lots of bandwidth!).</p><p>We also have been moving an increasing amount of our services to Amazon Web Services — this helps to reduce the amount of operational overhead, as well as to take advantage of the convenience and scalability of many of their services.</p><h3>In Closing</h3><p>We hope this has been an interesting overview of what makes Twitch tick under the hood. If you are interesting in learning more about these (or other) systems, please <a href="http://engineering.twitch.tv/">look at the Twitch Engineering site</a>!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=36ceeb8875de" width="1" height="1" alt=""><hr><p><a href="https://medium.com/twitch-engineering/twitch-engineering-an-introduction-and-overview-36ceeb8875de">Twitch Engineering: An Introduction and Overview</a> was originally published in <a href="https://medium.com/twitch-engineering">Twitch Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How we migrated over half a billion records without downtime]]></title>
            <link>https://medium.com/twitch-engineering/how-we-migrated-over-half-a-billion-records-without-downtime-d91e58f39cad?source=rss----e7f6a8ed8244---4</link>
            <guid isPermaLink="false">https://medium.com/p/d91e58f39cad</guid>
            <category><![CDATA[data-migration]]></category>
            <category><![CDATA[golang]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Jos Kraaijeveld]]></dc:creator>
            <pubDate>Tue, 19 Jan 2016 20:53:05 GMT</pubDate>
            <atom:updated>2016-01-21T23:56:10.642Z</atom:updated>
            <content:encoded><![CDATA[<p>As Twitch has grown, we’ve encountered many different and interesting scaling problems. One of our biggest challenges has been the 500+ million following relationships between users. Up until a few months ago, these relationships were stored very inefficiently and could no longer scale to our needs. Following relationships are immensely important to our broadcasters and viewers, as they are the means in which we notify users when their favorite broadcasters start streaming. This underpins the communal nature of Twitch; thus, while planning improvements we decided that downtime during any migration was unacceptable. To efficiently solve this task, we built a <a href="https://www.facebook.com/notes/facebook-engineering/tao-the-power-of-the-graph/10151525983993920/">TAO-look-a-like</a> and incurred absolutely zero down time in the migration. Here’s how.</p><h4>Establishing the Path Forward</h4><p>The initial schema was not designed with a billion relationships in mind. It lacked correct indexing and was a part of a large, centralized PostgreSQL cluster — which was succumbing under load during peak times. One of the primary use cases for our following system is to notify users when their favorite broadcasters have come online. This means iterating over all of a channel’s followers as quickly as possible. To illustrate the problem, this is a graph of time required to retrieve all followers sequentially, fetching 100 results at a time. The old model is unsustainable, while the new model is a perfect fit.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/765/0*Dg3tpnDX9KvKdbQ9." /></figure><p>At peak, the following-related queries represented 40% of our PostgreSQL cluster’s available CPU time. Having pushed that cluster to its limits already, we sought to move to a more optimal data model. Inspired by Facebook’s TAO, we realized we could simply model our follower data as associations in the form of [Entity A, Association Type, Entity B], as such:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/646/0*L0vqioOFLGj_YpTW." /></figure><p>With the target data model established, we created a high level migration plan:</p><ol><li>Take a database dump of the PostgreSQL table</li><li>Simultaneously start recording all new write events (follows and unfollows) on to a time ordered event queue.</li><li>Import the database dump into a new database and convert the data into the new schema format.</li><li>Replay all queued up writes onto the new data store until it’s caught up</li><li>Divert traffic to the new database</li></ol><p>We had a separate program consume the write events and write them to the new database using the new schema. Although on paper that makes us able to divert the traffic and switch over, we wanted to be sure that our newly formatted data matched the semantics of our old data. Clients of our API should not be aware that this change was happening and all previously stored data should be retrievable. Since each of these migration steps has a possibility to introduce non-obvious faults, we devised a strategy to ensure consistent behavior between the two data representations.</p><h4>Ensuring Success</h4><p>To ensure data consistency, we took inspiration from Github’s <a href="https://github.com/github/scientist">Scientist</a> library for refactoring critical paths. We wrote our service to support more than a single data store: a primary one and an arbitrary number of secondaries. We can mirror, in parallel, each incoming request to all the data stores and return the result from the primary one to the client. We can then, in a different thread, compare the result of a secondary data store with the primary to see whether it’s correct. With this information, we can say with confidence when the migration is ready to proceed. We can also measure request times for each secondary data store to ensure response times are within expectations. The idea is illustrated here, with the steps being numbered in order:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/334/0*c0bLjjhFT3bcBICb." /></figure><p>Below is a code snippet that illustrates the flow mentioned. The client supplies ‘from’ and ‘to’ IDs, as well as the type of the association. Our service responds with a single result if the record existed, otherwise nothing. The interfaces look like this (note that I’ve excluded <a href="https://blog.golang.org/context">Contexts</a> everywhere, trimmed package names and simplified some things for brevity’s sake):</p><pre>type Reader interface {<br>    GetAssoc(Association) (*AssocResponse, error)<br>}</pre><pre>type Backender interface {<br>    GetAssoc(Association, *Params) (AssocResponse, error)<br>}</pre><pre>// Backend provides storage and stats implementations<br>type Backend struct {<br>    primaryReader Reader<br>    secondaryReaders []Reader<br>}</pre><p>This makes it possible to create multiple readers. Every incoming request comes into the backend, which then routes them to the primary and the secondaries.</p><pre>func (b *Backend) GetAssoc(assoc Association) ([]AssocResponse, error) {<br>    res, err := b.PrimaryReader.GetAssoc(assoc)<br>    if err == nil {<br>        go func() { b.secondaryGet(assoc, res) }()<br>    }<br>    return res, err<br>}</pre><p>Secondary reads are handled after the primary has already returned. We spin up a goroutine for each of the registered secondary readers, and time how long each one takes. That allows us to compare the result it got back with the primary result and report stats around to our statsd cluster. Finally, these all execute within a timeout function for safety.</p><pre>func (b *Backend) secondaryGet(assoc Association, primaryResult AssocReponse) {<br>    for _, r := range b.secondaryReaders {<br>        go func(reader Reader) {<br>            res, err := reader.GetAssoc(assoc)<br>            if err != nil || res != primaryResult {<br>                // Log failed comparison<br>            } else {<br>                // Log successful comparison<br>            }<br>        }(r)<br>    }<br>}</pre><p>Logging the successful and failed comparisons in our statsd clusters allow us to measure mismatch rates:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*pOP3s2Fky79-Nzvb." /></figure><p>In the case of a mismatch we logged the result alongside the expectation and compared the two. The dips in the graph above represent our progress from steadily investigating inconsistencies and fixing them. A few example issues that we found were:</p><ul><li>Result sets not being ordered correctly</li><li>Records being included when they should not have been</li><li>Time stamps being returned in the wrong timezone</li></ul><h4>Conclusion</h4><p>By the end of it, we knew that the results we were serving to our users were the ones they were expecting and felt confident in switching over to the new database cluster. As an extra safeguard for rolling back, we added the original database as a secondary data store when we switched over — meaning that it wouldn’t get out of date, and it’d be easy to switch back if any problems occurred. It’d just be a matter of changing which database we call primary and which we call secondary. We first did this with reads and subsequently with writes by implementing a secondary writer.</p><p>Migrating 500 million rows without downtime was a lot of fun, especially given our confidence about the outcome. We knew our new TAO-like schema would be a significant upgrade over the old schema, and since we moved this information into its own separate data store we took about 30–40% of load away from our main database cluster. And no one noticed!</p><h4>We&#39;re hiring!</h4><p>This was a fun problem for us to work on. We have a ton of other fun problems left. If you are interested in working on systems and scale, please <a href="http://engineering.twitch.tv/">look at the Twitch Engineering site</a>!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d91e58f39cad" width="1" height="1" alt=""><hr><p><a href="https://medium.com/twitch-engineering/how-we-migrated-over-half-a-billion-records-without-downtime-d91e58f39cad">How we migrated over half a billion records without downtime</a> was originally published in <a href="https://medium.com/twitch-engineering">Twitch Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>