# Order Fulfillment System Low-Level Design

Source: https://www.techinterview.org/post/3233467521/lld-order-fulfillment/
Updated: 2026-04-17 · techinterview.org

## What is Order Fulfillment?

Order fulfillment covers the steps from a confirmed order to the item delivered to the customer: pick → pack → ship → track → deliver. The fulfillment system coordinates warehouse management, carrier integration, shipping label generation, and real-time tracking updates. A well-designed fulfillment system directly impacts customer experience (delivery speed, accuracy) and operational cost.

## Requirements

  - Route orders to the optimal warehouse (closest to destination, has stock)

  - Generate pick lists for warehouse workers

  - Print shipping labels and submit to carrier APIs (UPS, FedEx, USPS)

  - Track shipments in real time; push updates to customers

  - Handle returns and re-shipments

  - 100K orders/day, SLA: ship within 24h of order placement

## Order Lifecycle


```
PLACED → PAYMENT_CONFIRMED → ROUTED → PICKING → PACKED → SHIPPED → IN_TRANSIT
→ OUT_FOR_DELIVERY → DELIVERED
                     ↓
              EXCEPTION (delay, lost, damage)
                     ↓
              RETURN_REQUESTED → RETURN_RECEIVED → REFUNDED
```


## Warehouse Routing

When an order is confirmed, route to the best warehouse. Routing algorithm:

  - Find warehouses with all order items in stock (JOIN Inventory WHERE quantity_available >= quantity)

  - Calculate estimated shipping time from each candidate warehouse to the delivery address (carrier API or shipping zone table)

  - Calculate shipping cost for each candidate (carrier rate table: weight × zone × service)

  - Score = alpha * delivery_time + beta * shipping_cost (configurable weights)

  - Assign to the warehouse with the best score

  - Reserve inventory at that warehouse

Split shipments: if no single warehouse has all items, split across two warehouses. Minimize splits (customer receives everything in one delivery when possible).

## Pick List Generation

A pick list tells warehouse workers which items to retrieve. Generated when the order is assigned to a warehouse:


```
PickList(pick_list_id, order_id, warehouse_id, status ENUM(PENDING,IN_PROGRESS,COMPLETE),
         created_at, assigned_to, completed_at)

PickListItem(pick_list_id, sku, location_code, quantity, picked_quantity, scanned_at)
-- location_code = aisle-rack-bin, e.g., "B3-12-04"
```

Batch picking: group multiple orders' items by warehouse zone to minimize travel distance. A picker walks once through the warehouse collecting items for 10-20 orders simultaneously. Zone picking: divide warehouse into zones; each picker is responsible for one zone. Items are merged at the packing station.

## Carrier Integration and Label Generation


```
def create_shipment(order_id, warehouse_id):
    order = get_order(order_id)
    package = calculate_package(order.items)  # weight, dimensions

    # Call carrier API (EasyPost, ShipStation, or direct UPS/FedEx API)
    response = carrier_api.create_shipment(
        from_address=warehouse.address,
        to_address=order.shipping_address,
        parcel={'weight_oz': package.weight_oz,
                'length': package.length, ...},
        service='UPS_GROUND'
    )

    label_url = response.postage_label.label_url
    tracking_number = response.tracking_code
    rate = response.rate.rate  # cost in dollars

    UPDATE Order SET tracking_number=tracking_number, status='SHIPPED',
                     carrier='UPS', label_url=label_url, shipped_at=NOW()
```


## Shipment Tracking

Carriers provide tracking webhooks (or polling APIs) with status updates: picked up, in transit, out for delivery, delivered, exception. Consume tracking events via webhook → Kafka → update Order status and notify customer. Push notification when out for delivery and when delivered. For tracking page: query order.tracking_number → carrier tracking API (cached in Redis, TTL=5min). Exception handling: if a package is stuck in transit for > 2× expected delivery time, alert customer service team and initiate a trace with the carrier.

## Returns

Return flow: customer requests return → generate return shipping label (carrier API) → email label to customer → customer ships back → warehouse receives and inspects → if condition OK: restock inventory; if damaged: write off → issue refund. Track return: ReturnRequest(order_id, reason, status ENUM(REQUESTED,LABEL_SENT,IN_TRANSIT,RECEIVED,INSPECTED,REFUNDED)). Restock only if item is resellable (no damage, original packaging). Disposition code on inspection: RESTOCK, DISPOSE, VENDOR_RETURN.

## Key Design Decisions

  - Warehouse routing algorithm — minimize shipping time and cost with configurable weights

  - Batch picking — reduces warehouse travel time, increases throughput per shift

  - EasyPost/ShipStation for carrier abstraction — single API for all carriers, automatic rate shopping

  - Carrier webhook for tracking — real-time updates without polling

  - State machine for order lifecycle — prevents invalid state transitions

Amazon system design is the canonical order fulfillment interview topic. See common questions for [Amazon interview: order fulfillment and warehouse system design](https://www.techinterview.org/post/3233460275/scale-ai-interview-guide-2026-data-infrastructure-rlhf-pipelines-and-ml-engineering/).

Shopify system design covers order fulfillment and shipping. Review patterns for [Shopify interview: order fulfillment system design](https://www.techinterview.org/post/3233459924/shopify-interview/).

Uber Eats system design covers order fulfillment and delivery logistics. See design patterns for [Uber interview: order fulfillment and logistics design](https://www.techinterview.org/post/3233460273/uber-interview-guide-2026-dispatch-systems-geospatial-algorithms-and-marketplace-engineering/).
