Discover more from The Pragmatic Engineer
The Platform and Program Split at Uber
The change that shaped the engineering culture for years to come, and my take on Platform teams
👋 Hi, this is Gergely with an originally 🔒 subscriber-only issue of the Pragmatic Engineer Newsletter — in fact, this was the first paywalled issue. 2 years after publishing this issue, I’ve opened it up to the public, celebrating 450,000 readers of the newsletter.
If you enjoy this article: you’ll like the upcoming ones as well. Subscribe to learn about challenges at Big Tech and startups through the lens of engineering managers and senior engineers:
In the spring of 2014, Uber’s Chief Product Officer, Jeff Holden, sent an email to the tech team. The changes outlined in this email would change how engineering operated and shape the culture for years to come. The email kicked off with this:
“After a huge amount of data collecting, thinking and debating among many folks across the company, we are ready to launch Programs & Platforms! (Attached to this email) you’ll find out whether you’re on a Program or Platform team, and where your seat will be with your new team.”
It had only been three years since Uber made its first full-time engineering hire, and there were already more than 100 engineers, 10 Product Managers (PM), and 15 designers at the company by this time. Almost all engineering teams operated independently, owning their roadmap and projects. This was an evolution from the very early days of Uber when things got done on a project basis of people coming together, shipping a project, splitting up when done and moving to the next project.
The email explained how the current org structure would completely change; over a dozen teams replaced by 16 program and 11 platform teams, with every person allocated to either a platform or a program team.
Most of the teams would not be fully staffed, and more than 100 people would need to be hired across engineering, product and design, to staff these teams. The new teams were stack ranked by importance – for example, teams responsible for growing the supply of drivers were ranked much higher than those generating rider demand.
This email executed Uber's biggest engineering organizational change: creating cross-functional program teams and introducing platform teams. To date, Uber operates following the legacy of this change, of teams being either platform or program teams.
But what is this split, and why does it make sense? Let’s start with the definition of the two types of teams.
Program teams – often referred to as Product teams at other companies – represented between 60–70% of the engineering population. These teams organize around a mission and are optimized for rapid execution and product innovation. Programs were defined with the following characteristics:
Long-lived as opposed to just assembled for a short project. The teams were formed around a mission such as Driving Experience, Marketplace Efficiency, or APAC Growth. The teams owned a well-defined mission.
Cross-functional. Each team had the staffing to allow it to execute its mission. In practice, this meant a mix of non-engineers and engineers on a team. It was common to have a product manager, a data scientist, and even a business operations person on the team. Engineering was also cross-functional, with backend and native mobile engineers on most teams. Some teams had web engineers as well. Teams usually owned features in the Rider, Driver, or Eats app. To build and operate features, you needed to build and own backend systems and the client code.
External customers to the Tech org. Program teams would work directly with customers, shipping features they used. Customers were not only Riders, Drivers, Eaters, or Couriers, although they were the majority. Internal customers included Operations, Customer Support or Accounting, and other smaller business area customers such as Freight customers, Jump bike riders, and others.
Focused on a business mission. All program teams were focused on moving the needle for the business. If the business changed drastically, for example, because there was no more need to focus on growth, then the team would cease to exist. Over time, Program teams did change. They usually only grew. However, some teams got disbanded after not growing as rapidly as the business hoped. An example of this was Uber Rush, where the team split up after it did not grow as fast as the business had hoped.
When joining Uber, I started and worked on a Program team for a long time; Rider Payments. Our mission was to provide a magical payment experience for all riders. The team was a cross-functional unit of eight native mobile and backend engineers when I started managing it. A PM, a data scientist, a designer and a product operations person were also part of the team, though did not report to me, as an engineering manager. The team eventually grew to around 12 engineers before we changed the mission of the team.
Our customers were riders using the Uber app. We measured our business impact with metrics like incremental customers onboarded, incremental gross bookings generated, or cost savings generated. These metrics changed with every planning cycle, adapting to whatever the company was focusing on.
Platform teams own the building blocks that Program teams used to ship business impact. Programs are built on top of Platforms, which enabled Programs to move faster. All Platforms teams shared the following characteristics:
Focused on a technical mission. Platforms are focused on technical goals like scaling a key area, achieving performance or availability goals, or building an easy to extend and maintain architecture that serves multiple teams and areas.
Specialized and rarely cross-functional. As Platforms solve technology problems, it rarely makes sense for cross-functional teams to do so. A Platform team typically worked on one domain or stack. Most teams would only have engineers of a certain stack. Later on, some platform teams started to work with Technical Product Managers (TPMs) or product managers, but this was rarely the case early on.
Customers are engineering teams and are internal (usually). Most customers for a platform team are engineers of other program teams or, in rare cases, people from the business side also using the platform. This was also why lots of platform teams could just consist of engineers. Some – though fewer – platform teams might serve external engineering customers directly, such as a team shipping a development SDK.
Consumed by multiple “verticals” (Programs or Platforms). Each Platform would have multiple customers. This was also a requirement for a Platform team to own any functionality. If a service or functionality would only be used by one Program, that Program should own it, not a Platform.
As my organization grew within Uber, I spun out platform teams, creating the Payments Web Platform and the Payments Mobile Platform teams. These teams owned the payments building blocks that other teams across Uber could use to quickly ship web or mobile payments capabilities.
Creating a platform team tends to be a challenge for many engineering leaders, myself included. Securing headcount is rarely trivial, staffing the team from the start can be tricky, and defining what success looks like is less straightforward than with Program teams.
If you are building a platform team, as a subscriber, you have access to 🔒 this platform narrative document that I used when making a business case to create a new platform team.
Shared Program/Platform Characteristics
While programs and platform teams solved different needs, they both shared several attributes:
Single manager for all engineers. Every engineer on the team – regardless of their stack or specialization – reported to the same engineering manager, who headed up the team. The engineering team was one tightly coupled unit.
You build it, you own it. Whatever a team built, they owned the quality, the oncall, and ensuring things operated. This meant both Platforms and Programs typically had oncalls. There were very rare exceptions to this.
The same quality bar. Regardless of which team you were on, the quality bar was the same. Your code was expected to be tested and the functionality monitored. Some might be surprised to learn that Platform teams ran their own monitoring and alerting on the metrics they owned. Platform teams would add telemetry to almost everything they did and usually knew when their system had an issue before customers did. For example, the Developer Experience team would get alerted for issues with the Continuous Integration (CI) service and could start to investigate well before an engineer would report the same issue.
No permission needed to build. You do not have to be a Platform to create new services, modules, or reusable components. Many platform pieces started with a Program team building it. This newly built platform piece would then either become a Platform team itself, or might be handed over to a Platform team operating in this domain to own.
Program teams splitting into further Programs and Platforms as they grew. As a natural consequence of the programs and platforms approach, as most program teams grew they tended to split into more programs, and some into platform teams. Platform teams tended to own shared functionality and responsibilities across programs. This “splitting” became a natural process in most parts of the organization.
All of these attributes are tied to team autonomy. Team autonomy together with engineering autonomy is something that innovative, “Silicon Valley-like” companies “get,” and which traditional companies often struggle to understand and grant.
Landing Teams on a Best-Effort Basis
Uber took a bold and decisive path in implementing this organizational change. They chose not to do a gradual, area-by-area change. Instead, leadership announced a date when all splits would happen, and teams would be set up as landing parties; a bit like how a landing party “beam down” in Star Trek from the USS Enterprise to a planet’s surface. Moving to Program and Platform teams happened at the same time as the company moved to its new Market Street headquarters in San Francisco, bundling the two changes together.
Uber decided to restructure ahead of having the sufficient number of people in place for all “landing parties” to be complete. What this meant was several teams were still operating as skeleton crews and were expected to catch up with hiring.
In my view, Uber was able to pull this restructuring move off for a few reasons. First, engineering leadership knew with high certainty that hiring would not be a problem based on both recruitment forecasts and the investment in recruitment. To make these kinds of expansion calls, speaking with recruitment – and getting their take on what it takes to hire certain targets – is a key step.
More importantly, Uber leadership must have had very high confidence in the business continuing to grow, and to eventually outgrow even the existing structure in place. Making a change this impactful would hit productivity in the short term, but the teams would bounce back right after and carry on executing with increased efficiency.
Confidence that the business would keep growing proved correct. Uber not only grew the ridesharing business significantly, but it also started Uber Eats in the summer of 2014, Uber Freight in 2017, and several other big, bold bets within the business.
Problems Solved Related to the Old Structure
Before the change, Uber operated in a classic, functional organizational structure with Engineering, Product Management, Business Operations, Design, and Data Science, each operating in their own groups. Engineers were grouped in teams, but those teams did not include people from other disciplines like Product Management or Design.
Engineering teams at the time included Rider Operations, Driver Operations, Dispatch and Mobile. These teams did not have dedicated product managers or other functions assigned to them. Product managers tended to own projects and would often work with multiple teams.
I’d describe this approach as project-based, although strictly speaking, there were stable engineering teams. However, projects dominated the way work got done and how people organized.
Upsides of this project-based approachwere plenty:
1. Response time. Any time a new opportunity or threat came up, you could form a project and tackle it. Not much coordination was needed.
2. Flexibility. This structure adapts well when you have little idea what type of work will come up, even in the short-term. In the early days of Uber, this was true. It was unclear if responding to external events, seizing a new opportunity, or executing on the existing plan would come first.
3. Little planning and structure overhead. Teams practically self-organized themselves with projects, continuously responding to the biggest challenges for the company. As long as this setup worked well, why add more processes to planning and organizing teams?
Downsides of the project-based approach also started to show, though. For Uber, at that time, these were the main ones:
1. Difficult to prioritize as the company grows. With a small team and few priorities, project-based work was easy to juggle. But Uber’s business was already very complex by this time. The Driver and Rider app had many parts that grew in complexity, with more rules than the original app.
It wasn’t just app functionality; the business operations teams needed to execute on more and more one-off initiatives in different cities. Other business units – from finance to legal and others – also had projects to get done. Prioritizing several dozens of projects was becoming more and more difficult.
2. Many cross-functional projects launched as MVPs, getting little love afterward. After a project was launched, the launch team immediately split up. An engineering team would still own the project, but other people, like the mobile engineer, Product Manager or Business Operation person, would focus on the next project.
With the ad-hoc approach for cross-functional work, it was a lot harder to start a “follow-up” project. This was especially true for work that involved mobile engineers, as they worked in teams separate from all other engineering teams.
3. Starting new projects became more difficult to coordinate. The theory of “start a project anytime, with the right people” sounds great with the project-based approach. However, the reality was not nearly so simple.
Each project typically needed people with specific skills and sometimes domain experience. This might have been a mobile engineer, a designer or a business operations person. However, those people were typically working on other projects. So instead of starting a project immediately, new projects had to coordinate when all people would become available. More frequently, people would juggle several projects.
4. More silo projects and fewer cross-functional projects were started. Because starting projects across multiple groups was difficult, it was no surprise that more projects with no cross-functional coordination were started. For example, because all mobile engineers worked in the Mobile team and it was hard to “book” a mobile engineer, most teams started to work on features that did not involve mobile work.
Uber reached the point where it needed to prioritize executing on projects that were best for the business - and, to do so, it needed to address the underlying issue blocking these efforts.
5. The most important company objectives were cross-functional by nature. Uber realized that shipping the “easy”, but siloed projects, is not in the interest of the business or the customers.
Uber needed to make the change of enabling cross-functional work easier. The Program teams defined the company-wide priorities with logical groupings, and the company committed to staffing these teams for the long run. Platform teams were put in place to support Program teams, to allow them to focus on their business mission, and to own the shared foundations that many Program teams build on top of.
Enjoying this article? Subscribe to get articles like this regularly👇
New Problems Created
There is no free lunch when it comes to org structures. Every structure change solves some problems and creates others. Uber was no different. The structural change brought in a few new problems that were clear from the start, and other issues that only crystallized later.
1. “Double reporting”. Product Managers, Designers, Business Operations and other functions would all be assigned to Program teams, while keeping reporting structures in their functional units. This would create a setup where the reporting line and the day-to-day work became separated.
In the above setup, a designer has a design manager: even though they work with a cross-functional team on a daily basis. This creates a “double-reporting” structure. Still, this can be a better setup than the alternative: a designer reporting to a Program lead who has no idea about design. This is because by reporting into a different function, the designer would have access to less professional guidance and fewer career growth paths.
All functional units kept their reporting lines. This change did make the lives of functional managers outside of engineering more challenging, by requiring them to keep tabs on several Programs. However, it brought more stability to career growth, by working on more stable teams, and doing fewer ad hoc, unexpected projects.
2. A less flexible way of responding to unexpected changes. In the project-based world, responding to unexpected changes was easy: pull in a project team, now. In the world of long-lived Program and Platform teams, this is more complex to do.
The loss in flexibility to respond to change was a deliberate tradeoff. It's also why smaller startups always have an edge in terms of adapting and changing how they work. Startups can adapt on a whim, while larger tech companies take time to reorganize themselves.
The most common approach to responding to new events is to either seed a new team that focuses on the new area, or do a reorg. Starting a new team, transferring a few people internally, and hiring for this team is the least disruptive approach. For more complex situations, a full-on reorg might be necessary. Uber's tech reorg, splitting into programs and platforms, is a good example of such a change.
3. Some teams overstay their welcome and do low priority work. In the Programs and Platforms world, each team had a clear vision and mission that they worked towards. However, what happens when the area the team owns becomes less important for the company? Looking at the bigger picture, the company's interest would be for people on this team to work on something else.
Solving this problem is typically done by leadership regularly reviewing whether each team should exist. Uber decided to do quarterly Programs and Platforms reviews. On these reviews, the team reviewed the impact of the team, the roadmap, and what would happen if this team ceased to exist.
I observed that Uber did a good job of questioning whether teams should exist, especially for Program teams. When the impact of a team declined, leadership would either change the funding of the team (e.g. move a few people out to work on other things), or wind these teams down and move people to work in a new area.
How a company adapts to a changing business environment makes or breaks it. Thisis a fact I saw first-hand at Uber. Companies that "move fast" and "ship ahead of their competition" are good at winding down teams that are no longer relevant and starting ones that are.
Uber was competing with startups which operated mostly on a project basis, just like how Uber operated in the past. These other startups would respond incredibly quickly to new market opportunities, to regulatory changes, or to the competition. Uber needed to retain its flexibility to respond to competitors and to solve most of the pain points they saw with the project-based approach.
3. What teams should be created, and who is the decision maker? When Uber launched the Programs & Platform reorg, all the teams were defined. Quarterly reviews would confirm if teams were still relevant. If not, they might be downsized or disbanded.
But who decides on creating new teams, what is the process, and who has the final say on funding? After all, at a fast-growing company like Uber, there would be no shortage of ideas for new teams.
The decision would stay with the tech leadership team; suggestions and business cases were sent there. Program team decisions would live with the CPO, and platform team decisions would live with the CTO. Over time, as Uber grew, the decision would move down to organization leaders.
Creating a new product and platform team is something we'll dive more into in later issues of this newsletter. I've made business cases for creating and several program and platform teams over the years.
As a subscriber, feel free to check out 🔒 this platform narrative document that served as the business case for creating a platform team.
If you have created a platform team and can share your experience, please hit reply - I’d love to hear from you!
It’s been more than seven years since the Program-Platform split at Uber. I will say that these changes worked well for the business. Throughout my time, I observed how critical platform teams kept up with user growth and enabled program teams to deliver quickly.
The platform-program split has not evolved much at Uber because it has not needed to. The programs & platforms approach lends itself to creating “startups within a startup” as the company grows.
For a new initiative, a small program team would be put in place. They’d utilize existing platforms where they could. As this small team achieved success, they’d start to grow. They’d fill up a whole Program team. They would grow further, and split into two Program teams. As they grew, they might have spawned a Platform team after spanning into multiple Program teams… and so on.
To have 30–40% of engineering working on platforms is a massive investment. Any business person would be hard-pressed to agree with this allocation; after all, this could mean 30–40% fewer features shipped in the short term.
However, Uber had three types of platform teams, all of them serving different customers:
Infra-type platforms were the first Platform teams across Uber. These teams provide foundational services to most engineering teams. Teams like this included Storage, Compute, Mobile Platform, and so on.
Developer Platform is a special type of infra-type platform worth highlighting. The mission of this group was to make engineers and engineering teams more efficient across the company. They owned CI/CD systems, the developer experience on different platforms, and researched innovative ways to enable engineers to deliver more efficiently, get feedback faster, and iterate in smaller steps.
Customer-facing Platforms are a less common platform edge case. They offer services to either internal, non-engineering customers, or external customers who could also include engineers. Examples include the Communications Platform, who offer messaging to customers and to business users in a “low-code” type of way. Another example is the team building the Uber Developer SDK, and offering the services to external developers.
Product Platform teams evolved from needs that multiple Program teams had. For example, the Tipping and Rating Platform team evolved after realizing that several Program teams need these services. They built a product that is used by a variety of teams, from Driver, through Eats, to Freight teams. All of these teams have slightly different use cases that the platform caters for.
What would happen if we kept most engineers working on product areas, not creating any teams owning the foundations? If Uber had done so, I am certain that architecture, scalability, and tech debt would have caught up with engineering early on. The team would have had to take unplanned diversions to address systems issues that had been swept under the rug. On top of this, engineering attrition would have likely have spiked. Who wants to keep working on systems that are being held together by duct tape?
The notion of platform teams is not unique to Uber. Many fast-growth organizations reaching 20 – 30 engineers in a given discipline consider creating platform teams. I strongly believe that platforms are key to scaling any technology organization, in order to operate with higher leverage.
My Brief Take on Platform Teams
I have been working with platform teams for many years, have been involved in the creation of several, and observed dozens of them operating. Here are a few of my takes on platform teams.
Platforms teams are non-intuitive to put in place. Looking at platform teams with a business lens, they make little sense.
“Why would I have 20 to 40% of my engineers doing things that customers will never see? Even worse, why would I have my most senior engineers work on these efforts?”
This question is a very common reaction from the business to the idea of funding platform teams. True enough, platform teams make no sense at small organizations, or at those that are not growing much and have a structure that works well.
Platform teams improve organizational efficiency. They reduce duplication of work and help with standardization of approaches, when standardization is a benefit for the organization. For example, setting up a Backend Security Platform team can help with standardizing security vulnerability checks across the company. They would also help uncover duplicated – and inconsistently implemented – security approaches.
Reducing duplication of work becomes easier with platform teams in place. It’s in the interest of platform teams to onboard customers who would benefit from using their services. This allows Product teams to spend more effort focusing on their offering, but also results in Platforms becoming more flexible and serving more customers, better.
Platform teams are a must-have when scaling up and scaling fast. When you’ve crossed the line of a few dozen engineers, and you’re in a business that is growing rapidly in customers, products, complexity, platform teams make a huge difference.
Platform teams own non-functional requirements like the reliability of systems, the ability to handle more load, or the ability to support more products, in a way that satisfies non-functional constraints.
Non-functional constraints are all the invisible things that are critical to any product to function. These include:
Reliability (uptime, storage reliability, data durability)
Latency (systems response time, UI latency, and others)
Performance (systems, UI, and others)
Client-side non-functional constraints (memory usage, application footprint, and others)
Developer experience (compile/testing/deploy times, CI turnaround times, developer tooling UX)
The more complex an organization becomes, the more sense it makes for dedicated teams to own these non-functional parts and ensure all teams adhere to the same requirements.
Product platform teams are just as important in scaling as infrastructure-like platform teams are. As a product area grows and splits into multiple product teams, it often makes sense to move out common functionality and services to a product platform team of its own. This is, for example, how Uber’s Communications Platform team was born, as discussed in the Aftermath section.
Platform teams bring new pain points. While I cannot deny how helpful platform teams are, they come with a host of new challenges in an organization that introduces them. I won’t go into depth now, and we’ll do so in later issues, but here are a few as food for thought:
Harder to define and measure goals and key results. Measuring the impact of a platform team becomes more challenging than a Program team. Program teams almost always have their goals tied to business metrics. For platform teams, this is not the case. Further, platform teams move the needle on a longer timeframe, so the feedback on their goals is slower than the Program teams.
Pulling away seniority from programs and the “seniority saturation”. Platform teams work across many engineering teams and often have a company-wide impact. Working on such teams, engineers also rarely have to deal with business stakeholders; their customers are other engineers. This setup sounds like paradise to many senior and above engineers. Platform teams can get over-saturated with senior people seeking to avoid the suits, making professional growth difficult for most team members.
Working on projects the Platform team wants instead of what customers need. Platform teams need to balance building things that customers don’t ask for, versus what they do. For example, a platform team will need to keep investing reliably and keep tech debt at bay, but also add new capabilities important to customer teams. However, there’s a danger that the Platform team starts to over-prioritize the work they deem important, to the point of breaking customer teams.
Communicating with customers. I’ve observed Platform teams build a feature they expected their customers to want, then release it, only for it to cause frustration with customers, who did not want the feature, nor the additional work it meant. How to keep an open loop with customers is a major challenge for any newly formed Platform team.
We’re just getting started on the Products and Platforms Topic
Products and Platforms is a topic close to my heart, and we’ve just scratched the surface with how Uber moved to Program and Platform teams to scratch their itch.
Following the publication of this article, we went into more details on platform teams, talking with senior Uber leaders and industry veterans from various companies about their perspectives on products and platforms — and their impact on developer productivity — in future issues of this newsletter:
Ganesh Srinivasan - formerly VP of Engineering at Uber founded Uber’s mobile platform team when there were only five mobile engineers at the company. We talked about why moving fast was so important and what else he’s learned about platforms in the issue Platform teams with Ganesh Srinivasan, Chief Product & Engineering Officer at Confluence.
Adam Rogal used to head up Uber’s Mobile Platform team. He is now Director of Developer Platform at Doordash. We went into details in the article Platform teams and developer productivity with Adam Rogal, Dir. Developer Platform at DoorDash.
Max Kanat-Alexander, principal engineer at LinkedIn shared How LinkedIn measured engineering efficiency
Laura Tacho, a VP of engineering and a leadership coach went into details on Measuring software engineering productivity.
If there are people whose perspective you’d value, please reach out. If you’ve worked in a product/platform split, please share your thoughts and areas you’d be interested in reading deeper insights.
🔒 A platform team narrative based on the business case I used to fund a platform team
🔒Platform teams with Ganesh Srinivasan, Chief Product & Engineering Officer at Confluent
🔒 Platform teams and developer productivity with Adam Rogal, Director of Developer Platform at DoorDash
Enjoyed this article? Subscribe to get articles like this in your inbox, every week:👇