Multi-Channel Multi-Location Menu Management
How CloudKitchens enables seamless management of menus across multiple channels and locations
Introduction
In the modern age, orders are placed from multiple channels – delivery apps, online ordering storefronts, in-store, and more – so having a best-in-class digital menu is equally as critical as a restaurant’s physical storefront. We build technology that allows restaurants to easily create and manage their menus in both the physical and digital space, enabling them to succeed across all channels.
Menus are easy
The concept of a menu is simple. It is a catalog of food the restaurant can make and its associated prices.
…But menus aren’t so easy
There’s more to a menu than meets the eye. Let’s look at a basic digital menu designed to mirror a restaurant’s physical menu.
Much like their physical counterparts, menus are expected to have some structure.
Generally, this means menus have different categories of items they can sell. “Entrees”, “Sides”, and “Drinks”, with items organized under those categories. Some restaurants may offer add-ons on specific items, like adding a side of fries to a burger. Some of these add-ons may even have their own add-ons, such as adding melted cheese to the side of fries. Some restaurants may even have different menus they sell depending on the time of day – a lunch menu and a dinner menu, for example.
How CloudKitchens helps restaurants create user-friendly menus across channels
When we learned that menus aren’t easy, we began building solutions to make setting up and managing menus across multiple channels a better experience for the restaurateur. Since a good menu requires categories, add-ons, add-ons to the add-ons, and perhaps even a different menu depending on the time of day, we developed a primary set of four entity types that we store in a tree-like structure to model these menus: Menus, categories, items, and modifier groups.
Separating these entities allows us to store specific information for them. For example, items will often have photos and prices. Menus will have the hours they are sold. Modifier groups may restrict the number of underlying modifier items that may be selected.
In our model, we allow entities to be re-used without creating duplicates. This lets us reduce the workload for restaurateurs managing a menu. Information about an entity must only be updated once and will appear everywhere the entity is referenced.
The CloudKitchens digital menu solution in action
Let’s look at an example. Say we’re making a menu for a fast-food burger chain: Burger Prince. Many items can add sauces (burgers, fries, onion rings, etc), but they are all the same. Rather than specifying every possible sauce for every item, we can create a single modifier group titled “Add a sauce” with all the sauces underneath and reference the same modifier group several times. If we would like to introduce a new sauce, we can just add it once to the “Add a sauce” modifier group, and it will be available on every item with the modifier group attached.
While this helps in most cases, it also adds some complexity if entities should have different properties depending on where they appear on a menu. This is most common when it comes to pricing.
Let’s look at another example from our existing burger restaurant, Burger Prince. “French Fries” can be ordered as a stand-alone item on the menu or as an added-on for a burger combo meal. When ordered as a stand-alone item, French Fries should cost $2, but when ordered as part of a combo, they go down to $1.
To support this, we built menu-path-based pricing for the “French Fries” item, so we can set different prices depending on whether it’s ordered as part of the modifier group for a burger combo or from the category of the menu.
Menus are hard
Now that we’ve examined how we model menus internally let’s add another layer of complexity.
Adapting menus across different channels
While we offer an online, direct-to-consumer storefront, the menus created by our technology will likely also appear on external delivery channels (e.g., Uber Eats, Doordash, Grubhub) so the restaurant can take orders through those channels.
Because every delivery channel models their menus differently and has different information they store per entity, we must be able to adapt our internal menu to theirs and vice versa. This requires our menu model to be the superset of all information available on these different channels while still not overcomplicating things for restaurateurs.
Each delivery channel may support different features compared to our internal menu. For example, some channels may not support nested modifiers (add-ons to add-ons), meaning we’ll have to copy and automatically unnest modifiers when we convert our menu data to the external service's format. Some channels may not support the same item appearing in a category and as an add-on to another item. For those cases, we have to split the item into two copies on the external menu, which link back to the same item on our internal menu.
We have a complex integration suite for adapting internal menus to external menus, which we’ll discuss in detail in a future post.
Managing menus across different channels
Since delivery channels often charge restaurants a commission on every order, a restaurateur may decide to alter their menu pricing depending on the ordering channel. This means we must now model differences in prices across delivery channels and prices based on where an item appears on a menu (e.g., a standalone order of fries or fries added onto a combo).
One of the core features we offer customers is inventory management – the ability to mark items as out of stock when they are sold out or mark items as back in stock when they do have inventory. This allows restaurants to quickly toggle which items are being sold without logging in to each channel and editing every menu during day-to-day operations.
For this feature to be effective, once a user marks an item as available or unavailable on our internal menu, we must quickly and accurately propagate this information to all connected delivery channels. Hence, they mark the equivalent items on their channels. We do this by storing links between our internal entities and every external entity at a published channel so our system can propagate the availability update for the correct item.
We have a complex integration suite to adapt internal menus to external menus, which is a deep rabbit hole, so we’ll save those details for a future post.
Menus at scale are really hard
But let’s take it a step even further. Many of our customers aren’t just operating on multiple channels but also at multiple locations. Menus are usually the same across these locations, so we do not need to manage a copy of every menu.
Let’s say Burger Prince had 50 locations. If we wanted to start selling a new seasonal item at each location, we’d have to go to every single location’s menu and make the same change 50 times. That would be a lot of work!
Meet template menus
To alleviate the issue above, we created template menus. Template menus are meant to model a digital menu that can be used at multiple locations, so restaurants managing a menu sold at multiple locations can make all their changes once on a single template menu.
While locations sharing a template menu are more likely than not to share information, many aspects of the menu can be customized per location. This means that sources of complexity, like per-channel pricing, are potentially multiplied by the number of locations using a template menu.
Menu differences across multiple locations
By default, a single price may be set for an item on a template menu, and that same price will propagate to all locations. However, menu items are often priced differently for different locations, so we have to manage price per location, price per delivery channel, and price based on where the item appears.
A restaurateur managing a template menu may want to mark an item as unavailable across all locations. Also, it’s common for a restaurant to run out of stock of an item for the day at just a few locations, so the item should only be marked unavailable at a subset of locations.
This means we must store a link from each item on the template menu to every item across all delivery channels for each location so we can manage its availability at any number of locations with a single button click.
Menus can also be generally different per location. Some items or categories may be sold at some locations and not others. For example, global fast-food franchises usually sell a few specialty items based on the region in which the restaurant is operating.
Menus are still just one part of the larger picture
We’ve explored some of the complexities menus may present, but we must remember that menus are only one part of the restaurant ecosystem.
In addition to creating an easy-to-use menu management experience, our menu system must integrate with many other systems, such as online order management, POS (point of sale), KDS (kitchen display systems), printers, business intelligence reporting, analytics, promotions, and inventory/supply chain.
Here’s an example of a simplified order interaction involving all these pieces:
At a high level, when an order comes in from a third-party channel like DoorDash, Uber Eats, or Grubhub, our system must be able to properly match the items in the order to items on the internal menu. These orders must then be converted to a kitchen-readable format and sent to the KDS (kitchen display systems) or printers for chefs to prepare. At the same time, if the storefront has a physical point-of-sale device for taking orders, we must also inject any online orders into their point-of-sale device so they can manage their entire restaurant from one channel. On top of that, other integrated apps like business intelligence or inventory management must also be able to understand what items are being ordered and consumed so we can properly decrease inventory count for our users.
Each of these interactions is very complex, so stay tuned for the next few posts, where we’ll explore the details of some of these challenges.