Order Routing: From Fixed Logic to Programmable Rules

When a customer places an order, Shopify must decide which inventory location fulfills it. For single-location merchants that decision is trivial. For multi-location sellers—those with physical stores, several warehouses, or international distribution—the platform must weigh inventory availability, shipping costs, buyer proximity, and whether items can ship together from one place.

Historically, Shopify’s order routing was rigid. Merchants could only set a prioritized list of locations, and the default algorithm would try to ship all items from a single location whenever possible, using that list to break ties. With the Winter ’23 Edition, Shopify introduced smart order routing to replace that one-size-fits-all approach. The new system lets merchants define “routing rules”—customizable functions that rank eligible locations according to specific criteria—and chain them together in whatever order suits their business.

Routing Rules as Shopify Functions

A routing rule is a function that ranks all possible fulfillment locations for a given order. Given a parameter like buyer proximity, the rule orders locations from best to worst. Merchants can combine multiple rules sequentially, so the highest-priority rule is applied first, with subsequent rules used to decide among locations that tie.

Shopify formalized several common routing questions into three default rules, each built as a separate function written in Rust:

  • Ship from closest location — ranks by distance to the destination address.
  • Stay within the destination market — prefers locations in the buyer’s country.
  • Ranked locations — prioritizes individual locations or groups in a merchant-defined order, such as shipping from warehouses before retail stores. This rule is powered by a single function that handles both the individual and grouped cases.

Each routing rule is a Shopify Function composed of three parts: a GraphQL query that defines the input (for example, available inventory locations), the logic written in Rust, and the output—a ranked set of locations. The best match for a rule receives rank 0, the next best rank 1, and so on. That output conforms to a defined GraphQL payload.

Shopify deliberately built these default rules using its own Shopify Functions infrastructure, dogfooding the same extensibility mechanism that third-party developers will use to write custom rules.

Routing rules in Order Routing settings page in Admin
Routing rules in Order Routing settings page in Admin

The Reducer: Breaking Ties Between Rules

When a merchant selects multiple routing rules, each runs independently and produces its own location ranking. The rules execute in the order the merchant configured them in the admin UI. The final decision is left to the reducer, which processes each rule’s results in sequence.

If the first rule yields a single location ranked 0, the reducer returns that location immediately. If two or more locations tie at rank 0, the reducer advances to the next rule and uses its rankings to break the tie, choosing the location with the lower rank number. The process repeats across subsequent rules until a single best location emerges.

A diagram showing the Reducer breaking a tie between routing rules.
The reducer breaking a tie between two rules.

Rebuilding the Algorithm with the Pipeline Pattern

The new order routing algorithm replaced what Shopify describes as a “tightly coupled process” with nested loops and multiple iterations. That structure made debugging difficult: developers without domain context had to spend considerable time understanding the code before addressing reported errors.

The rebuild splits routing into discrete pipeline steps, where each step performs one overarching action and its output feeds the next stage. The initial pipeline input remains available to all steps throughout. The rebranded flow prepares the order routing input, runs the selected rules, reduces their results, and finally produces the optimal location. That flattening gives developers a clean separation of concerns and makes the code easier to read and debug.

What Comes Next

Smart order routing’s first stage combines three elements: routing rules for flexibility, Shopify Functions for extensibility, and the pipeline pattern for maintainable code. The next stage aims to open up order routing further, letting developers build additional—and potentially more complex—rules for merchants to adopt.