Last week, GitHub experienced an incident that resulted in degraded service for 24 hours and 11 minutes. While portions of our platform were not affected by this incident, multiple internal systems were affected which resulted in our displaying of information that was out of date and inconsistent. Ultimately, no user data was lost; however manual reconciliation for a few seconds of database writes is still in progress. For the majority of the incident, GitHub was also unable to serve webhook events or build and publish GitHub Pages sites.
All of us at GitHub would like to sincerely apologize for the impact this caused to each and every one of you. We’re aware of the trust you place in GitHub and take pride in building resilient systems that enable our platform to remain highly available. With this incident, we failed you, and we are deeply sorry. While we cannot undo the problems that were created by GitHub’s platform being unusable for an extended period of time, we can explain the events that led to this incident, the lessons we’ve learned, and the steps we’re taking as a company to better ensure this doesn’t happen again.
The majority of user-facing GitHub services are run within our own data center facilities. The data center topology is designed to provide a robust and expandable edge network that operates in front of several regional data centers that power our compute and storage workloads. Despite the layers of redundancy built into the physical and logical components in this design, it is still possible that sites will be unable to communicate with each other for some amount of time.
At 22:52 UTC on October 21, routine maintenance work to replace failing 100G optical equipment resulted in the loss of connectivity between our US East Coast network hub and our primary US East Coast data center. Connectivity between these locations was restored in 43 seconds, but this brief outage triggered a chain of events that led to 24 hours and 11 minutes of service degradation.
In the past, we’ve discussed how we use MySQL to store GitHub metadata as well as our approach to MySQL High Availability. GitHub operates multiple MySQL clusters varying in size from hundreds of gigabytes to nearly five terabytes, each with up to dozens of read replicas per cluster to store non-Git metadata, so our applications can provide pull requests and issues, manage authentication, coordinate background processing, and serve additional functionality beyond raw Git object storage. Different data across different parts of the application is stored on various clusters through functional sharding.
To improve performance at scale, our applications will direct writes to the relevant primary for each cluster, but delegate read requests to a subset of replica servers in the vast majority of cases. We use Orchestrator to manage our MySQL cluster topologies and handle automated failover. Orchestrator considers a number of variables during this process and is built on top of Raft for consensus. It’s possible for Orchestrator to implement topologies that applications are unable to support, therefore care must be taken to align Orchestrator’s configuration with application-level expectations.
During the network partition described above, Orchestrator, which had been active in our primary data center, began a process of leadership deselection, according to Raft consensus. The US West Coast data center and US East Coast public cloud Orchestrator nodes were able to establish a quorum and start failing over clusters to direct writes to the US West Coast data center. Orchestrator proceeded to organize the US West Coast database cluster topologies. When connectivity was restored, our application tier immediately began directing write traffic to the new primaries in the West Coast site.
The database servers in the US East Coast data center contained a brief period of writes that had not been replicated to the US West Coast facility. Because the database clusters in both data centers now contained writes that were not present in the other data center, we were unable to fail the primary back over to the US East Coast data center safely.
Our internal monitoring systems began generating alerts indicating that our systems were experiencing numerous faults. At this time there were several engineers responding and working to triage the incoming notifications. By 23:02 UTC, engineers in our first responder team had determined that topologies for numerous database clusters were in an unexpected state. Querying the Orchestrator API displayed a database replication topology that only included servers from our US West Coast data center.
By this point the responding team decided to manually lock our internal deployment tooling to prevent any additional changes from being introduced. At 23:09 UTC, the responding team placed the site into yellow status. This action automatically escalated the situation into an active incident and sent an alert to the incident coordinator. At 23:11 UTC the incident coordinator joined and two minutes later made the decision change to status red.
It was understood at this time that the problem affected multiple database clusters. Additional engineers from GitHub’s database engineering team were paged. They began investigating the current state in order to determine what actions needed to be taken to manually configure a US East Coast database as the primary for each cluster and rebuild the replication topology. This effort was challenging because by this point the West Coast database cluster had ingested writes from our application tier for nearly 40 minutes. Additionally, there were the several seconds of writes that existed in the East Coast cluster that had not been replicated to the West Coast and prevented replication of new writes back to the East Coast.
Guarding the confidentiality and integrity of user data is GitHub’s highest priority. In an effort to preserve this data, we decided that the 30+ minutes of data written to the US West Coast data center prevented us from considering options other than failing-forward in order to keep user data safe. However, applications running in the East Coast that depend on writing information to a West Coast MySQL cluster are currently unable to cope with the additional latency introduced by a cross-country round trip for the majority of their database calls. This decision would result in our service being unusable for many users. We believe that the extended degradation of service was worth ensuring the consistency of our users’ data.
It was clear through querying the state of the database clusters that we needed to stop running jobs that write metadata about things like pushes. We made an explicit choice to partially degrade site usability by pausing webhook delivery and GitHub Pages builds instead of jeopardizing data we had already received from users. In other words, our strategy was to prioritize data integrity over site usability and time to recovery.
Engineers involved in the incident response team began developing a plan to resolve data inconsistencies and implement our failover procedures for MySQL. Our plan was to restore from backups, synchronize the replicas in both sites, fall back to a stable serving topology, and then resume processing queued jobs. We updated our status to inform users that we were going to be executing a controlled failover of an internal data storage system.
While MySQL data backups occur every four hours and are retained for many years, the backups are stored remotely in a public cloud blob storage service. The time required to restore multiple terabytes of backup data caused the process to take hours. A significant portion of the time was consumed transferring the data from the remote backup service. The process to decompress, checksum, prepare, and load large backup files onto newly provisioned MySQL servers took the majority of time. This procedure is tested daily at minimum, so the recovery time frame was well understood, however until this incident we have never needed to fully rebuild an entire cluster from backup and had instead been able to rely on other strategies such as delayed replicas.
A backup process for all affected MySQL clusters had been initiated by this time and engineers were monitoring progress. Concurrently, multiple teams of engineers were investigating ways to speed up the transfer and recovery time without further degrading site usability or risking data corruption.
Several clusters had completed restoration from backups in our US East Coast data center and begun replicating new data from the West Coast. This resulted in slow site load times for pages that had to execute a write operation over a cross-country link, but pages reading from those database clusters would return up-to-date results if the read request landed on the newly restored replica. Other larger database clusters were still restoring.
Our teams had identified ways to restore directly from the West Coast to overcome throughput restrictions caused by downloading from off-site storage and were increasingly confident that restoration was imminent, and the time left to establishing a healthy replication topology was dependent on how long it would take replication to catch up. This estimate was linearly interpolated from the replication telemetry we had available and the status page was updated to set an expectation of two hours as our estimated time of recovery.
GitHub published a blog post to provide more context. We use GitHub Pages internally and all builds had been paused several hours earlier, so publishing this took additional effort. We apologize for the delay. We intended to send this communication out much sooner and will be ensuring we can publish updates in the future under these constraints.
All database primaries established in US East Coast again. This resulted in the site becoming far more responsive as writes were now directed to a database server that was co-located in the same physical data center as our application tier. While this improved performance substantially, there were still dozens of database read replicas that were multiple hours delayed behind the primary. These delayed replicas resulted in users seeing inconsistent data as they interacted with our services. We spread the read load across a large pool of read replicas and each request to our services had a good chance of hitting a read replica that was multiple hours delayed.
In reality, the time required for replication to catch up had adhered to a power decay function instead of a linear trajectory. Due to increased write load on our database clusters as users woke up and began their workday in Europe and the US, the recovery process took longer than originally estimated.
By now, we were approaching peak traffic load on GitHub.com. A discussion was had by the incident response team on how to proceed. It was clear that replication delays were increasing instead of decreasing towards a consistent state. We’d begun provisioning additional MySQL read replicas in the US East Coast public cloud earlier in the incident. Once these became available it became easier to spread read request volume across more servers. Reducing the utilization in aggregate across the read replicas allowed replication to catch up.
Once the replicas were in sync, we conducted a failover to the original topology, addressing the immediate latency/availability concerns. As part of a conscious decision to prioritize data integrity over a shorter incident window, we kept the service status red while we began processing the backlog of data we had accumulated.
During this phase of the recovery, we had to balance the increased load represented by the backlog, potentially overloading our ecosystem partners with notifications, and getting our services back to 100% as quickly as possible. There were over five million hook events and 80 thousand Pages builds queued.
As we re-enabled processing of this data, we processed ~200,000 webhook payloads that had outlived an internal TTL and were dropped. Upon discovering this, we paused that processing and pushed a change to increase that TTL for the time being.
To avoid further eroding the reliability of our status updates, we remained in degraded status until we had completed processing the entire backlog of data and ensured that our services had clearly settled back into normal performance levels.
All pending webhooks and Pages builds had been processed and the integrity and proper operation of all systems had been confirmed. The site status was updated to green.
During our recovery, we captured the MySQL binary logs containing the writes we took in our primary site that were not replicated to our West Coast site from each affected cluster. The total number of writes that were not replicated to the West Coast was relatively small. For example, one of our busiest clusters had 954 writes in the affected window. We are currently performing an analysis on these logs and determining which writes can be automatically reconciled and which will require outreach to users. We have multiple teams engaged in this effort, and our analysis has already determined a category of writes that have since been repeated by the user and successfully persisted. As stated in this analysis, our primary goal is preserving the integrity and accuracy of the data you store on GitHub.
In our desire to communicate meaningful information to you during the incident, we made several public estimates on time to repair based on the rate of processing of the backlog of data. In retrospect, our estimates did not factor in all variables. We are sorry for the confusion this caused and will strive to provide more accurate information in the future.
There are a number of technical initiatives that have been identified during this analysis. As we continue to work through an extensive post-incident analysis process internally, we expect to identify even more work that needs to happen.
Adjust the configuration of Orchestrator to prevent the promotion of database primaries across regional boundaries. Orchestrator’s actions behaved as configured, despite our application tier being unable to support this topology change. Leader-election within a region is generally safe, but the sudden introduction of cross-country latency was a major contributing factor during this incident. This was emergent behavior of the system given that we hadn’t previously seen an internal network partition of this magnitude.
We have accelerated our migration to a new status reporting mechanism that will provide a richer forum for us to talk about active incidents in crisper and clearer language. While many portions of GitHub were available throughout the incident, we were only able to set our status to green, yellow, and red. We recognize that this doesn’t give you an accurate picture of what is working and what is not, and in the future will be displaying the different components of the platform so you know the status of each service.
In the weeks prior to this incident, we had started a company-wide engineering initiative to support serving GitHub traffic from multiple data centers in an active/active/active design. This project has the goal of supporting N+1 redundancy at the facility level. The goal of that work is to tolerate the full failure of a single data center failure without user impact. This is a major effort and will take some time, but we believe that multiple well-connected sites in a geography provides a good set of trade-offs. This incident has added urgency to the initiative.
We will take a more proactive stance in testing our assumptions. GitHub is a fast growing company and has built up its fair share of complexity over the last decade. As we continue to grow, it becomes increasingly difficult to capture and transfer the historical context of trade-offs and decisions made to newer generations of Hubbers.
This incident has led to a shift in our mindset around site reliability. We have learned that tighter operational controls or improved response times are insufficient safeguards for site reliability within a system of services as complicated as ours. To bolster those efforts, we will also begin a systemic practice of validating failure scenarios before they have a chance to affect you. This work will involve future investment in fault injection and chaos engineering tooling at GitHub.
We know how much you rely on GitHub for your projects and businesses to succeed. No one is more passionate about the availability of our services and the correctness of your data. We will continue to analyze this event for opportunities to serve you better and earn the trust you place in us.
I’m thrilled to share that the Microsoft acquisition of GitHub is complete. 🎉 Monday is my first day as CEO. Millions of people rely on GitHub every day, and I am honored by the opportunity to lead this company.
When we announced the acquisition in June, I shared two principles for GitHub that are worth repeating:
GitHub will operate independently as a community, platform, and business. This means that GitHub will retain its developer-first values, distinctive spirit, and open extensibility. We will always support developers in their choice of any language, license, tool, platform, or cloud.
GitHub will retain its product philosophy. We love GitHub because of the deep care and thoughtfulness that goes into every facet of the developer’s experience. I understand and respect this, and know that we will continue to build tasteful, snappy, polished tools that developers love.
Ultimately, my job is to make GitHub better for you.
I’ve spent the past few months meeting with hundreds of developers as I prepared for this role, from maintainers to startups to large businesses. The passion for GitHub is amazing—both in the areas where we excel and in the areas where you want us to do more. I’ve learned a lot from these conversations, and listening to our customers will be a core part of how GitHub operates as a company.
Three objectives will be top of mind for us as we build the future of GitHub:
We will start by focusing on the daily experience of using GitHub and will double down on our paper cuts project. We will improve core scenarios like search, notifications, issues/projects, and our mobile experience. And of course we are excited to make GitHub Actions broadly available.
We believe in the power of communities—that we can all achieve more when we collaborate with others. As the world’s largest developer community, GitHub brings together over 31 million developers to create, collaborate, share, and build on each other’s work.
Our vision is to serve every developer on the planet, by being the best place to build software. This is a dream opportunity for all of us at GitHub, and we couldn’t be more excited to roll up our sleeves and start this next chapter.
Governments around the world use GitHub to build software, shape policy, and share information with constituents. To better support the missions of our government community, we participated in the US government’s recent efforts to streamline the security review and authorization for certain software tools—and today we’re pleased to share that GitHub Business Cloud is authorized via the FedRAMP Tailored baseline of security controls.
This exciting milestone means government users can continue to use GitHub with the confidence that our platform meets the low impact software-as-a-service (SaaS) baseline of security standards set by our US federal government partners.
The US General Services Administration’s (GSA) Federal Risk and Authorization Management Program (FedRAMP) standardizes security assessment, authorization, and continuous monitoring of cloud products and services by federal agencies. Instead of agencies individually authorizing cloud service offerings, FedRAMP offers a single authorization process, speeding up the government’s adoption of cloud services.
FedRAMP applies to a wide range of government technology services. The team at GSA recognized an opportunity to fine-tune FedRAMP specifically for software-as-a-service (SaaS) providers, allowing GitHub to provide feedback as they created the new FedRAMP Tailored framework. We’ve completed the assessment phase and Business Cloud has secured the FedRAMP Tailored Authorization.
In the summer of 2009, The New York Senate was the first government organization to post code to GitHub. In 2013 the GSA made their initial commit—and today GitHub has thousands of active government users. Agencies use GitHub to develop software, collaborate with the public on open source, publish data sets, solicit input on policies, and more.
The Tailored framework lowers the barrier to entry for cloud software providers interested in securing FedRAMP Authorization. It’s our hope that the new framework controls helps SaaS providers more efficiently meet government security standards and makes it easier for federal, state, and local government agencies to use the development tools they need to do their best work.
With GitHub’s FedRAMP Authorized service, agencies can:
These are not restricted to government agencies—and everyone in the GitHub community can benefit from these security and privacy enhancements.
Continuing our work on EU copyright reform, last week GitHub visited Brussels to host an event for developers and policymakers about open source and copyright. During our trip, we also met with EU policymakers who are negotiating the final details of the EU Copyright Directive. Read on for a full event recap and to get the latest on where things stand for open source in the current negotiations.
Since GitHub’s first trip to Brussels in February, we’ve worked alongside other companies, organizations, and developers in the open source software community to raise awareness about the EU Copyright Directive. While we recognize that current copyright laws are outdated in many respects and need modernization, we are concerned that some aspects of the EU’s proposed copyright reform package would inadvertently affect software.
As part of our ongoing efforts to mobilize developers and educate policymakers about this, GitHub hosted an event last Tuesday in Brussels with OpenForum Europe and Red Hat. We invited EU developers, policymakers, researchers and more to join us for Open Source and Copyright: from Industry 4.0 to SMEs.
OpenForum Europe’s Astor Nummelin Carlberg welcomed the crowd, and then James Lovegrove from Red Hat moderated a round of lightning talks on different topics:
GitHub’s Abby Vollmer shares what developers can do to help with the EU copyright negotiations.
After the formal discussion, we finished out the evening with drinks and great conversations among developers, policy wonks, reporters, researchers, and policymakers alike. A big thank you to everyone who came out for the event and participated!
But our work isn’t over yet. In our last update, we explained that the EU Council, Parliament, and Commission were ready to begin final-stage negotiations of the copyright proposal. They’ll resume negotiations this Thursday. Of the parts most relevant to developers, negotiators from those three institutions are now working on exceptions to copyright for text and data mining (Article 3), among other “technical” elements of the proposal.
Article 13 (which would likely drive many platforms to use upload filters on user-generated content) is expected to be a thornier discussion, so negotiators are trying to get the technical elements resolved first. And since Article 2 defines which services are in the scope of Article 13, Articles 2 and 13 will be discussed together.
This means it’s not too late to contact these policymakers with your thoughts on what outcomes are best for software development. Here’s our take:
tl;dr = Council, adopt the Parliament’s language in Article 2.
Article 2 is important because it determines which services need to comply with Article 13. As an overall note, the language Article 2 uses to define what those services are could use some clarity, especially around what words like “organises,” “optimises,” and “promotes” mean. However, there are a few outstanding issues with the definition that are more directly relevant for software development:
We believe we’ve made some headway in our meetings last week in Brussels by describing how many software development platforms run as a business, but do not profit from content posted under an open source license.
This distinction isn’t intuitive, and developers can help educate policymakers about:
tl;dr = Adopt Article 3a as a mandatory exception.
On Article 3, including a broader exception for text and data mining that extends beyond only research organizations for scientific, non-profit purposes will be crucial for EU developers. However, that’s currently proposed as an optional exception (Article 3a). So why should the exception be mandatory, not just optional?
Contact your Council members to explain that limiting the software exclusion to only non-for-profits in Article 2 would fail to protect open source software in Europe. On Article 3, tell them why a broad, mandatory exception for text and data mining will help EU developers and businesses stay competitive. Make it clear how important this exception will be—especially where artificial intelligence and machine learning are at play.
Developers, let’s help policymakers get these parts of the proposal right.
As our 2018 Octoverse report shows, the GitHub community comes from nearly every country and territory in the world—and we’re still growing. So as much as we loved seeing everyone who made it to GitHub Universe, we know there are even more of you who couldn’t join us in person.
This year, we’re running The Check-In: our inaugural webcast for everyone who couldn’t attend Universe. We’ll recap all the latest Universe product releases and features—meaning you won’t miss a thing. Then after our first post-Universe episode, we’ll continue hosting The Check-In webcast as a quarterly round-up of what’s new at GitHub for our business customers.
In this 45-minute webcast, we’ll deep dive into new releases announced at Universe, including:
The Check-In webcast takes place on October 25 across three time zones, depending on where you are. Ready to save your seat? Choose your region below to register: