As DoorDash expanded and grew its product lines, we needed to find a better way to manage user data. In DoorDash’s Storefront offering, which provides merchants with a customizable online ordering solution along with the Dasher network for delivery fulfillment, we needed a better way to manage user data because customers could checkout as guests but had to endure the negative user experience when providing their payment and address information each time they checked out. The technical challenge was that we could not persist duplicate users, which would mean a customer with an existing DoorDash account wouldn’t be able to create a Storefront merchant account with the same information. To solve this user data management problem, we introduced the concept of multi-tenancy to our existing codebase and infrastructure which altered how we manage sensitive user data and improved our customer’s user experience.

The challenge with guest checkouts

Whenever customers ordered from one of our Storefront merchants, who have a customized online ordering UI but are powered by DoorDash’s backend infrastructure,  they would have to fill in their personal information (e.g. contact details, payment) each time. After ordering a few times, this process feels long and tedious. Even if customers were coming back to shop from the same exact store, they would have to enter their information again. Furthermore, the ordering experience lacked a degree of personalization, as customers weren’t shown reorder recommendations or other personal touches that might improve their ordering experience. 

This customer friction caused many customers, even loyal customers of the merchant, to leave during checkout, reducing reorder rates. Ultimately we wanted to enable storefront customers to create accounts with their go-to merchants so they would not have to re-enter their information repeatedly and would receive a more personalized experience. 

The data challenges inherent in persisting user data  

One of the most daunting challenges in solving this problem was that our existing user data tables didn’t allow duplicate users, which was enforced by a constraint dictating that no two users could have the same email. From the Storefront product perspective, we couldn’t support allowing users to create multiple accounts that were each tied to their favorite merchants because this would create duplicate accounts with the same email addresses and phone numbers. Additionally, Storefront accounts could be duplicates of existing DoorDash accounts. Given future goals of expanding internationally, we were also mindful to not violate GDPR requirements, which favor clear user data separation.

Where multi-tenancy comes in

Multi-tenancy is an architecture paradigm where one software application and its supporting infrastructure is designed to serve multiple customer segments, also called tenants. We addressed our data challenges by adopting the multi-tenancy model and introducing a separate database for each business vertical (e.g. Marketplace vs. Storefront vs. Drive). Each vertical can be considered an L0 tenant, representing a larger separation of data. Furthermore, multi-tenancy enforces logical separation within each database to allow for even more differentiation/labeling of data within the L0 tenant. This more granular division of data consists of what we call L1 tenants, which represent merchants in the Storefront case. Using this concept of multi-tenancy, we were able to incorporate this model of data separation into the existing DoorDash engineering ecosystem to unblock storefront’s business problem and enable future flexibility.

Figure 1: L0 tenants are based on different business verticals and L1 tenants are database divisions within verticals .

How we incorporated multi-tenancy into DoorDash’s codebase

To address Storefront’s business needs, we built a flow for user authentication allowing users to create one account per merchant and have their user data pre-filled when they visit the merchant’s stores again. Instead of relying on email addresses as the primary identifier, we used phone numbers with the goal of a password-less authentication process. Additionally, we handled Storefront user data in a similar fashion as DoorDash user data: 

  • preserve user control over their data
  • preserve data integrity with the appropriate constraints
  • prevent data intermingling among different verticals

To ensure that data was handled according to these requirements, multi-tenancy helped solve two problems for us: separating Storefront and existing DoorDash’s Marketplace/Caviar users and allowing duplicate phone numbers/emails across different Storefront merchants. Incorporating multi-tenancy into our system involved a few steps:

  1. With help from partner teams, we first created a new database for the Storefront vertical (L0 tenant) and added a new column to all user-related tables called tenant id (a string which contains both L0 and L1 tenant). This step introduces both the larger L0 level of separation and the more granular L1 division.
  2. Then, we added logic to route a user-related query to the correct database based on the L0 tenant (first part of the tenant id) passed in from the request header. To break it down a bit, we defined tenant id as a string formatted like the code sample below. In our case, this was represented as “<business vertical>:<entity/merchant id>”, This value allows us to derive the high-level vertical (L0 tenant) as well as a more granular differentiator (L1 tenant/subtenant) from a request.
 “<L0 tenant>:<L1 tenant>”
  1. In addition, we included this tenant id value in the headers of requests throughout the chain of services Storefront calls to power the vertical. 
  2. Finally, we changed the uniqueness constraint on the user table to be enforced on a (phone number/email, tenant id) pair instead of just phone number/email. This would allow a user to create multiple accounts with different merchants with the same phone number, but the database wouldn’t complain as the tenant ids are different for different merchants. Thus, a user can log into each of their favorite merchants with the same phone number, but the system would register each as a separate merchant account.
Figure 2: Our solution passes the tenant id is through different services until it reaches the user management service, including navigating the multi-tenant database.

Conclusion 

Supporting multiple accounts is a typical problem as businesses want to retain their customers and improve/personalize their experiences. Additionally, data separation and labelling is becoming more important given compliance requirements such as GDPR. This sensitive user data can get messy for companies with multiple product offerings. As product lines grow over time, coming up with new data storage and handling processes becomes a necessary bridge to cross.

The multi-tenancy solution detailed in this article is helpful for those who want a pragmatic, more feasible solution to supporting multiple accounts for users or improving their user management in general. It doesn’t involve any overly complex technologies or external integrations. Instead, it looks at what is already built in our existing services and builds on top of it in an extensible way. 

For most companies starting out, it’s probably a typical pattern to start off with one centralized database to manage user data. However, as the company grows, it might be necessary to figure out a better, more scalable way to manage the growing data. Multi-tenancy provides a practical solution for this problem, without having to uproot what’s already built. With multi-tenancy, business verticals can enforce both physical and logical separation in their codebase and supporting infrastructure, allowing both existing and new user data to abide by the same model of separation. After completing the initial integration, this model of user data management can be easily extended to new verticals, while maintaining consistency and data integrity across all verticals.

Acknowledgements

Thanks to all the individuals and teams who were involved in this ongoing effort to make multi-tenancy a reality! Special shout-out to Kritarth Upadhyay, Omendra Rathor, and Ivar Lazzaro for their hard work on this project to bring Storefront user accounts and multi-tenancy to life. 

If you are interested in solving these kinds of challenges, please consider joining the Storefront engineering team. We are actively hiring backend and frontend engineers in both San Francisco and Seattle. For questions on Storefront-specific roles, please reach out directly to our recruiter, Dolores, on Linkedin. If you are interested in working on other areas at DoorDash, check out our careers page.