π― What this feature does
SKULabs automatically assigns each order line item to the closest warehouse with stock based on the customer's shipping ZIP. It works across every sales channel (Shopify, Amazon, eBay, Walmart, BigCommerce, WooCommerce, etc.) and manual orders. Pickers only see the items routed to their warehouse, so the picking workflow stays clean and per-warehouse β even when a single order ends up split across multiple locations.
Why it matters
Faster delivery β items leave from the warehouse closest to the buyer.
Lower shipping cost β shorter zones, less weight-distance overhead.
Cleaner picking β each warehouse only sees the items it owns on the order.
Channel-agnostic β same logic on Shopify, Amazon, eBay, Walmart, and manual orders.
Safe by default β if routing can't decide, the order still imports and is flagged for review. Nothing is blocked.
How it works
The routing calculation
When an order comes in, the system:
Reads the customer's ZIP from the shipping address (handles
zip,postal_code,postalCode, and strips ZIP+4 suffixes like10001-1234down to10001).Looks up coordinates for that ZIP from a built-in database of ~42,500 US ZIP codes.
Measures the great-circle distance from the customer to every warehouse that has coordinates configured.
Ranks warehouses from closest to farthest.
For each line item, assigns the closest warehouse with enough stock. If no warehouse has stock, the closest eligible warehouse is assigned anyway so the item still has a home.
Each item on the order can be routed to a different warehouse. Example: a Denver customer orders A and B. Item A is only in stock at LA, item B is only in stock at Chicago β Item A goes to LA, Item B goes to Chicago, all on one order.
Dropshipped items (Amazon FBA, Walmart WFS, or anything channel-marked as dropshipped) are skipped β they're fulfilled externally and never get a warehouse assignment from geo-routing.
Split fulfillment by quantity
When no single warehouse has enough stock to cover the full quantity, geo-routing splits the item across multiple warehouses:
Walk warehouses from closest to farthest.
Take
min(remaining qty, free stock)from each, until the order qty is satisfied.If stock runs short, the remaining quantity stacks onto the closest warehouse.
Each split allocation becomes a separate line on the order so the warehouses can pick independently.
The ZIP data foundation
Coordinates come from two trusted, publicly available sources, refreshed automatically:
Source | Records | Role | License |
HUD population-weighted centroids | ~29,300 | Primary β coordinates represent where people actually live within each ZIP | US Government (free) |
GeoNames | ~13,200 supplemental | Fills gaps β PO Box ZIPs, military ZIPs, unusual codes HUD doesn't cover | Creative Commons 4.0 |
The database refreshes automatically on the 1st of every month at 3:00 AM UTC. Warehouse coordinates are set automatically when you save a warehouse address
How to enable & configure
Geo-routing is configured per store from a dedicated settings page. There's no single account-wide checkbox β each connected store decides whether routing runs for its orders and which warehouses are eligible.
The dedicated page β Settings β Inventory β Geo Route
The Geo Route page lists every active store with its current routing status (green check / red ban), the warehouse summary, and a pencil icon to edit. A question-mark icon in the header opens a help box that explains priority warehouse, Disable Split Geo Routing, and the rule actions.
Editing a store
Click the pencil on a store row to open the Geo Route Settings modal. From the modal:
Pick eligible warehouses. Every list always shows all the account's warehouses β orders from this store can be geo-routed to any of them. The layout depends on whether the channel exposes multiple fulfillment locations:
Multi-location stores (Shopify, Amazon, Square, etc.) β the warehouse list is grouped by channel location. Each channel location has its own draggable list. This lets you express, for example, "for Shopify-NY use WH-East first, then WH-West; for Shopify-LA use WH-West first, then WH-East".
Single-location stores (eBay, etc.) β the warehouse list is flat (one ordered list, no grouping) because there's only one channel location to configure. The list still contains every warehouse, and orders can route to any of them based on geographic proximity.
Drag rows to set priority order. The first warehouse in each list is the priority warehouse for that location. The remaining warehouses act as the routing chain β closer wins among them when priority can't fulfill.
Toggle the three switches:
Enable geo-routing for this store β turns the whole engine on for this store.
Enable priority warehouse β when on, the priority warehouse wins over closest-with-stock if it can cover the full qty. When off, drag handles dim to ~35% opacity and reordering is disabled.
Disable Split Geo Routing β when on, geo-routing assigns the entire order to a single warehouse. See the "Single-warehouse mode" section below.
Save. The store row updates immediately with the new status and warehouse summary.
Single-warehouse mode (Disable Split Geo Routing)
When Disable Split Geo Routing is on for a store:
Geo-routing finds the closest single warehouse that can fulfill every item in the order β that's the success path. Reason code:
closest_with_full_stock_no_split(orpriority_warehouse_no_splitif priority covered it).If no single warehouse can fulfill the entire order, routing falls back to the closest warehouse that can fulfill the most items and tags the order Failed Geo-Routing with a log entry explaining the partial-fulfillment fallback. Reason code:
disable_split_partial_fallback.This is the right mode when an account cannot tolerate split shipments and prefers a known failure mode they can react to.
What happens when you turn geo-routing on (for a store)
New orders syncing from that store route automatically.
Manually created orders for that store route the moment they're saved.
All existing open (unstarted) orders for that store are routed in the background.
What happens when you turn it off (for a store)
Geo-routing assignments are cleared from open orders for that store.
Items you manually assigned to a warehouse are preserved β only auto-routed assignments are wiped.
The picking UI keeps grouping by warehouse whenever items have a warehouse assignment.
Users can still manually reassign warehouses from the picking interface.
Before you enable, make sure
At least two warehouses are configured (one-warehouse setups gain nothing).
Each warehouse has a valid US ZIP in its address.
Inventory is tracked at each warehouse so stock levels are accurate.
For multi-location channels, channel locations have synced into SKULabs so the modal can group warehouses by location.
Channel orders vs. manual orders
Channel orders (Shopify, Amazon, eBay, Walmart, etc.)
Geo-routing runs as part of the sync pipeline. After each order is saved, items receive a warehouse assignment and a reason code. Fully automatic β no user action.
Manual orders
The order is saved first, then geo-routing runs on that single order. The warehouse assignment appears immediately. If routing fails (e.g., no ZIP), the order is still created and just flagged for review.
Manual warehouse override (always available)
Whether geo-routing is on or off, users with the reassign permission can change a warehouse from the picking interface:
Reassign an entire warehouse section to a different warehouse (section-level dropdown).
Reassign an individual item to a different warehouse (per-item dropdown).
Reassign a partial quantity β the system splits the line, creating a new line for the moved quantity.
Manual reassignments are tagged manual and preserved on subsequent re-routes unless someone forces a re-route.
Manual re-route
For unstarted orders, users can ask the system to recalculate routing. Three entry points:
Single order β order page menu β "Re-route order". Preserves manual warehouse overrides on individual lines. Works on both Channel orders and Manual orders.
Bulk re-route β Orders β Processing β select orders β "Bulk re-route orders". Always uses force mode β manual overrides are cleared. The bulk trigger is hidden entirely for accounts that have no stores with geo-routing enabled. Works on both Channel orders and Manual orders.
Waiting for the next channel sync β works for Channel orders only. Each sync cycle re-applies geo-routing to that channel's open orders. Manual orders do not get this auto-retry β there's no sync cycle for a Manual store, so a Manual order that needs re-routing after a fix has to be re-routed via the single or bulk action above (or by editing the Manual store's Geo Route config, which auto-re-routes all of its open orders in the background).
If an order has moved past unstarted status, both re-route paths refuse with "Only unstarted orders can be re-routed."
When does geo-routing run? β quick reference
Trigger | Channel orders | Manual orders |
Order created / synced in | β runs once | β runs once |
Next channel sync | β re-runs each cycle | β (no sync cycle exists) |
Store's Geo Route config changes | β re-routes all open orders for that store | β re-routes all open orders for that store |
User clicks "Re-route order" (single) | β preserves manual overrides | β preserves manual overrides |
User clicks "Bulk re-route orders" | β always forces (clears manual overrides) | β always forces (clears manual overrides) |
Stock levels change | β no auto-retry | β no auto-retry |
Ship-to address edited on the order | β no auto-retry (use Re-route order) | β no auto-retry (use Re-route order) |
Multi-location channels (Shopify, Square, etc.)
When a channel supports multiple fulfillment locations, warehouse links decide which SKULabs warehouses are eligible:
Each channel location maps to one or more SKULabs warehouses.
When an order item carries a channel location ID, routing is restricted to the warehouses linked to that location.
If a location has no linked warehouses, routing falls back to the store's warehouse list, then to all warehouses with coordinates.
When warehouse links change, all open orders for that store are automatically re-routed in the background.
Priority warehouse (per store)
Each store can prefer a specific warehouse even when it isn't the closest. Set it from the Geo Route page β the first warehouse in the list under each location (multi-location stores) or in the flat list (single-location stores) is the priority warehouse.
The Enable priority warehouse toggle on the same modal turns the feature on/off for that store. When off, drag handles dim and the ordering is ignored β closest-with-stock takes over.
Priority wins only when the warehouse has enough stock to fulfill the full quantity (or the full order, in single-warehouse mode). If it can't, routing falls back to the standard closest-with-stock logic. Priority is per-item under split mode, so one order can mix priority-routed items and closest-routed items.
Shipping rules can override routing
Shipping rules let customers selectively override geo-routing per condition β useful for "always send TX to FL", "always split CO between MA and FL", "skip routing for FL orders", or "this SKU stays in its channel location". Create rules from Settings β Shipping β Rules; each rule has filters (state, ZIP, store, channel tag, SKU, item tag, etc.) and one of the actions below.
Available rule actions
Action | What it does |
Apply manual Geo Route for Order | Pins the order's fulfillment to a chosen warehouse, with optional fallbacks. Cascades through primary β fallback β fallback if the previous can't cover the qty. Reason: |
Apply manual Split Geo Route for Order | Greedy split across primary + fallback warehouses. Reason: |
Do not apply Geo Route for order | Skips routing for the whole order β items keep the channel-assigned warehouse |
Do not apply Geo Route for item | Skips routing for matched items only. Supports item-level filters like Item SKU, Item Tag, Kit SKU. |
Do not Geo Route split orders | Forces the matched order into single-warehouse mode for this run only |
Apply Geo Route for Order | Re-enables splitting for the matched order even when the per-store Disable Split Geo Routing toggle is on |
Rules win over priority and closest-with-stock β they're a deliberate override. The activity log captures which rule applied so support can trace any unexpected routing.
Rule precedence & conflict detection
No-split beats allow-split. If both Do not Geo Route split orders and Apply Geo Route for Order match the same order, the no-split rule wins.
Conflict detection β rules that would route the same order to different outcomes are flagged in the rules table as "Conflicting with: <other rule>". Identical rules (same fingerprint) are treated as redundant, not conflicting.
Tag rule ping-pong β rules that add a tag and rules that remove the same tag are now flagged against each other.
Duplicate-log suppression β manual Geo Route rules no longer re-log on every sync. A per-rule record tracks the last chosen warehouse; the log is only appended when the chosen warehouse changes.
Picking workflows
Heads up: Whether picking is grouped by warehouse depends on the store. Stores with Geo Route enabled get the grouped layout automatically. Stores without Geo Route can opt in via Integration Settings β Fulfillment Settings β "Group order lines by assigned fulfillment locations" (per-store checkbox). When off, the store uses the flat picking table even if items have warehouse assignments. Manual warehouse reassignment from the picking interface is always available.
Single order picking
Items are grouped by their assigned warehouse, each group with a section header:
Items within a group only show picking locations from the assigned warehouse.
Pickable items and unpickable items are visually separated.
Items that couldn't be routed appear in an "Unassigned Warehouse" section at the bottom.
Batch picking
Steps are sorted by warehouse first, then by zone/location within each warehouse.
Warehouse headers visually separate items in the step list.
The warehouse name appears in the bin header during the active step.
The location dropdown only offers bins from the assigned warehouse.
"Skip unpickable items" auto-skips items with no pickable location in their assigned warehouse.
Showing pickers only their items
The system filters items down to what each warehouse user is responsible for through three layers:
1. User warehouse filters
In each user's profile, "Picking warehouses" controls which warehouses they can see locations from. A user assigned only to "East Coast Warehouse" will only see East Coast locations everywhere in the app.
2. Geo-routing warehouse restriction
On top of the user filter, each item's picking locations are restricted to the single warehouse it was routed to. This prevents picking the wrong unit.
3. "Hide unpickable items" preference
A per-user preference. When on, items that have no picking locations in the user's warehouses are completely hidden during picking.
Failure handling
Geo-routing is designed to never block order processing. If something goes wrong, the order still imports β it just lands with a clear reason code and (where applicable) a "Failed Geo-Routing" tag.
Failure | What happens | Reason code |
Customer ZIP missing | Order tagged "Failed Geo-Routing" |
|
ZIP not in database | Order tagged "Failed Geo-Routing" |
|
No warehouses have coordinates | Order tagged "Failed Geo-Routing" |
|
Non-US shipping address | Items skipped, no assignment |
|
No warehouse has stock for an item | Closest warehouse with a tracked entry assigned (Tier 2 fallback) |
|
Item not tracked at any eligible warehouse | Closest eligible warehouse assigned (Tier 3 fallback) |
|
Closest warehouse has partial stock | Closest with some stock assigned |
|
Item split across multiple warehouses | Split into multiple lines |
|
Closest warehouse has full stock | Assigned to closest with sufficient free stock (success) |
|
Priority covers full qty | Assigned to the priority warehouse (success) |
|
Single-warehouse mode β one warehouse can fulfill everything | Assigned to closest warehouse that can fulfill every item |
|
Single-warehouse mode β priority covers everything | Assigned to priority warehouse |
|
Single-warehouse mode β no warehouse can fulfill everything | Assigned to closest warehouse that can fulfill the most items; order tagged "Failed Geo-Routing" |
|
Rule forces a warehouse or split | Assigned by the shipping rule |
|
Manual assignment by a user | Preserved on single re-routes (cleared on bulk force re-route) |
|
When routing succeeds on a later attempt (e.g., after fixing warehouse coordinates), the "Failed Geo-Routing" tag is automatically removed.
FAQs
Why is my order tagged "Failed Geo-Routing"?
The customer's ZIP is missing, not in the database, or the order is international. The order activity log shows the specific reason.
Does this affect existing orders?
Yes. Turning geo-routing on for a store routes every open (unstarted) order for that store in the background. Turning it off clears auto-routed assignments β manual overrides are preserved.
Is there still an account-wide on/off switch?
No. Geo-routing is configured per store from Settings β Inventory β Geo Route. Each store has its own toggle, warehouse list, priority setting, and Disable Split Geo Routing toggle.
What does "Disable Split Geo Routing" do?
When on for a store, geo-routing assigns the entire order to a single warehouse β the closest one that can fulfill every item. If no single warehouse can cover the order, it falls back to the closest warehouse that can fulfill the most items and tags the order "Failed Geo-Routing". Use this when split shipments aren't acceptable.
How do I let one order split when the store has Disable Split Geo Routing turned on?
Create a shipping rule with the Apply Geo Route for Order action and a filter that matches the order (e.g., order tag force_split).
Why is a rule showing "Conflicting with: <other rule>"?
Two active rules would route the same kind of order to different outcomes. The rules table flags both rows so you can decide which one wins. Identical rules are treated as redundant and not flagged.
What if I only have one warehouse?
Geo-routing runs but all items go to that warehouse. No real benefit β leave it off.
Can I manually override a warehouse assignment?
Yes. From the picking interface, reassign a whole section, an individual item, or a partial quantity. Manual assignments stick across re-routes (unless someone forces a re-route).
Does this work with international orders?
No. Only US ZIPs are supported. International orders are flagged with non_us_address and skip routing.
How does this interact with warehouse-linked reserves?
Geo-routing reads the "free" quantity (on-hand minus reserves) per warehouse to decide where stock is actually available. This avoids over-promising stock that's already committed to another order.
What happens if my closest warehouse runs out mid-day?
The next order routes to the next-closest warehouse with stock. Geo-routing does not re-route already-routed open orders when stock changes.
Can I exclude a warehouse from a specific channel?
Yes β via warehouse links. Remove the warehouse from a store/location's linked-warehouse list and routing skips it for that channel.
Can a single order ship from multiple warehouses?
Yes β that's the normal split fulfillment behavior. The picking UI groups items by warehouse so each location only handles its own pieces.
Known limitations
US ZIPs only. International postal codes aren't supported.
No automatic re-routing on stock changes. Routing runs at sync time, on warehouse-link changes, and on manual re-route.
ZIP database covers ~42,500 codes β very new or unusual codes may be missing. The database refreshes monthly; support can trigger an immediate refresh if needed.
Shopify per-location inventory mismatch during reassignment: when a user manually moves an item from one warehouse to another, SKULabs doesn't call Shopify's
fulfillmentOrderMoveAPI. Per-location Shopify counts can temporarily differ until the next stock sync. Total inventory is always correct β only per-location counts can drift briefly.

