Under the Hood of Uber: the Tech Stack and Software Architecture

Let's face it. Uber is an inspiring example for both startups and existing taxi services. Why? Because the app provides users with a convenient experience when hailing a cab. 

What could be simpler? You can hail a cab in tour taps: open the app, type the address, select riding options, and confirm.

That's why people search for "Uber tech stack" and "What programming languages can I use to create an app like Uber?" on the Internet. But the key is that technologies and programming languages are just a means for Uber to meet its business goal - to provide fast and convenient taxi-hailing services.  

So, don't be deceived. Those technologies wouldn't suit your business needs unless your taxi app serves millions of users. Moreover, Uber technologies are costly to implement. 

On the other hand, you can learn from Uber's example about obstacles your taxi app might face in the future and how to overcome them. 

Since you are here to learn about the Uber technology stack, we will gladly share it with you.   

Is it hard to build an app like Uber? 

The short answer is "yes." Uber processes vast amounts of information leveraging sophisticated ML and data analytics platforms built in-house. 

Thus, to develop an exact Uber clone, you need a significant amount of money and a large development team. 

But why would you want to copy Uber functionality? Don't do that,  instead, you can start your cab-hailing service with simple functionality and add integrations as your business grows. 

With this idea in mind, let's investigate Uber-like app development requirements and define the technology stack. 

How do I build a real-time-app like Uber?

To develop an application similar to Uber, get to know what Uber consists of. Three main components power Uber - a passenger app, driver app, and marketplace. 

Passenger app. If you have used the Uber app at least once, you know the passenger app functionality. The app has all features necessary for hailing a cab, including GPS tracking, online payments, etc. 

Driver app. This Uber component shows new ride requests from passengers nearby, allows, accepts or declines ride requests, and has a built-in map. 

But the real magic happens at the marketplace that connects these two applications. 

The marketplace carries out the most complex tasks. This component handles online requests from both Uber's apps, matches passengers with drivers, and processes other transactions. Uber also leverages its marketplace for other products (UberRUSH and UberEATS). 

Thus, to create a similar app, you need two user interfaces for hailing a cab and accepting requests, and a sophisticated dispatch system to handle online operations. Let's see how this process works from the inside. 

Related reading: How to develop an application like Uber 

How does the Uber app technically work?

Every ride request made by a passenger generates a lot of information. The app receives data about the passenger, location, credit card information, taxi drivers nearby, their names and car details, and the ride cost and length. But how does information travel across the system? 

Right after you push a button to find a cab, the platform launches the following process: 

  • Stores ride information on the database 
  • Processes your ride request with the current geolocation
  • Streams the processed data to the matching algorithm 
  • Searches information about drivers nearby in the database 

Uber also leverages user-generated information for:

  • Training AI-based ML algorithm 
  • Visualizing your ride requests in the form of a process graphs

uber data processing flow

[Data processing flow, source]

Apart from knowing how the app works, you should also be aware of other project requirements. 

Requirements for Uber-like projects

So, what should your cab-hailing app include to deliver the same experience as Uber? 

The core requirements are:

  • Simple UI/UX design 

The application should have a clear design for both drivers and passengers. The app's layout should help designers create new features without drawing a new design each time an Uber programmer develops a new feature. For this purpose, the company has its own UI framework, which we will discuss a bit later. 

  • Microservice architecture 

With time, the number of the app's features will grow. Thus, consider microservice architecture for your app from the very beginning. We already described the difference between monolithic and microservice architecture in the previous article. In short, monolithic architecture simplifies regular app updates and new app parts deployment. 

  • Streaming services 

Many of Uber's functionalities operate in real-time. From location tracking and matching to online payments and maps - all this functionality requires significant computing power and is expected to operate without downtime. Moreover, all these actions happen numerous times in a second in different parts of the globe. For that purpose, on-premise hosting servers fail to provide streamlined operations. That is why Uber hosts its infrastructure on cloud hosting with a dedicated network, located in a particular geographic area so that online services can work without delays.  

  • Cloud storage 

Operating in numerous locations and serving millions of users generates tons of data. There is no on-premise solution that can store such an amount of information. For this reason, Uber leverages cloud storage. 

Now, let's answer the question of how the app was created. 

I want to develop an app like Uber. What is the detailed explanation of its architecture?

Since the company's launch in 2009, the backend has had a monolithic architecture. It included a single database and a bunch of app servers to handle online requests. 

Soon, the number of new features grew. To integrate the new features, the development team needed to deploy all their code at once, which impacted the app's speed and made each new deployment risky and time-consuming. Each new integration could bring the whole system down.  

uber backend monolythic  architecture

[A monolithic software architecture of the backend system, source]

Microservices

In 2014, the team faced the necessity of adopting new architecture for better operational performance. That is why they leveraged the microservice architecture. 

uber microservice architecture

[Microservice architecture diagram, source]

The microservice architecture includes a set of services targeted to one-another's functionality. All the applications are available over the network via the application interface (API). Microservices allows the deployment of new code independently, thus ensuring the ultimate system's scaling. But the team didn't stop there.

DOMA

With time, the development team applied the new approach to the system's architecture, called DOMA (Domain-Oriented System Architecture). How is DOMA different from microservices? Let's explain. 

Developers oriented their system design around collections of underlying services called domains. Next, they created collections of domains they called layers. Layers define what dependencies the microservices from different domains are allowed to take on. 

The development team calls such a hierarchy of microservice components a layered design. Then, developers made each domain independent from other domains using Gateway API. In this way, each domain has its own logic and isn't related to other domains inside of its codebase or data models.  

Uber gateway api

[The gateway abstracts away the internal details of the domains, source]

To support extension points within each domain, the team provided an extension architecture to each domain. DOMA transforms microservice architectures from something complicated to something comprehensible. In this way, developers received a structured set of flexible, reusable, and layered components. 

To write the initial system's architecture, developers used Python and SQLAlchemy as the ORM-layer to the database. After integrating a microservice architecture approach, the team integrated more than 100 services to the backend. 

However, developers integrated new features faster than they could announce them. For that reason, it is hard to answer the question, "What software does Uber use?" Don't be surprised if they've already changed the Uber system design to something more innovative to meet other needs. 

We just discovered how Uber works from the inside. Now, let's see what the app uses for the user interface. 

Which UI framework does Uber use?

As we said, the development team is continuously improving the app by adding new features. But every feature requires its own design. 

Unfortunately, checking designers' work against the design system takes time and designers must edit their screens to match the existing design system.  

To streamline the design team's workflow, the team created Base, a web React UI framework. 

Uber custom ux framework

[Base design framework, source]

Base includes pre-designed basic app’s elements: 

  • Typography 
  • Colors 
  • Grids 
  • Iconography
  • Buttons 
  • Lists 

Thanks to this framework, the team creates design faster and maintains high UI/UX standards and consistency. 

Now, let's see what technologies power Uber's web and mobile apps. 

What is the tech stack behind Uber?

To find out what language Uber's made from, let's start from the very beginning. In 2014, the team used Python, MySQL, and Mongo for the Uber backend, Node.js, and Redis for a dispatch system. Java and Objective-C powered mobile applications and Backbone.js for the website. 

To meet new business requirements, developers changed almost all of the platform's components: the marketplace and web and mobile applications. 

Marketplace Technologies Stack

The marketplace hosts data analytics and data streaming functionality. For its maintenance, Uber has a dedicated development team. It includes a data team, integrations team, front and backend engineers who build infrastructure and integrate new data solutions. The leading tech stacks for the marketplace are Python, Node, Go, and Java. 

Let's check out the tech stack of advanced marketplace functionality:

The trip execution engine works on Node.js. Its runtime environment gave developers the ability to manage numerous concurrent connections. Now, the company creates new services in Go because of its safety, efficiency, and concurrency. 

The frontline API routes requests from passenger and driver mobile devices to other services the platform uses. Developers wrote it on Node.js and used NGINX for the frontend, so the edge ensures authentication security with Secure Sockets Layer (SSL). To connect the frontline API with internal infrastructure components, developers leveraged the open-source module logtron for logging to disk, Kafka, and the Node.js client for statistics

Real-time connection. To ensure the highest availability demands for its online operations, developers used Ringpop, a library for building cooperative distributed systems. Thanks to this library, developers receive a highly-available, partition-tolerated connection with distributed databases like DynamoDB or Riak at the application level. 

The matching logic is written in Node.js and Go. Developers also used Ringpop and Sevnup for their function to hand off ownership of particular objects when a node in a hashing goes down or another node takes ownership of the keyspace. 

Dynamic pricing optimization uses Flask and uWSGI. But, with time, developers rewrote most Python with Go for higher performance. The team also moved from MySQL back end built with Python to Riak and Cassandra cluster that enable seamless and fast request throughput. 

Data streaming and machine learning work on Kafka, Hive, MapReduce, HDFS, Elasticsearch, the production databases, and file storage web services. The Ledger of Interactive Data Analysis Records runs JupyterHub for multi-user Jupyter (IPython) Notebooks, integrated with Apache Spark and a built-in-house data platform. 

Can you imagine? Not every company can afford to have its own ML platform. But how did Uber make it? 

In 2015, the team wanted to scale ML across the organization, avoiding ML anti-patterns while standardizing workflows and tools. Two years later, in 2017, they announced Michelangelo.

Michelangelo is an ML and AI platform covering the end-to-end ML workflow: manage data, train, evaluate, deploy models, make predictions, and monitor forecasts. 

Uber Michelangelo architecture

[Michelangelo flow for offline and online prediction services, source]

The platform includes components built in-house, as well as open-source systems, such as: 

  • HDFS
  • Spark
  • Samza 
  • Cassandra
  • MLLib 
  • XGBoost
  • TensorFlow

Now that you know about all the marketplace secrets, let's check out the technical stack used in web and mobile applications. 

Stack technologies of a web application

For the web-based transportation platform, developers used Node.js., an open-source, cross-platform, backend, JavaScript runtime environment. But in 2019, the company rebuilt its web application using Fusion.js, a modular Javascript framework for creating plugin-based React applications created in-house by the Uber team.

The client-side app is built with Browserify, an open-source JavaScript tool that allows developers to write Node.js-style modules that compile for browser use.

A base web server named Bedrock is built with Express.js, a popular backend web application framework. The server has a set of default middleware to provide security, internationalization, and other User-specific pieces that handle infrastructure integration. 

The build system, Core Tasks, has a standard set of scripts to compile and version frontend assets. Developers used Gulp.js, a stack technology that automates workflow by publishing to the file storage web service. 

Application rendering and state handling are supported by standard Flux application architecture for React.js apps. 

Mobile technology stack examples

There are four mobile applications: Android rider, Android driver, iOS rider, and iOS driver. For mobile apps, the team wasn't inventive. Developers built Android apps with Java and iOS apps with Objective-C and Swift. But there is a bunch of other technologies: 

Android app tech stack 

  • Gradle is a building system for Android apps
  • OkHttp, Retrofit, and Gson ensure networking 
  • Dagger is a dependency injection framework
  • Butter Knife powers views and callbacks to fields and methods via annotation processing
  • Picasso provides image loading.
  • Espresso ensures native automation code writing
  • RxJava allows asynchronous and event-based programming architecture that
  • Timber for logging

iOS app tech stack 

  • Buck powers a monorepo for storing iOS app code
  • Masonry and SnapKit with Auto Layout ensures the component building and scaling 
  • KSCrash, the internal reporting framework, detects and reports crashes
  • OCMock mocks and stubs classes for testing Objective-C code 

Let's sum everything up. 

What programming languages can I use to create an app like Uber?

To develop a project like Uber, apply technologies from this list: 

  • Python for a web-based booking app
  • Node.js for Marketplace web application 
  • Go for high performance, simplicity, and runtime speed
  • Java for integration with third-party services 
  • Browserify for the client-side bundling
  • ELk (Elasticsearch, Logstash, and Kibana) for storing logs, shipping, processing, and visualization 
  • Apache Hive data warehouse for data query and analytics 
  • Apache Cassandra for handling a large amount of data 
  • MySQL Database Service for relational database management 
  • Mesos/Docker for data centers infrastructure 
  • HAProxy for the load balancer and proxy server
  • MySQL, PostgreSQL, Schemaless, and Heatpipe (HP) Scheme, Kafka, Samza, Athen for data streaming and processing

And the list of technology stack examples doesn't end here. Unfortunately, copying technology behind Uber doesn't guarantee your cab-hailing service will have the same success. Let us explain why. 

The company applies a market-driven approach. Before adding one or another feature, the team analyzes user data first and makes data-driven decisions afterward. In plain words, Uber gives users what they want while searching for room for improvement. 

To build a successful cab-hailing service, do the same. Instead of collecting hi-end technologies, start small.  Use as few technologies and languages as possible. 

As your business grows, you might face the same challenges Uber did - the need for independent components deployment, user data analytics, and ML algorithms. Maybe even streaming the workflow of the UI design team. But, before this happens, you can use Uber stack only as an inspiration source on technologies to leverage in one or another case. 

We can create a personalized technology stack tailored to your business needs. To make that happen, tell us more about your idea, and we will get in touch with you soon. 

Need a tailored-made tech stack for your taxi app?

Receive a guaranteed consultation

 
Daria Dubrova

Tech Journalist