Skip to main content

How warehouse transfers work

A warehouse transfer moves stock from one of your warehouses to another and keeps your books honest at every step — the units leave the source, ride as in-transit inventory while they travel, and land as fresh on-hand stock at the destination, carrying their original cost and lot dates the whole way. This page explains the model underneath the buttons: the lifecycle, what shipping and receiving do to your inventory, how stock is committed without being deducted, the different transfer types, and how cost flows.

For the hands-on steps, see Create & open a transfer, Ship a transfer, Receive a transfer, and Close a transfer, add costs & post accounting. This page is the "what happens and why" behind those tasks. To move stock between bins inside a single warehouse — which is a different, lighter operation — see Move stock between bins instead.

Three status axes, not one

A transfer tracks three independent statuses at once: a transfer status (DraftOpenClosed), a shipment status (UnshippedPartially shippedShipped), and a receipt status (UnreceivedPartially receivedReceived). They advance semi-independently — a transfer can be Open, Shipped, and Partially received all at the same time. The transfer reference lists every value.

The transfer lifecycle

A standard (non-Amazon) transfer moves through four stages of work. You create it as a draft, open it to commit source stock, ship it to physically move the goods into transit, and receive it at the destination — and a full receipt automatically closes it.

  1. Draft. A new transfer starts as Draft: fully editable, holding no stock and writing no movements. Add the source warehouse, the destination warehouse, and line items. See Create & open a transfer.
  2. Open. Clicking Open Transfer commits the transfer. It creates allocations against source on-hand stock so those units can't be double-committed — but it doesn't deduct stock or write any movements yet. The transfer becomes Open with an Unshipped shipment status.
  3. Ship. Clicking Ship performs the physical move: it posts a negative movement at the source (removing on-hand) and a positive in-transit movement at the destination. This is the moment stock leaves. Partial ships are allowed — shipping some lines leaves the transfer Open and Partially shipped.
  4. Receive. At the destination, clicking Receive removes the in-transit units and creates new on-hand stock through fresh FIFO layers. When every shipped unit has been received, the transfer is marked Received and automatically moves to Closed.
Quick Receive skips the ship step

For a local or immediate transfer you don't have to ship first. From an Open, Unshipped transfer, Receive auto-creates a shipment covering exactly the quantities you're receiving, then receives them in one action — useful when the goods move the same day. See Receive a transfer.

The split between open and ship is deliberate (SKU-7965). Opening is a commitment — it reserves the stock so nothing else grabs it — while shipping is the physical event that actually deducts it. Keeping them separate means an open transfer can sit reserved for days before the goods physically leave, without the source warehouse's on-hand count dropping prematurely.

Opening commits stock without deducting it

Opening a standard transfer creates only Allocated allocation rows against the source warehouse's on-hand-available stock — it writes no inventory movements. Each line's quantity is checked against live availability, and if any line asks for more than is available, the whole open is refused with an insufficient-stock error. Nothing is partially committed.

This is a key difference from a sales order. A sales order line splits into Allocated (stock you have) plus a Planned backorder (demand waiting for stock to arrive). A transfer has no backorder state — it's an operational commitment, not customer demand, so it can't be partly satisfied and rolled forward. Either the source has the stock and the transfer opens, or it doesn't and the open is rejected.

As the transfer ships, each line's Allocated allocation flips to Fulfilled (splitting when you ship partially). And when a fully received transfer closes, any leftover non-Fulfilled allocations on its lines are garbage-collected — a safety net that clears stale "phantom" reservations against the source warehouse once the goods have provably arrived at the destination.

There is no "reserved" status

An open transfer's committed stock shows as Allocated in the stock states breakdown — the same earmark bucket a sales order uses. SKU.io has no separate "reserved" inventory status; the older reserved-movement mechanism was replaced by allocation rows. See Allocations & backorders and the allocations reference.

In-transit: What shipping and receiving actually do

The heart of the model is the pair of movements shipping writes, and the pair receiving writes to unwind them. Understanding these four movements explains every stock number you'll see on a transfer.

Shipping

When you ship a line, SKU.io walks the source warehouse's FIFO layers (oldest first) for the shipped quantity and, per consumed layer, posts two movements:

MovementWarehouseInventory statusSignEffect
Transfer outSourceActiveNegativeRemoves the units from source on-hand
Transfer in-transitDestinationIn-transitPositiveRecords the units as in-transit to the destination

The negative active movement is stamped with the exact source bin the stock was drawn from. The positive in-transit movement has no warehouse location — in-transit stock lives in no physical bin, so it's excluded from the destination's bin location cache. A partial ship moves only the shipped quantity into transit and leaves the rest committed at the source.

At this point the units count as In Transit on the destination warehouse and are gone from the source's On Hand. In-transit stock is tracked separately from on-hand: your company-wide Total stock is unchanged by shipping (the units still exist), but on-hand at the source has dropped and won't reappear until receipt. See Stock states for how In Transit sits alongside On Hand, Available, Allocated, On Hold, and Non-Sellable.

Receiving

Receiving is the mirror image. For the received quantity, SKU.io writes:

MovementWarehouseInventory statusSignEffect
In-transit cancellationDestinationIn-transitNegativeClears the units out of in-transit
Transfer receiptDestinationActivePositiveCreates new on-hand stock via fresh FIFO layers

The positive active receipt movement is the one stamped with the destination bin you receive into. A partial receipt clears and lands only that portion; the remainder stays in transit until it arrives. When the received total covers everything shipped, the receipt status becomes Received and the transfer closes.

You can't manually receive a channel-managed transfer

Transfers whose destination is Amazon FBA, Amazon AWD, or Walmart WFS are received automatically from the channel — Amazon's inbound reconciliation or the Walmart WFS inbound feed drives their receipt status. The destination warehouse holds no SKU-side on-hand, so a manual receipt would create orphan stock. Attempting one is rejected with a clear message, and the Receive action isn't offered in the app for those destinations. See Transfer types below.

FIFO and lot dates carry across the move

When receiving creates the destination on-hand stock, the new FIFO layers aren't stamped with today's date. Instead, SKU.io looks back at the exact source layers the shipment consumed and rebuilds them at the destination:

  1. It reads the source FIFO layers off the shipment's negative active movements.
  2. It groups them by their original FIFO layer date and lot identity (batch number plus expiry date), so each distinct lot stays its own group.
  3. For each group it creates one destination FIFO layer, copying the source FIFO layer date, batch number, expiry date, manufacture date, and lot notes.

The received quantity is distributed across those groups proportionally to what each contributed (using a largest-remainder rounding so unit counts always sum exactly to the receipt), and the cost is distributed proportionally too.

The result: a transfer preserves your FEFO (First Expired, First Out) ordering and full lot traceability across warehouses. Stock that was three months old at the source arrives three months old at the destination — it doesn't reset to "new" and jump the FIFO queue. If the shipment consumed several date or lot groups, receiving produces several destination layers, one per group. See FIFO layers & how COGS is realized and the FIFO/COGS reference.

Fallbacks when source layers can't be resolved

If no source layers can be traced (an edge case), receiving falls back to a single destination layer dated at receipt. AWD transfers are a deliberate exception: they hold no source-warehouse FIFO layers, so their destination layer is created fresh at receipt, dated with the receipt event and costed from the AWD ledger rather than by source preservation.

Transfer types

The source and destination warehouse types determine which flow a transfer follows. The Transfer type filter on the transfer list maps these to warehouse-type predicates so you can filter by them.

TypeSource → destinationFlow
StandardYour warehouse → your (non-Amazon) warehouseThe core open → ship → receive → close path on this page: real movements, in-transit tracking, FIFO preservation.
FBA inboundYour warehouse → Amazon FBAChannel-managed. Opening creates the reservation; shipping and receipt are driven by Amazon's inbound shipment lifecycle.
AWD inboundYour warehouse → Amazon AWDChannel-managed. Opening creates movements and a pending inbound immediately, since AWD units are treated as already in transit.
AWD → FBA replenishmentAmazon AWDAmazon FBAReconciled entirely through Amazon ledgers — no SKU-side inventory movements. The destination layer is created at FBA receipt from ledger cost.
WFSYour warehouse → Walmart WFSChannel-managed by the Walmart WFS inbound feed.

The three concept-critical rules for channel-managed types:

  • Standard is the only type that uses the manual ship/receive path. For every channel-managed type, the generic Ship and Receive actions are refused — shipping or receiving is driven by the channel, not by an operator clicking a button.
  • FBA destinations drop the shipping method. Saving a transfer whose destination is Amazon FBA nulls its shipping method automatically (SKU-2435) — Amazon controls the inbound carrier.
  • Amazon-to-Amazon transfers reconcile internally, so manual receiving-discrepancy handling is blocked for them.

Cost flow: COGS carries over, bills add landed cost

Because transferring stock between your own warehouses isn't a sale, it books no COGS — the goods haven't sold, they've moved. What a transfer does do is carry each unit's cost basis from the source to the destination so that when the stock eventually sells, its COGS is still correct.

Cost carries over from the consumed layers

The cost of a shipment line is the weighted-average cost of the exact FIFO layers it consumed at the source. That per-unit cost is what the destination FIFO layers are created at — so a unit that cost you $8.50 at the source is worth $8.50 at the destination, not a re-averaged or reset figure. This is what keeps COGS accurate across a move.

Landed cost comes from bills, not cost lines

Freight, duty, and handling on a transfer are added as bills linked to the transfer, and prorated onto the shipment lines by cost weighting. Each line's share of the bill total is folded into the destination layers' cost, so freight raises the value of the transferred stock. Add and manage these on the transfer — see Close a transfer, add costs & post accounting.

Cost financial lines are disabled — use bills

The older per-transfer "cost financial line" mechanism was disabled (2026-03-30) after seeing zero production use. Third-party costs on a transfer belong on a bill (a landed-cost invoice), which prorates correctly into the FIFO layers. Bills are the supported way to add landed cost to a transfer.

Accounting transactions

Shipping and receipt each generate a batch accounting transaction — moving value into an in-transit nominal code when goods ship and into the destination inventory code when they're received, so your balance sheet reflects where the stock physically is. If you need to rebuild them (after editing costs, say), the transfer's generate accounting transactions action re-posts them.

Cost corrections cascade downstream

If a source FIFO layer's cost is later corrected, the fix cascades to the destination layers this transfer created — a background recalculation walks the chain so downstream on-hand keeps the corrected basis. This is part of the broader COGS-correction machinery; see Correcting COGS: revalue vs rebuild vs recalculate and Rebuild COGS & the SKU COGS Health dashboard.

Auditing a transfer's movements

Every movement described above is visible in the inventory movement ledger, tagged with the transfer type and linked back to the shipment or receipt line that created it. A completed standard transfer of, say, 100 units leaves four movements per FIFO layer touched: a negative active at the source and positive in-transit at the destination (from shipping), then a negative in-transit and positive active at the destination (from receipt). The movement types & fields reference lists every field on those rows.

Next steps

Last verified: