Mental models as a startup engineer

STARTUP ENGINEER SERIES: Mental models for decision-making - This is a series covering problems I've worked on. I discuss how I use mental models to improve my decision-making and solve them iteratively.

Context

WaystoCap is a local B2B managed marketplace. An aggregator that provides delivery to the end-user which are usually family owned shops.

WaystoCap is a very good example of a company that does things that don't scale until we need to automate it.

In this particular story, we will discuss order fulfilment from an operational point of view.

Every day, operations team members manually divided orders between delivery agents. Then, copy pasted the coordinates of each of the orders into an online tool that would return the list of coordinates in the best route. After that, they would manually pair these coordinates back to the order of each, print out each of the orders and assign the ordering on the printout. Then give the printed orders to the delivery agents.

There were also other related problems that we won't get into in this series, most critically, improving the warehouse operations to prepare all the orders for pickup.

The routing process alone became too much once we hit 100 orders per day, it was taking staff at least 2 hours every day to prepare the routing for the next day.

The problem

From a business point of view, the issue was this order routing process was taking at least 2 hours every day of operational team time. We were growing quickly and it was already not feasible to keep doing this manually. We had to find a solution to this problem and fast.

In computer science, our routing scenario could be split into 2 separate problems.

  1. Constrained Vehicle Routing Problem (VRP): dividing orders between delivery agents
  2. Travelling Salesman Problem (TSP): optimizing the route of each delivery agent

Problem constraints:

  • list of agents
  • each delivery agent had a different hourly pay (our agents were contractors with variable costs)
  • each agent has a specific vehicle
  • each vehicle has specific volume and weight constraints
  • each vehicle has a unique cost of gas
  • list of orders with geo-locations
  • each order has a list of different products
  • each product has a different weight and volume

To achieve an MVP solution quickly, we boiled these constraints down to the constraints that were already being solved by our manual process.

MVP Problem constraints:

  • list of agents
  • list of orders with geo-locations

Researching Solutions

When finding solutions to a problem, one of the first mental models to think about is availability bias. In other words, people think about the solutions given the options they know about (and can think of in the moment).

To mitigate this (as much as possible) you need to first research the available solutions. This is a critical step as an open-source project or affordable SAAS product could save you considerable amount of man hours and money over the long term.

The better you understand the problem and the constraints of the problem, the better you will be able to research for the available solutions.

Be aware of the law of diminishing returns and mental fatigue when researching. i.e. Find a balance, don't under do it and don't overdo it.

Open source options (with notes):

  1. Node-Kmeans - simple K means clustering with no constraints.
  2. Min Cluster Constraint in Python - Use it or convert to JS (I could set relative lower bound based orders/drivers)
  3. jsprit in Java (engine used in GraphHopper)
  4. GraphHopper Engine
  5. OSMR Engine
  6. Implement this paper in Nodejs
  7. MinMax K Means in Python

Paid options:

  1. GraphHopper ($128 for our monthly order count, max 80 locations per visit)
  2. Routific (Full Fleet solution with Driver app and Management Dashboard)
  3. Routific API (min. $600 for our monthly order count)
  4. OpenRouteService (FREE Only: max 50 orders x 3 vehicles)
  5. Other options omitted for brevity...

Deciding on a Solution Roadmap

One of the most important mental models I use when coming up with solutions and product roadmaps is the Pareto principle ( the 80/20 rule ). This mental model is so powerful and a hidden property is that it's recursive! You can see it at work here with one of Pablo Picasso's most famous drawings.

The way I think about problems is starting left to right. The way I think about solutions is from right to left.

Initially, we wanted to go purely with GraphHopper as it was the best value/price trade-off for our needs, requiring very little development effort. Unfortunately, the 80 location limit stopped us from being able to use it (remember we were at +100 orders per day). Their highest tier was out of our budget and it maxed out at 150 locations per request anyways so it wouldn't work for our VRP problem as it would break down over 150 orders.

After evaluating all of these options we decided for our MVP to use node-kmeans library to solve the VRP problem and GraphHopper to solve our TSP ( optimized route for delivery agents ).

MVP results

We were able to develop this solution and start using it in production in 2 days.

A task that took over 2 hours per day was now being done in 2 button clicks!

The automated algorithm wasn't perfect, so we added the ability to manually update the delivery agent of an order. This way the bulk of the work was being done by the algorithm, and one of our operations team members was tweaking the routes to perfection. Again, the Pareto principle at play here - the algorithm handled 80% of the work and the last 20% of the work was being done by our team member.

After delivering our MVP, we collected feedback, validated assumptions and started figuring out our next iteration.

Post-MVP Prioritizing:

Remaining Problem constraints:

  • each delivery agent had a different hourly pay (our agents were contractors with variable costs)
  • each agent has a specific vehicle
  • each vehicle has specific volume and weight constraints
  • each vehicle has a unique cost of gas
  • each order has a list of different products
  • each product has a different weight and volume

New problems:

  • assignment was done using straight-line distances between coordinates, rather than real road based distances
  • dividing orders equally between vehicles was giving non-optimal results
  • we assumed our customers would want to see the same delivery agents to build better rapport since they were often using us at least weekly for restocking, we wanted to keep the same delivery agents to deliver in the same zones

We decided the next biggest problems in order of priority:

  1. Dividing orders equally between vehicles was giving non-optimal results
  2. Optimizing order routing based on volume and weight constraints of each vehicle
  3. Building our own solution that could handle hundreds of orders and a dozen of drivers in a single call
  4. Assignment using real road based distances

In our case solving 2 would solve 1, and solving 3 required solving 4.

Preserving Optionality

When working on problems in a startup, situations and priorities change all the time. It's important to keep optionality in product roadmaps and in technical implementations. If you are not mindful of this you can create path dependence, making it difficult to shift priorities due to high switching costs, organizational process debt and technical debt.

In this case, the next most important problem was maximizing the use of each driver based on the volume and weight constraints.

Our products at the time did not have the volume and weight on every product. We needed to have one of our data entry employees fill out this information for each product.

We quickly built an optimized spreadsheet that allowed them to add these values quickly, showing only the products that were missing values. This was built within 1-2 hours using Retool and some small GraphQL changes.

We couldn't move forward with the volume and weight based constraint solution until our data entry team filled these out. The development team was blocked from solving priorities 1 & 2 until this was complete. By providing an optimized Retool, we set our data team up for success while we focused on priorities 3 & 4.

What we achieved: This allowed us to continue our prioritized roadmap, optimize the efficiency of the data entry team and work in parallel with the data entry team. It also allowed us to preserve the optionality of the roadmap! We would continue working on other priorities and we could shift focus in a moment's notice once all these values were filled out.

Conclusion

Mental models are a toolbelt for decision making. They help you make better decisions by mitigating your own cognitive biases that hold you back. Working in a startup you are faced with tremendous amounts of uncertainty, and no roadmap is perfect. Every day there are many decisions to be made, it's better to be roughly right than precisely wrong! Add mental models to your set of tools to help you make better decisions for your company and your life.

Thanks for reading :) If you have any questions please feel free to reach out!