# No order left behind; no shopper left idle.

This post is about how we use Monte Carlo simulations to balance supply and demand in a rapidly growing, high-variance marketplace.

**By Jagannath Putrevu, Instacart.**

At Instacart, our goal is to make grocery delivery accessible to everyone. In the last 9 months, we grew tremendously from a handful of established markets to over 100+ markets in the US. Such rapid expansion brings a lot of growth potential but also adds more unpredictability to our demand. Offering every customer same day delivery, while keeping our shoppers busy becomes a very hard problem.

This post is about how we use Monte Carlo simulations to balance supply and demand in a rapidly growing, high-variance marketplace.

Instacart’s service locations progression from Jan 2017 to Sep 2017

### Supply-Demand Equilibrium

Balancing supply and demand is extremely important for any company that is in the business of taking orders and fulfilling them. If demand exceeds supply, we have a system that decides to stop taking orders and that hinders us from honoring our promise of same day delivery. We define the percentage of demand that was lost on a given day as **Lost Deliveries**.

If we have more supply than demand, our shoppers, the couriers who pick/deliver groceries, are left idle and that hurts their earning potential because they complete fewer orders per hour. Our shoppers like being busy and making good use of their time on our platform.

Supply < Demand: Lost Deliveries, Supply > Demand: Idleness

If we had the same demand every day, we would staff exactly the same number of shoppers every day. But there are several factors contributing to unpredictability in our demand and supply, especially in our new markets, and that makes staffing a very hard problem.

How do we staff the right number of shoppers in each market on each day for each hour, to make sure we do not lose too many deliveries and also not keep our shoppers idle? What makes this problem so hard? Where is the variance coming from? We will answer all of these questions, but first let’s define the problem we are trying to solve more formally.

**Problem Statement**

For a given market and a given day, how do we staff:

- number of shoppers at every hour

so as to:

- minimize shopper idleness
- minimize lost deliveries

The final output of this problem looks something like this:

We call these numbers

**Staffing Levels**.

### What makes this problem so hard?

**Variances**

We have to deal with the standard supply and demand variations, which only intensify during rush hours, hurricanes, snowstorms, Game of Thrones season finales and long weekends. Shopper productivity isn’t uniform either. Some can zip through an order at an item a minute, while some, especially new shoppers, take their time as they get used to the platform and ramp up. Shoppers also have the flexibility to cancel their shifts as needed, which adds even more unpredictability to our supply.

Every component below has variance and impacts staffing decisions:

**Constraints**

There are several constraints that make the problem even more complicated. Our demand can be fulfilled from different store locations in each city. Stores are open for different hours. Our picking and delivery times can vary based on how busy the stores and streets are. There are constraints on how long a shopper can work with us if they are a part-time employee. We work with 160+ retailers, and often times we have to adhere to retailer specific rules.

**Unification of objectives**

We must also quantify the costs associated with idleness and lost deliveries, and unify them into a single function to make better staffing decisions. Idleness leads to increased labor costs while lost deliveries lead to losses in revenue. Lost deliveries can also have a long term cost if we lose a potential repeat customer.

**Heuristics based methods for staffing**

In the beginning, we solved this problem using a mixture of forecasting and heuristics based methods. The core idea behind these approaches was based on adaptive course correction:

- forecast using previous weeks’ staffing numbers
- correct for next week based on previous week’s idleness and lost deliveries
- adjust for next week’s demand forecast changes

But with these approaches, we would often lose too many deliveries or keep too many of our shoppers idle. The dependencies on prior week’s outcomes can result in a potentially vicious feedback loop by settling at a local optimum. For example, it might be more optimal to put more shoppers in a store location with more order density around it, than at a store that is not as centrally located. Nuances like that are really hard to capture with these approaches.

To deal with all this complexity and uncertainty, we decided to try Monte Carlo Simulations.