In the US, Uber Eats gives fierce competition to other popular food delivery apps such as GrubHub and DoorDash, even as the ranking of the top three food ordering apps fluctuates between these three.
In this blog, we will understand how Uber Eats works, have an idea about its system design and architecture, find out how its fulfillment process works, and decode its amazing speed of execution by getting a sneak peek into its image storage and optimization model.
But first, let’s find out some amazing statistics about this fascinating food delivery app and its history in brief.
Uber Eats: The Food Delivery App Everyone Loves
After launching Uber in 2009, founders Garrett Camp and Travis Kalanick decided to launch UberFRESH as an experiential food delivery app in Santa Monica, California, based on the original Uber app.
Since the riders were anyways traveling from one destination to another, Uber founders decided to provide them with food delivery orders as well, and there was no separate app for this service initially.
Buoyed by the response, they renamed this app to Uber Eats in 2015 and launched a separate app, dedicated to food delivery service.
With more than 80 million active users, Uber Eats is present across 6 continents, 45 countries, and 6000+ cities. In 2021, it reported revenues of $8.1 billion, which is expected to break the $10 billion revenue threshold in 2022. More than 90,000 restaurants have partnered with this platform.
An interesting fact: although Uber, the parent company, is valued at more than $120 billion, Uber Eats is valued at a much lower scale of $20-30 billion.
But in 2021, the overall revenue generated by Uber Eats was higher than Uber!
How Uber Eats Works: The Business Model
Uber Eats is basically a platform that has three aspects:
Customers can select restaurants, and order their food which is delivered by the riders.
It has the following components:
- Mobile app for customers (Android and iOS)
- Mobile for riders (Android and iOS)
- Admin panel for restaurants to accept and track orders
Some basic requirements of the Uber Eats platform (from the customers’ perspective)
- Users can search for a restaurant
- Users can search for food items within the restaurants
- Users can select the food items, order them and make the payment
- Once ordered, users can track their delivery
System Design Of A Food Delivery App
Basic requirements of the Uber Eats platform (from the restaurant’s perspective)
- Restaurants can list themselves
- They can upload their menu, pricing, and the rules
- Via a dedicated app, restaurants can accept or reject orders
- Once accepted, the restaurants can update the status of the order
- They can receive the payments from the customers, after deducting the commission
Basic requirements of Uber Eats riders
- View the order, accept the ride
- Check the address of the restaurant, and of the customer
- Pick up the order from the restaurant, follow the map, and deliver to the customer
- Get their incentives and commissions based on the case to case basis
Besides these basic requirements, there are other inherent processes and activities involved for the customers, restaurants, and riders such as:
- Customers can view all their orders
- Customers can edit, or cancel their orders
- Riders can view all the orders delivered
- Restaurants can search orders via Order ID
- Customers can add, edit or delete their addresses
- Restaurants can add or remove special offers and discounts
- Customers can view all discounts and offers
Understanding the Fulfillment Platform Of Uber Eats
Fulfillment is the soul of Uber’s system design and architecture. Fulfillment is defined as “act or process of delivering a product or service to a customer.”
Initially, the tech team behind this application adopted the fulfillment model of Uber’s cab-hailing services, which depended on two factors: trip and supply.
As seen in this model, the rt-demand service was managed by the Trip entity, whereas the rt-supply service was managed by the Supply entity.
In this model, a Trip represented a unit of work, whereas the Supply entity represented a real-world person who is capable of doing the unit of work.
This model faced problems such as consistency (for instance failed order delivery), multi-entity writes & scalability.
At the same time, the languages and platforms became outdated (Node.js and the HTTP/JSON framework were removed from Uber’s core tech stack in 2018), data incoherence, and unclear extensibility patterns.
In order to remove these obstacles, their technical deployed a new fulfillment platform, which basically transitioned the app from NoSQL to NewSQL.
- Uber Eats is now leveraging Apache Helix and Apache Zookeeper for centralized shard management, instead of Ringpop, which used decentralized peer-to-peer shard management.
- Deploying Serial Queue, which ensures that only one transaction is executed at one time, instead of multiple transactions.
- Usage of Saga-based pattern for multi-entity cross-shard transactions
Uber Eats developed an in-house team for deploying and managing MySQL storage, wherein the NewSQL database is being leveraged for transactional primitives.
The programming model of the Uber Eats fulfillment process involves three parts:
- Statecharts for modeling entire fulfillment entities (ensuring consistent and modular behavior modeling)
- For handling writes across multiple entities, leveraging Business Transaction Coordinator
- ORM layer for database abstractions, along with simplicity and corrections
After deploying this new fulfillment model for processing deliveries, they were able to handle multiple queries seamlessly, ensure zero errors during exceptional handling (orders getting canceled), and 3swiftly and allocation of deliveries to the riders.
You can find more information about the new fulfillment model here.
Image Storage & Optimization Process
Uber Eats stores a hundred million+ images, and processes millions of updates, and modifications of images, every hour.
This caused their servers to slow down, and consume more resources which impacted their delivery process and more importantly, their ROI.
To overcome this problem, system architects and engineers deployed a content-addressable caching layer, which seamlessly removes duplicate images, and thus:
- Reduces download times
- Reduces processing time
- Reduces storage costs
How did Uber Eats accomplish this?
First, let’s understand how they process the images:
- The system determines if the URL and the image are already known
- If not, it will download the image and check if it’s valid
- Once validated, the image is re-formated and scaled to the standard size
- The final processed image is stored in the database
Deduping Images For Optimized Performance
Uber Eats created a powerful image handler, that introduced the process of deduping images to ensure that one image is only saved once in the database.
For this, the engineers created this flow:
There are three main flows in this image optimization process:
Known, Processed Image:
This flow (yellow boxes) returns only those images which are known and processed.
New, Unprocessed Image:
This flow returns those images which are downloaded and processed
Known image but not processed:
This flow goes through those images which are known, but not processed before with the requested specifications.
By deploying this image handler process flow, UberEats has been able to process millions of images without impacting their servers, and delivery process, since less than 1% of the calls need to be processed.
More information about image optimization processes can be found here.
If you wish to develop and launch a food delivery app like Uber Eats and grab a bigger market share while delighting your users with world-class features, our mobile app engineers at Zazz can help you.
Founded in 2009, we are a powerful team of 275+ mobile app designers, developers, programmers, and solution architects, who are passionate about your success.
Schedule a no-obligation consultancy session with us right here.