RYAN CHAN
成本模型 · 定价Cost Model · Pricing

单 SKU 仓租模型Per-SKU Storage
Cost Model

Ryan Chan
WMS 产品负责人 · 多伦多WMS Product Owner · Toronto
仓租不是按平方尺摊的,是按「库位 × 占用时长」摊的。同一个托位,放一托两天就出完的货,和放一托压了 447 天的货,成本差一百倍以上。按面积算,这两者完全一样。

这份模型把仓租从「每平方尺多少钱」一路拆到「每个 SKU 每天多少钱」,四个步骤全部跑在我自己负责的多伦多仓 WMS 实测占用数据上:689 个 SKU、1,326 个在用储位、6 个温区。左边的假设可以现场改,右边的结论实时重算。
Storage rent is not allocated by square foot. It is allocated by location × dwell time. The same pallet position holding stock that ships in two days, versus stock that has sat for 447 days, differs in cost by more than 100×. Measured by area, the two are identical.

This model takes storage cost from "dollars per square foot" all the way down to "dollars per SKU per day" — four steps, run on live occupancy data from the Toronto warehouse WMS I own: 689 SKUs, 1,326 occupied storage locations, 6 temperature zones. Change any assumption on the left; every conclusion on the right recomputes.
数据源:xhc_wms · 多伦多仓 · 快照 2026-08-20 · 结构与占用为实测,绝对容量以占比表示 Source: xhc_wms · Toronto DC · snapshot 2026-08-20 · structure and occupancy measured; absolute capacity expressed as shares 01 / 07
第一步Step 1
分区Zoning
「一平方尺多少钱」这个问题本身就是错的"Dollars per square foot" is the wrong question
你租的面积不等于能放货的面积。通道、打包区、发货区、办公室、消防通道,这些地方一件货都放不下,但租金照样在付。所以第一步不是算面积,是分区:仓储费必须由真正能存货的那部分面积去回收,而操作区和非操作区的租金要由操作费去回收,不能混进储位成本里搅乱结构。 The area you lease is not the area you can store in. Aisles, packing, shipping, offices, fire lanes — none of them hold a single unit, and all of them are on the rent cheque. So step one is not measuring area, it is zoning: storage rates must recover the rent attributable to space that actually holds goods, while operational and non-operational rent has to be recovered through handling rates instead.
这一步在我的系统里不是概念,是一个字段。cell_info.cell_use_type:2=仓储、1=拣货、0=验收、3=集货、4=上架车。只有 cell_use_type=2 的库位吃仓储成本。分区规则是我在 WMS 里定义的,所以这条线我不需要向营运要假设。 In my system this step is not a concept, it is a field. cell_info.cell_use_type2=storage, 1=pick face, 0=receiving, 3=staging, 4=putaway cart. Only cell_use_type=2 carries storage cost. I wrote the rules that assign it, which is why I don't have to ask operations for this assumption.

假设面板,现场可改Assumptions — change them live

场地与分区Building & zoning
sq ft
$/SF/yr
%
%
货位配置Location config
sq ft
%
名义租金 / 建筑平方尺Nominal rent / building SF
货位净占地实际承担Loaded rate / footprint SF
放大倍数Multiplier
建筑Building 存储区Storage block 货位净占地Rack footprint
总租金Total rent 储位承担Carried by storage ·操作费承担Carried by handling
托位总数Total positions ·每托位占地Floor per position
默认值 $20.50/SF 为 GTA 2026 Q1 全包口径(净租 $16.36 至 16.49 加 TMI $3.50 至 4.00)。建筑面积是输入项,不是本页的实测数据,原因见第 7 页:我的 WMS 里 cell_type 字段全为空,物理尺寸不在系统内。 The $20.50/SF default is GTA Q1 2026 all-in (net $16.36–16.49 + TMI $3.50–4.00). Building area is an input here, not measured data — see slide 7: cell_type is null across every location in my WMS, so physical dimensions are not in the system.
分区决定谁来回收租金Zoning decides who recovers the rent02 / 07
第二步Step 2
下钻:库区Drill down: zones
最贵的空间是最挤的,最便宜的空间空着一半The most expensive space is the tightest. The cheapest is half empty.
一个仓不是一种成本。冷冻区的电费是常温的数倍,所以一平方尺的成本也是数倍。下面是多伦多仓实测的六个温区:容量占比、当前占用率、平均占用天数,以及按成本权重折算后每个区真正吃掉多少仓租。结论很反直觉:冷冻区只占 9.0% 的储位容量,却吃掉 27.1% 的仓储成本;而常温区占了一半以上容量,占用率只有 34.6%。 A warehouse is not one cost. A freezer's power bill is several times ambient, so its cost per square foot is several times ambient too. Below are the six temperature zones as measured in the Toronto DC: capacity share, current occupancy, average dwell, and what share of storage cost each zone actually consumes once weighted. The result is counter-intuitive: frozen is 9.0% of storage capacity but 27.1% of storage cost, while ambient holds over half the capacity at just 34.6% occupancy.
温区Zone 容量占比Capacity share 占用率Occupancy 平均占用天数Avg dwell (days) 最长占用Max dwell 成本权重Cost weight 吃掉仓租Share of cost
成本权重是假设,占用数据是实测。冷冻和低温 3.0 倍、生鲜和冷藏 2.5 倍取自行业经验值,可以按实际电费和设备摊销替换;而容量占比、占用率、占用天数全部来自 inventorycell_info 的实查。「吃掉仓租」这一栏问的是「实际被消耗掉多少」,分母是实测库位天数,不是容量占比,这两个口径必须分开:租金分摊看的是每个区的空间要多少钱去提供,成本消耗看的是压在那里的货真正烧掉多少。混用会得出完全不同的结论。另外注意 UNSET 那一行:31.8% 的储位没有设 storage_condition。任何按温区分摊成本的模型,如果不显式处理这一桶,就会把五分之一的租金分错地方。这不是模型问题,是我系统里的数据质量问题,我知道它在哪。 The cost weights are assumptions; the occupancy data is measured. Frozen/cold at 3.0× and fresh/chilled at 2.5× are industry values and can be replaced with actual power and equipment amortisation. Capacity share, occupancy and dwell all come from live queries against inventory × cell_info. The "share of cost" column answers what was actually consumed, so its denominator is measured location-days, not capacity share — the two must be kept apart: allocation asks what each zone's space costs to provide, consumption asks what the stock sitting there actually burned. Conflating them yields entirely different conclusions. Note the UNSET row: 31.8% of storage locations have no storage_condition set — any temperature-based allocation that doesn't handle that bucket explicitly misassigns a fifth of the rent. That is a data-quality gap in my system, not a modelling one, and I know exactly where it lives.
租金按面积付,货按库位存,中间隔着一个占用率Rent is paid by area; goods are stored by location; utilisation sits in between03 / 07
第三步Step 3
占用时长Dwell time
同一栋楼,同一个托位,成本差几十倍Same building, same pallet position, tens of times the cost
前两步算出的是「一个库位一天多少钱」。真正的成本杀手是第三步:货在这个库位上停了多久。下面每一行用的都是该温区的实测平均占用天数,乘以该温区按当前占用率加载后的库位日成本,这就是一托货在我仓里真实吃掉的仓租。 The first two steps give you the cost of a location per day. The real cost driver is step three: how long the goods sat there. Every row below uses that zone's measured average dwell, multiplied by its daily location cost loaded for current occupancy — the actual storage cost one pallet consumes in my warehouse.
占用与定价Occupancy & pricing
%
%
$/plt/mo
空置也要有人付。占用率 53.6% 意味着每一个装了货的托位,要替将近一个空托位承担租金,所以库位日成本必须除以占用率。 Vacancy is paid for by someone. At 53.6% occupancy every occupied position carries the rent of nearly one empty position — which is why daily location cost must be divided by occupancy.
常温托位 / 天(已加载空置)Ambient position / day (loaded)
冷冻托位 / 天(已加载空置)Frozen position / day (loaded)
最贵 ÷ 最便宜(单托全周期)Costliest ÷ cheapest pallet
这条链只有 WMS 侧的人跑得出来。入库时间、上架货位、出库时间是任何 WMS 都有的三组字段;难的不是公式,是知道自己数据的粒度和坑。第 7 页把我踩到的坑全列出来了,包括一个让我第一版结果高估了 8 个百分点的粒度错误。 Only someone on the WMS side can run this chain. Receipt time, putaway location and issue time exist in every WMS; the difficulty is not the formula but knowing your own data's grain and traps. Slide 7 lists every one I hit, including a grain error that inflated my first result by 8 percentage points.
占用时长 × 库位日成本 = 真实仓租Dwell × daily location cost = actual storage cost04 / 07
第四步Step 4
排名与决策Ranking & decisions
10% 的 SKU 吃掉 59% 的仓租10% of SKUs consume 59% of storage cost
把加权库位天数分摊到 SKU 之后,多伦多仓 689 个 SKU 的仓租集中度是这样的。这不是理论分布,是实查结果: Once weighted location-days are allocated down to SKU level, storage cost across the Toronto DC's 689 SKUs concentrates like this — not a theoretical distribution, a measured one:
前 5% SKUTop 5% of SKUs
41.5%
前 10% SKUTop 10% of SKUs
59.3%
前 20% SKUTop 20% of SKUs
78.5%
前 50% SKUTop 50% of SKUs
96.7%

库存健康度四象限,改一个占用天数就看到 SKU 换象限Inventory health quadrants — change a dwell number, watch a SKU switch

SKU(脱敏)SKU (anonymised) 温区Zone 托位数Positions 占用天数Dwell days 期间销量Units sold 单件毛利 $Unit margin $ 仓租 $Storage $ 单位仓租 $$/unit 仓租/毛利Rent/margin 判定Verdict
高毛利 · 低仓租High margin · low rent
明星品,咬着别放,给它最好的库位。Stars. Hold on to them and give them the best locations.
高毛利 · 高仓租High margin · high rent
值得优化,不是砍。调库区、压库存天数、换更快周转的储位。Worth optimising, not cutting. Re-slot, cut cover days, move to faster locations.
低毛利 · 低仓租Low margin · low rent
可以留,但别压库存。Keep them, but don't build cover.
低毛利 · 高仓租Low margin · high rent
该砍就砍,不用犹豫。腾出来的库位比这个 SKU 值钱。Cut without hesitation. The freed location is worth more than the SKU.
毛利这一列必须从外面拿。WMS 只给成本侧:占用、库位、时长。毛利、周转、客诉在 ERP 和客户手里。这是模型的边界,也是我讲这份东西时会主动说清楚的地方:我提供的是成本侧的假设,而这些假设过去正是别人来找我要的那一半。 The margin column has to come from outside. The WMS only gives you the cost side — occupancy, location, dwell. Margin, turnover and complaint rates live in the ERP and with the client. That is the model's boundary, and I say so up front: what I supply is the cost-side assumption set — the half that people used to come to me for.
按「仓租 ÷ 毛利」排序,比值越高越该动Rank by rent ÷ margin; the higher the ratio, the sooner it moves05 / 07
商务转化Commercial
从成本到价卡From cost to rate card
会算保本填充率,才敢定价You can only price if you know your break-even fill
3PL 的仓储报价不是成本加个数就完事。仓是一个固定成本桶:单位成本等于固定成本除以货量,所以「填充率」比「单托毛利」先决定生死。下面用前几页的实测参数,直接算出价卡和保本点。 A 3PL storage quote is not cost plus a number. A warehouse is a fixed-cost bucket: unit cost equals fixed cost divided by volume, so fill rate decides survival before per-pallet margin does. Below, the measured parameters from the previous slides produce the rate card and the break-even point directly.
常温报价 / 托 / 月Ambient price / plt / mo
冷冻报价 / 托 / 月Frozen price / plt / mo
保本填充率Break-even fill
对比实际 53.6%vs actual 53.6%

价卡结构:按占用时长计费,不是按面积Rate card structure: charge for dwell, not for area

01 · 分温区01 · By zone

常温、生鲜、冷藏、冷冻分开报Separate rates per temperature zone

冷冻成本是常温的三倍,一个价报到底等于用常温客户补贴冷冻客户。实测里冷冻区占用率 82.1%,常温只有 34.6%,稀缺的那个区必须单独定价。Frozen costs 3× ambient; one blended rate means ambient clients subsidise frozen ones. Measured frozen occupancy is 82.1% against ambient's 34.6% — the scarce zone must be priced on its own.

02 · 按托天02 · Per pallet-day

托天计费,而非托月计费Bill per pallet-day, not per pallet-month

按月计费,住 2 天和住 29 天付一样的钱,快周转客户被惩罚,压货客户被补贴。按天计费直接把激励掰正。Monthly billing charges the same for 2 days as for 29 — it penalises fast-turning clients and subsidises hoarders. Daily billing fixes the incentive.

03 · 长龄附加费03 · Aging surcharge

超龄库存阶梯加价Tiered surcharge on aged stock

实测常温区有库位被占了 447 天,25 个库位超过 90 天。90 天和 180 天两档阶梯加价,既回收成本,也逼客户自己清库。One ambient location has been occupied 447 days; 25 exceed 90 days. Tiers at 90 and 180 days recover the cost and push the client to clear stock themselves.

04 · 最低消费04 · Minimums

最低托位承诺加假设前提Minimum commitment + assumption basis

空间一旦承诺就是固定成本。写明报价基于的托位数、周转天数、温区结构,超出即重议。不写清楚,毛利会被 scope creep 吃掉。Committed space is fixed cost. State the positions, cover days and zone mix the quote assumes, and reprice beyond them — otherwise scope creep eats the margin.

先算保本点,再谈价格Break-even first, price second06 / 07
数据模型Data model
坑 · 边界 · 下一步Traps · boundaries · next
这套模型踩过的坑,和它现在还不能回答的问题The traps this model hit, and what it still cannot answer
公式不难,难的是知道自己数据的粒度和缺口。下面五条全部是我在这份模型上真实踩到或查出来的,第一条让我的第一版结果高估了 8 个百分点。 The formulas are easy. Knowing your own data's grain and gaps is not. All five below are things I actually hit or found building this — the first one inflated my initial result by 8 percentage points.
inventory 粒度
= box_code
库存表是「箱」级,不是「库位」级。一个 SKU 有 33 条库存记录,实际只占 2 个冷冻库位。直接 SUM(DATEDIFF(...)) 得到的是箱天,不是库位天,会按每库位箱数的倍数高估。必须先按 DISTINCT cell_code 算库位占用,再按箱天份额把该库位成本分摊给 SKU。修正之后,前 10% SKU 的仓租占比从 67.7% 降到 59.3%。The inventory table is carton-grain, not location-grain. One SKU had 33 inventory rows but occupied only 2 frozen locations. A naive SUM(DATEDIFF(...)) yields carton-days, not location-days, overstating by the cartons-per-location factor. You must compute occupancy over DISTINCT cell_code first, then allocate each location's cost to SKUs by carton-day share. Correcting this moved the top-10% share from 67.7% to 59.3%.
cell_type IS NULL
(100%)
这就是我答不出仓库面积的真正原因。我的 WMS 把库位建成逻辑对象,不是物理对象。cell_type(物理结构)在全部 4,242 个库位上都是空的,货架层数、库位尺寸、净高都不在系统里。所以托位数我能精确到个位,面积却必须靠换算。这是数据模型的缺口,补法很具体:cell_type 落库,再给每类库位登记占地与层数,面积和容量就能从 WMS 直接出,不用再靠人记。This is the real reason I could not state the warehouse's square footage. My WMS models locations as logical objects, not physical ones — cell_type is null across all 4,242 locations, and rack levels, location dimensions and clear height are not in the system at all. I can give position counts exactly; area has to be derived. It is a data-model gap with a concrete fix: populate cell_type and register footprint and levels per location class, and area and capacity fall straight out of the WMS instead of relying on memory.
shelf_life_status
= 'CLOSE' (94%)
看起来像临期预警,实际没有区分度。2,997 条储位库存里有 2,819 条是 CLOSE,占 94%,覆盖 619 个 SKU,用它筛临期库存等于筛出全仓。真正有信号的是 WARNING(19 条)、DEADLINE(7 条)、OVERDUE(4 条)。一个字段有枚举值,不等于它能用。It looks like a near-expiry flag and carries no discriminating power. 2,819 of 2,997 inventory rows are CLOSE, spanning 619 SKUs — filtering on it returns the whole warehouse. The signal is in WARNING (19 rows), DEADLINE (7) and OVERDUE (4). A field having enum values does not make it usable.
cell_abc_level
vs dwell
ABC 周转分级没有产生任何效果。快速位平均占用 20.7 天、正常位 21.0 天、慢速位 19.7 天,三档几乎一样,而且 37% 的储位根本没设等级。这是一个现成的立项:库位分级的目的是让最好取的库位周转最快,现在它没有兑现,而衡量它的数据 WMS 里已经有了。目标可量化,基线已存在。The ABC turnover tiers are earning nothing. Fast locations average 20.7 days of dwell, normal 21.0, slow 19.7 — statistically flat — and 37% of storage locations have no tier set at all. That is a ready-made project: the point of tiering is that the most accessible locations turn fastest, it currently does not deliver that, and the data to measure it already exists in the WMS. Quantifiable target, baseline already in place.
枚举文档
跟不上生产
文档里没有的值在生产里活着。cell_use_type 出现了文档没有的 8 和 9(877 个 9 类库位,全部空置),拣货位上还有文档外的 cell_abc_level=3。做历史占用配对时,state=-1(撤回)、44 和 45(仅用于重算)、5 和 7 和 11(2023-10-17 前已废弃)、21 和 22(源码注释「不了解用途」)都必须显式排除,否则时间链会断。Values absent from the documentation are alive in production. cell_use_type shows undocumented values 8 and 9 (877 type-9 locations, all empty), and pick faces carry an undocumented cell_abc_level=3. When pairing historical occupancy you must explicitly exclude state=-1 (reversed), 44/45 (recalculation only), 5/7/11 (deprecated before 2023-10-17) and 21/22 (source comment: "purpose unknown") or the time chain breaks.
这份模型的诚实边界:它是 2026-08-20 的在库快照,不是历史配对。完整的进出配对要跑 inventory_transactto_cell_codefrom_cell_code 时间链;毛利、周转、客诉不在 WMS 内,必须从 ERP 和客户拿;冷区成本权重是行业经验值,不是实际电费。但成本侧的每一个假设,库位、分区、占用、时长,都是我在系统里定义并且能查证的。别人做报价要向营运要这些假设,我过去就是提供假设的那个人。 The model's honest boundaries: it is an on-hand snapshot at 2026-08-20, not a historical pairing — full in/out pairing means walking the to_cell_code / from_cell_code time chain in inventory_transact; margin, turnover and complaints are not in the WMS and must come from the ERP and the client; the cold-zone weights are industry values, not metered power. But every cost-side assumption — location, zone, occupancy, dwell — is one I defined in the system and can verify. Others building a quote have to ask operations for these assumptions. I used to be the person supplying them.
Ryan Chan · 单 SKU 仓租模型 · 2026-08Ryan Chan · Per-SKU Storage Cost Model · Aug 202607 / 07