Low-Level Design: Warehouse Inventory Management — Stock Tracking, Reservations, and Replenishment

Core Entities

Product: product_id, sku, name, category_id, unit_cost, unit_weight_grams, dimensions (JSONB: length, width, height in mm), reorder_point, reorder_quantity, lead_time_days, is_active. Warehouse: warehouse_id, name, address, timezone, capacity_cubic_meters. Location: location_id, warehouse_id, aisle, bay, level, bin, type (BULK, PICK_FACE, OVERFLOW), max_weight_kg, max_volume_cubic_cm. Inventory: inventory_id, product_id, location_id, quantity_on_hand, quantity_reserved, quantity_available (computed: on_hand – reserved), last_counted_at, last_moved_at. InventoryTransaction: txn_id, product_id, location_id, txn_type (RECEIVE, SHIP, ADJUST, TRANSFER, RESERVE, RELEASE), quantity (positive=in, negative=out), reference_id (order_id or PO_id), reference_type, performed_by, created_at. PurchaseOrder: po_id, supplier_id, status (DRAFT, SENT, CONFIRMED, PARTIAL, RECEIVED, CANCELLED), line_items (JSONB), expected_date, created_at.

Stock Reservation and Atomic Allocation

class InventoryService:
    def reserve_stock(self, product_id: int, quantity: int,
                      order_id: int) -> bool:
        with db.transaction():
            # Atomic read-modify-write with row-level lock
            inv = db.query_one(
                "SELECT inventory_id, quantity_on_hand, quantity_reserved "
                "FROM inventory WHERE product_id = %s "
                "FOR UPDATE",  # row lock prevents concurrent oversell
                product_id
            )
            if not inv:
                raise ProductNotFound(product_id)

            available = inv.quantity_on_hand - inv.quantity_reserved
            if available < quantity:
                raise InsufficientStock(
                    product_id, available, quantity
                )

            # Reserve stock
            db.execute(
                "UPDATE inventory SET quantity_reserved = quantity_reserved + %s "
                "WHERE inventory_id = %s",
                quantity, inv.inventory_id
            )

            # Audit trail
            db.insert("inventory_transactions", {
                "product_id": product_id,
                "location_id": inv.location_id,
                "txn_type": "RESERVE",
                "quantity": -quantity,  # negative = outbound reservation
                "reference_id": order_id,
                "reference_type": "ORDER"
            })
        return True

    def fulfill_reservation(self, product_id: int, quantity: int,
                             order_id: int):
        with db.transaction():
            inv = db.query_one(
                "SELECT * FROM inventory WHERE product_id = %s FOR UPDATE",
                product_id
            )
            db.execute(
                "UPDATE inventory "
                "SET quantity_on_hand = quantity_on_hand - %s, "
                "    quantity_reserved = quantity_reserved - %s "
                "WHERE inventory_id = %s",
                quantity, quantity, inv.inventory_id
            )
            db.insert("inventory_transactions", {
                "product_id": product_id,
                "txn_type": "SHIP",
                "quantity": -quantity,
                "reference_id": order_id,
                "reference_type": "ORDER"
            })

Receiving and Put-Away

def receive_purchase_order(self, po_id: int,
                            received_lines: list[dict]) -> Receipt:
    po = db.get_po(po_id)
    if po.status not in ("CONFIRMED", "PARTIAL"):
        raise InvalidPOStatus()

    for line in received_lines:
        product_id = line["product_id"]
        qty_received = line["quantity"]
        location_id = line.get("location_id") or 
                      self._suggest_putaway_location(product_id)

        with db.transaction():
            # Upsert inventory record for this product+location
            existing = db.query_one(
                "SELECT inventory_id, quantity_on_hand FROM inventory "
                "WHERE product_id = %s AND location_id = %s FOR UPDATE",
                product_id, location_id
            )
            if existing:
                db.execute(
                    "UPDATE inventory SET quantity_on_hand = quantity_on_hand + %s "
                    "WHERE inventory_id = %s",
                    qty_received, existing.inventory_id
                )
            else:
                db.insert("inventory", {
                    "product_id": product_id,
                    "location_id": location_id,
                    "quantity_on_hand": qty_received,
                    "quantity_reserved": 0
                })

            db.insert("inventory_transactions", {
                "product_id": product_id,
                "location_id": location_id,
                "txn_type": "RECEIVE",
                "quantity": qty_received,
                "reference_id": po_id,
                "reference_type": "PO"
            })

    self._update_po_status(po_id, received_lines)
    self._check_replenishment_triggers(received_lines)

Replenishment and Reorder Triggers

Trigger: after any stock-reducing transaction (SHIP, ADJUST), check if quantity_available falls below product.reorder_point. If yes: check if an open PO already exists for this product (avoid duplicate orders), then create a PurchaseOrder with quantity = reorder_quantity, expected_date = TODAY + lead_time_days. Auto-replenishment can be enabled per product. Replenishment background job (daily): scans all products WHERE quantity_available – reorder_point = 2 * average_daily_demand * lead_time_days (safety stock formula).

Shopify system design rounds cover inventory management. Review warehouse inventory LLD patterns for Shopify interview: inventory and warehouse management design.

DoorDash system design interviews cover inventory and supply chain systems. See design patterns for DoorDash interview: inventory and supply chain system design.

Stripe system design interviews cover transactional reservation systems. Review atomic inventory patterns for Stripe interview: transactional inventory and reservation systems.

Scroll to Top