Background
eBay’s View Item page lives at the center of our e-commerce platform. Our customers load this page over 250 million times each day, and stringent budgets on site speed and availability guarantee the quality of their experience. And yet, this page had its last intentional rewrite ten years ago.
A decade of rapid iteration made the codebase increasingly difficult to maintain. This hampers our ability to continue the pace of innovation our customers have come to expect. Figure 1 shows the result of this rapid, organic growth: a legacy stack requiring duplication of work for delivery to our four platforms (desktop, mobile web, iOS and Android). It was essential for us to modernize this system and the relevant development process to unlock the velocity gains necessary to allow us to continue innovating for our customers.
Goals
Our primary goal was to continually unlock velocity gains from day one rather than undergo an extended effort with a large payoff at the end. But how would we accomplish this?
The core effort would be to improve developer experience and productivity. The outcome must be that new features are written only once. Modern technologies and practices should be adopted to make it easier to hire and retain talent while also making it easier to add powerful features. New code must be documented as a requirement for acceptance to ease future troubleshooting, maintenance, and extensibility.
The health of the project will be measured against the four key metrics laid out in the book Accelerate, by Nicole Forsgren, Jez Humble and Gene Kim, with goals for improvement (table 1). Accelerate is used as a reference point for industry leaders seeking to define velocity.
Strategy
We wanted a new architecture (figure 2) that would eliminate the duplication of work and fulfill all stated goals.
It is easy to draw a diagram like this, but the reality of size and scope in our three legacy services (Desktop monolith service, Native experience service, Mobile web service) could lead to a years-long effort in creating a service with equivalent functionality under the new architecture. The problem would be exacerbated by the continuous introduction of new features (making development of the new service akin to hitting a moving target). Instead, we developed a strategy allowing the full migration of smaller pieces of code over time (figure 3). Our plan crystallized as follows:
-
Introduce a new service between the data layer and the legacy system.
-
Legacy services get their data proxied through the new service.
-
Implement modern versions of each module in the new service and place their data into the proxied data stream.
Outcome
At the time of this writing we are in phase two, with approximately 90 percent of modules migrated to the new architecture. Our new strategy is increasing development velocity across all areas of View Item.
-
All supported platforms now receive the same data from the same service, which removes the duplication of work by 1/3.
-
The module-by-module migration allowed us to unlock velocity gains of 200 percent on related new features from the beginning of the project.
-
Developer Experience
-
It is easier to onboard new team members due to the accurate documentation and modern tech stack that they are already familiar with.
-
Code merges happen more quickly due to the faster automation pipeline.
-
We increased the overall productivity due to improvements in the readability of code, documentation, and project structure.
-
All new features are now written only once and immediately support all four platforms.
Table 2 reflects corresponding improvements in our four key metrics.
The culmination of these improvements is a 200 percent increase in velocity. Even better, we saw this increase immediately during the module migration phase of the project. Each module migration, from the very first to the very last, resulted in a corresponding increase in velocity. With the project nearing completion, we are already at a 50 percent reduction in effort (in days) for new product improvements.
Learnings
Each module migration was kicked off with a deep dive into related legacy code. Due to the age of the codebase, the teams responsible for the migration no longer contain the original code authors. Initially, we focused on generating comprehensive documentation of the legacy system to aid in development of the new code. It was quickly determined that this process was not yielding the expected value; it was getting stale as we discovered new use cases. A pivot was made to focus on a rapid survey of the legacy modules to generate a high-level summary. We then relied on reverse-engineering while creating the new modules with comprehensive documentation on only the new code, to avoid future teams suffering the same fate.
The first few modules to be migrated followed a holistic approach that revised all portions of code that interacted with it, all the way down to including the client and display layer. Such changes are always A/B tested to be sure customer experience is improved. The data for some module migration with UX changes showed a negative impact on our customers. This cost us extra time waiting for the test results and to implement a new pivot to the feature to address those shortcomings. The most important thing we learned early on in the project was that we needed to completely segregate the back-end code modernization from any user-facing behavior changes. This new approach allowed our back-end teams to finalize all subsequent migrations in a shorter time. Client developers could then work on independent timelines for implementation, testing, and iteration.
The overarching theme of these lessons is to be flexible. We cultivated a team culture of continuously challenging our decisions and assumptions. Iteration on the plan itself was the most important part of being agile on such an ambitious project.
Conclusion
Doubling a team’s velocity is not a trivial task. It requires careful planning, execution, and an unwavering commitment from executive leadership. With all of these in place, our amazing team was able to achieve our goals. The project has been ongoing for two years, and today is close to the finish line, with over 90 percent of work completed. The step-by-step strategy allowed us to immediately unlock velocity gains at the beginning of the process and continuously unlock further gains during the entire timeline without having to wait for the project’s full completion. Doubling our velocity means doubling our ability to remain a market leader by responding quickly to our customers’ needs.
This is all possible because the incredible team came together to solve the problem with perseverance and hard work. We would like to thank everyone who is involved on this great mission beyond team boundaries to double the velocity at eBay. Our sincere thanks to Jamie Iannone (CEO, eBay) for initiating this program at eBay.
Note: Lead author Lakshimi Duraivenkatesh is no longer at eBay, at the time of publication.