supply-chain-analytics / 50-kpis · README
📄 KPI
⬆ 50 KPIs
KPI 50 KPIs · 5 categories · Python · SQL · Excel

📦 50 Supply Chain KPIs

A structured reference for analytics projects, dashboards, and business reviews. Every KPI includes its definition, formula, business meaning, and ready-to-use implementations in Python, SQL, and Excel.

🐍 Python 🗄️ SQL 📊 Excel 50 KPIs

1. Service Level & Customer Fulfillment KPIs

#01 On-Time Delivery (OTD)
Definition
Percentage of orders delivered on or before the promised date.
Formula
(On-time deliveries / Total deliveries) × 100
Why It Matters
Measures delivery reliability and customer service quality.
How to calculate
# df has columns: order_id, promised_date, actual_delivery_date df['on_time'] = df['actual_delivery_date'] <= df['promised_date'] otd = df['on_time'].mean() * 100 print(f"OTD: {otd:.1f}%")
SELECT ROUND( 100.0 * SUM(CASE WHEN actual_delivery_date <= promised_date THEN 1 ELSE 0 END) / COUNT(*), 2 ) AS otd_pct FROM orders;
| A (promised_date) | B (actual_delivery) | C (on_time?) | D (OTD %) | C2: =IF(B2<=A2,"Yes","No") D2: =COUNTIF(C2:C100,"Yes")/COUNTA(C2:C100)*100
#02 In-Full Delivery (IF)
Definition
Percentage of deliveries shipped with complete quantities requested.
Formula
(Orders delivered in full / Total orders) × 100
Why It Matters
Shows how well supply meets demand without shortages.
How to calculate
# df: order_id, qty_ordered, qty_delivered df['in_full'] = df['qty_delivered'] >= df['qty_ordered'] if_rate = df['in_full'].mean() * 100
SELECT ROUND(100.0 * SUM(CASE WHEN qty_delivered >= qty_ordered THEN 1 ELSE 0 END) / COUNT(*), 2) AS in_full_pct FROM orders;
| A (qty_ordered) | B (qty_delivered) | C (in_full?) | D (IF %) | C2: =IF(B2>=A2,"Yes","No") D2: =COUNTIF(C2:C100,"Yes")/COUNTA(C2:C100)*100
#03 OTIF (On-Time In-Full)
Definition
Percentage of orders delivered both on time and in full.
Formula
(Orders on time AND in full / Total orders) × 100
Why It Matters
Most important end-to-end service KPI.
How to calculate
df['otif'] = ( (df['actual_delivery_date'] <= df['promised_date']) & (df['qty_delivered'] >= df['qty_ordered']) ) otif = df['otif'].mean() * 100
SELECT ROUND(100.0 * SUM(CASE WHEN actual_delivery_date <= promised_date AND qty_delivered >= qty_ordered THEN 1 ELSE 0 END) / COUNT(*), 2) AS otif_pct FROM orders;
| A (promised) | B (actual) | C (qty_ord) | D (qty_del) | E (OTIF?) | F (OTIF%) | E2: =IF(AND(B2<=A2,D2>=C2),"Yes","No") F2: =COUNTIF(E2:E100,"Yes")/COUNTA(E2:E100)*100
#04Order Fill Rate
Definition
Percentage of customer demand fulfilled immediately from available stock.
Formula
(Units shipped immediately / Units ordered) × 100
Why It Matters
Reflects product availability and service responsiveness.
How to calculate
fill_rate = (df['units_shipped_immediately'].sum() / df['units_ordered'].sum()) * 100
SELECT ROUND(100.0 * SUM(units_shipped_immediately) / SUM(units_ordered), 2) AS fill_rate_pct FROM order_lines;
| A (units_shipped_immed) | B (units_ordered) | =SUM(A2:A100)/SUM(B2:B100)*100
#05Perfect Order Rate
Definition
% orders delivered: on time, in full, damage-free, with correct documentation.
Formula
(Perfect orders / Total orders) × 100
Why It Matters
Captures end-to-end execution quality across all dimensions.
How to calculate
df['perfect'] = ( df['on_time'] & df['in_full'] & df['no_damage'] & df['correct_docs'] ) por = df['perfect'].mean() * 100
SELECT ROUND(100.0 * SUM(CASE WHEN on_time=1 AND in_full=1 AND no_damage=1 AND correct_docs=1 THEN 1 ELSE 0 END) / COUNT(*), 2) AS por FROM orders;
| A (on_time) | B (in_full) | C (no_damage) | D (correct_docs) | E (perfect?) | E2: =IF(AND(A2="Yes",B2="Yes",C2="Yes",D2="Yes"),"Yes","No") =COUNTIF(E2:E100,"Yes")/COUNTA(E2:E100)*100
#06Backorder Rate
Definition
% of order lines/units that could not be fulfilled on the requested date.
Formula
(Backordered units / Total ordered units) × 100
Why It Matters
Highlights stock shortages and demand planning gaps.
How to calculate
backorder_rate = (df['backordered_units'].sum() / df['total_ordered_units'].sum()) * 100
SELECT ROUND(100.0*SUM(backordered_units)/SUM(total_ordered_units),2) AS backorder_rate FROM order_lines;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=backordered, B=total ordered)
#07Stockout Rate
Definition
Frequency at which inventory is unavailable when needed.
Formula
(Stockout events / Total demand events) × 100
Why It Matters
Measures product unavailability and lost sales risk.
How to calculate
stockout_rate = (df['stockout_events'].sum() / df['demand_events'].sum()) * 100
SELECT ROUND(100.0*SUM(stockout_flag)/COUNT(*),2) AS stockout_rate FROM demand_events;
=COUNTIF(A2:A100,"Stockout")/COUNTA(A2:A100)*100
#08Case Fill Rate
Definition
% of cases shipped vs cases ordered.
Formula
(Cases shipped / Cases ordered) × 100
Why It Matters
Common KPI in FMCG and warehouse distribution.
How to calculate
cfr = (df['cases_shipped'].sum() / df['cases_ordered'].sum()) * 100
SELECT ROUND(100.0*SUM(cases_shipped)/SUM(cases_ordered),2) AS case_fill_rate FROM shipments;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=shipped, B=ordered)
#09Customer Order Cycle Time
Definition
Average time from customer order placement to delivery.
Formula
Delivery date − Order date
Why It Matters
Measures speed of customer fulfillment.
How to calculate
df['cycle_days'] = (df['delivery_date'] - df['order_date']).dt.days avg_cycle = df['cycle_days'].mean()
SELECT AVG(DATEDIFF(delivery_date, order_date)) AS avg_cycle_days FROM orders;
| A (order_date) | B (delivery_date) | C (days) | C2: =B2-A2 =AVERAGE(C2:C100)
#10Returns Rate
Definition
% of shipped orders or units returned by customers.
Formula
(Returned units / Delivered units) × 100
Why It Matters
Indicates quality, fulfillment, or product fit issues.
How to calculate
returns_rate = (df['returned_units'].sum() / df['delivered_units'].sum()) * 100
SELECT ROUND(100.0*SUM(returned_units)/SUM(delivered_units),2) AS returns_rate FROM shipments;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=returned, B=delivered)

2. Inventory KPIs

#11Inventory Turnover
Definition
Number of times inventory is sold or used over a period.
Formula
COGS / Average Inventory
Why It Matters
Measures inventory efficiency and working capital use.
How to calculate
avg_inv = (df['opening_inv'] + df['closing_inv']) / 2 turnover = df['cogs'] / avg_inv
SELECT ROUND(SUM(cogs) / AVG((opening_inv+closing_inv)/2), 2) AS inv_turnover FROM inventory_summary;
| A (COGS) | B (avg_inventory) | =A2/B2
#12Days Inventory Outstanding (DIO)
Definition
Average days inventory stays in stock before being sold.
Formula
(Average Inventory / COGS) × Days in period
Why It Matters
Shows how long cash is tied up in inventory.
How to calculate
dio = (avg_inv / df['cogs']) * 365
SELECT ROUND(AVG((opening_inv+closing_inv)/2) / SUM(cogs) * 365, 1) AS dio FROM inventory_summary;
| A (avg_inventory) | B (COGS) | =(A2/B2)*365
#13Inventory Accuracy
Definition
Degree to which system inventory matches physical inventory.
Formula
(Correct records / Total records checked) × 100
Why It Matters
Critical for planning, fulfillment, and warehouse control.
How to calculate
df['match'] = df['system_qty'] == df['physical_qty'] accuracy = df['match'].mean() * 100
SELECT ROUND(100.0*SUM(CASE WHEN system_qty=physical_qty THEN 1 ELSE 0 END)/COUNT(*),2) AS inv_accuracy FROM cycle_counts;
| A (system_qty) | B (physical_qty) | C (match?) | C2: =IF(A2=B2,"Yes","No") =COUNTIF(C2:C100,"Yes")/COUNTA(C2:C100)*100
#14Cycle Count Accuracy
Definition
Accuracy observed during regular cycle count checks.
Formula
(Accurate counted items / Total counted) × 100
Why It Matters
Maintains high inventory record reliability.
How to calculate
cca = (df['accurate_items'].sum() / df['total_counted'].sum()) * 100
SELECT ROUND(100.0*SUM(accurate_items)/SUM(total_counted),2) AS cycle_count_accuracy FROM cycle_counts;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=accurate, B=total counted)
#15Safety Stock Coverage
Definition
Days that safety stock can cover expected demand.
Formula
Safety stock / Average demand per day
Why It Matters
Shows buffer protection against supply/demand variability.
How to calculate
df['ss_coverage_days'] = df['safety_stock'] / df['avg_daily_demand']
SELECT sku, ROUND(safety_stock/avg_daily_demand, 1) AS ss_coverage_days FROM inventory_params;
| A (safety_stock) | B (avg_daily_demand) | =A2/B2
#16Inventory Days of Supply
Definition
Days current inventory can support forecast demand.
Formula
Current inventory / Average daily demand
Why It Matters
Useful for replenishment and short-term planning.
How to calculate
df['dos'] = df['current_inventory'] / df['avg_daily_demand']
SELECT sku, ROUND(current_inventory/avg_daily_demand,1) AS days_of_supply FROM inventory;
=A2/B2 (A=current_inv, B=avg_daily_demand)
#17Slow-Moving Inventory Rate
Definition
% of inventory moving below expected threshold.
Formula
(Slow-moving inv value / Total inv value) × 100
Why It Matters
Identifies inefficient stock holding.
How to calculate
slow = df[df['velocity'] < threshold]['inv_value'].sum() smr = (slow / df['inv_value'].sum()) * 100
SELECT ROUND(100.0*SUM(CASE WHEN velocity < 0.1 THEN inv_value ELSE 0 END)/SUM(inv_value),2) AS slow_moving_rate FROM inventory;
| A (inv_value) | B (velocity) | =SUMIF(B2:B100,"<0.1",A2:A100)/SUM(A2:A100)*100
#18Obsolete Inventory Rate
Definition
% of inventory that can no longer be sold or used.
Formula
(Obsolete inv value / Total inv value) × 100
Why It Matters
Highlights waste and write-off exposure.
How to calculate
obs_rate = (df[df['status']=='obsolete']['inv_value'].sum() / df['inv_value'].sum()) * 100
SELECT ROUND(100.0*SUM(CASE WHEN status='obsolete' THEN inv_value ELSE 0 END)/SUM(inv_value),2) AS obsolete_rate FROM inventory;
=SUMIF(B2:B100,"obsolete",A2:A100)/SUM(A2:A100)*100 (A=inv_value, B=status)
#19Inventory Carrying Cost
Definition
Total cost of holding inventory over a period.
Formula
Storage + Capital + Insurance + Obsolescence + Handling
Why It Matters
Makes inventory trade-offs visible in financial terms.
How to calculate
df['carrying_cost'] = ( df['storage'] + df['capital'] + df['insurance'] + df['obsolescence'] + df['handling'] )
SELECT storage_cost+capital_cost+insurance_cost+obsolescence_cost+handling_cost AS carrying_cost FROM cost_summary;
| A (storage) | B (capital) | C (insur) | D (obso) | E (handling) | =SUM(A2:E2)
#20Forecast Bias
Definition
Systematic tendency of forecast to be above or below actual demand.
Formula
Sum(Forecast − Actual) over time
Why It Matters
Detects directional error in demand planning.
How to calculate
df['bias'] = df['forecast'] - df['actual'] total_bias = df['bias'].sum() # positive = over-forecast
SELECT SUM(forecast - actual) AS forecast_bias FROM demand_plan;
| A (forecast) | B (actual) | C (bias) | C2: =A2-B2 =SUM(C2:C100) total bias; =AVERAGE(C2:C100) for avg bias

3. Forecasting & Planning KPIs

#21Forecast Accuracy
Definition
Measures how close forecast values are to actual demand.
Formula
1 − MAPE (or WAPE)
Why It Matters
Core KPI for demand planning performance.
How to calculate
mape = ((df['actual']-df['forecast']).abs()/df['actual']).mean() * 100 fa = 100 - mape
SELECT 100 - ROUND(100.0*AVG(ABS(actual-forecast)/NULLIF(actual,0)),2) AS forecast_accuracy FROM demand_plan;
MAPE in column C: =ABS(A2-B2)/A2 (A=actual, B=forecast) Forecast Accuracy: =1-AVERAGE(C2:C100) format as %
#22MAPE
Definition
Mean Absolute Percentage Error between forecast and actual.
Formula
Avg(|Actual − Forecast| / Actual) × 100
Why It Matters
Most common forecasting accuracy metric.
How to calculate
mape = ((df['actual']-df['forecast']).abs()/df['actual']).mean() * 100
SELECT ROUND(100.0*AVG(ABS(actual-forecast)/NULLIF(actual,0)),2) AS mape FROM demand_plan;
C2: =ABS(A2-B2)/A2 (A=actual, B=forecast) =AVERAGE(C2:C100)*100 = MAPE %
#23WAPE
Definition
Weighted Absolute Percentage Error weighted by actual volume.
Formula
(Sum |errors| / Sum actual) × 100
Why It Matters
More stable than MAPE for business reporting.
How to calculate
wape = ((df['actual']-df['forecast']).abs().sum() / df['actual'].sum()) * 100
SELECT ROUND(100.0*SUM(ABS(actual-forecast))/SUM(actual),2) AS wape FROM demand_plan;
C2: =ABS(A2-B2) (A=actual, B=forecast) =SUM(C2:C100)/SUM(A2:A100)*100
#24MAE
Definition
Mean Absolute Error — average absolute difference between forecast and actual.
Formula
Average(|Actual − Forecast|)
Why It Matters
Gives error in actual volume units.
How to calculate
mae = (df['actual']-df['forecast']).abs().mean()
SELECT AVG(ABS(actual-forecast)) AS mae FROM demand_plan;
C2: =ABS(A2-B2) =AVERAGE(C2:C100)
#25RMSE
Definition
Root Mean Squared Error — penalizes large misses more heavily.
Formula
√(Average of squared errors)
Why It Matters
Useful when large forecast errors are especially costly.
How to calculate
import numpy as np rmse = np.sqrt((((df['actual']-df['forecast'])**2).mean()))
SELECT SQRT(AVG(POW(actual-forecast,2))) AS rmse FROM demand_plan;
C2: =(A2-B2)^2 =SQRT(AVERAGE(C2:C100))
#26Demand Plan Attainment
Definition
Degree to which actual demand aligns with the demand plan.
Formula
(Actual demand / Planned demand) × 100
Why It Matters
Shows planning realism and execution alignment.
How to calculate
dpa = (df['actual_demand'].sum() / df['planned_demand'].sum()) * 100
SELECT ROUND(100.0*SUM(actual_demand)/SUM(planned_demand),2) AS dpa FROM demand_plan;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=actual, B=planned)
#27Supply Plan Attainment
Definition
Degree to which actual supply execution meets the agreed supply plan.
Formula
(Actual supply / Planned supply) × 100
Why It Matters
Tracks planning discipline and operational consistency.
How to calculate
spa = (df['actual_supply'].sum() / df['planned_supply'].sum()) * 100
SELECT ROUND(100.0*SUM(actual_supply)/SUM(planned_supply),2) AS spa FROM supply_plan;
=SUM(A2:A100)/SUM(B2:B100)*100
#28Production Plan Adherence
Definition
% of production completed as originally scheduled.
Formula
(Scheduled production executed / Total planned) × 100
Why It Matters
Reveals scheduling stability and execution quality.
How to calculate
ppa = (df['executed_as_scheduled'].sum() / df['total_planned'].sum()) * 100
SELECT ROUND(100.0*SUM(executed_as_scheduled)/SUM(total_planned),2) AS ppa FROM production_schedule;
=SUM(A2:A100)/SUM(B2:B100)*100
#29Replenishment Lead Time
Definition
Average time between placing a replenishment order and receiving stock.
Formula
Receipt date − Replenishment order date
Why It Matters
Essential for reorder point and inventory planning.
How to calculate
df['replen_lt'] = (df['receipt_date']-df['order_date']).dt.days avg_lt = df['replen_lt'].mean()
SELECT AVG(DATEDIFF(receipt_date,order_date)) AS avg_replen_lt FROM replenishment_orders;
C2: =B2-A2 (A=order_date, B=receipt_date) =AVERAGE(C2:C100)
#30Planning Cycle Time
Definition
Time required to complete a planning cycle (e.g., S&OP).
Formula
Planning completion date − Planning start date
Why It Matters
Shows efficiency of planning processes.
How to calculate
df['cycle_time'] = (df['completion_date']-df['start_date']).dt.days avg_ct = df['cycle_time'].mean()
SELECT AVG(DATEDIFF(completion_date,start_date)) AS avg_cycle_time FROM planning_cycles;
C2: =B2-A2 =AVERAGE(C2:C100)

4. Procurement & Supplier KPIs

#31Supplier On-Time Delivery
Definition
% of supplier deliveries arriving on or before expected date.
Formula
(On-time supplier deliveries / Total deliveries) × 100
Why It Matters
Measures supplier reliability.
How to calculate
sotd = (df[df['receipt_date']<=df['expected_date']].shape[0] / len(df)) * 100
SELECT ROUND(100.0*SUM(CASE WHEN receipt_date<=expected_date THEN 1 ELSE 0 END)/COUNT(*),2) AS supplier_otd FROM supplier_deliveries;
C2: =IF(B2<=A2,"Yes","No") (A=expected, B=receipt) =COUNTIF(C2:C100,"Yes")/COUNTA(C2:C100)*100
#32Supplier In-Full Delivery
Definition
% of supplier deliveries received in full quantity.
Formula
(Supplier deliveries in full / Total deliveries) × 100
Why It Matters
Tracks upstream service consistency.
How to calculate
sif = (df[df['qty_received']>=df['qty_ordered']].shape[0] / len(df)) * 100
SELECT ROUND(100.0*SUM(CASE WHEN qty_received>=qty_ordered THEN 1 ELSE 0 END)/COUNT(*),2) AS supplier_if FROM supplier_deliveries;
=COUNTIF(C2:C100,"Yes")/COUNTA(C2:C100)*100 C2: =IF(B2>=A2,"Yes","No") (A=ordered, B=received)
#33Supplier OTIF
Definition
% of supplier deliveries received both on time and in full.
Formula
(Supplier OT & IF deliveries / Total) × 100
Why It Matters
Best single KPI for supplier execution performance.
How to calculate
df['s_otif'] = (df['receipt_date']<=df['expected_date']) & (df['qty_received']>=df['qty_ordered']) s_otif = df['s_otif'].mean() * 100
SELECT ROUND(100.0*SUM(CASE WHEN receipt_date<=expected_date AND qty_received>=qty_ordered THEN 1 ELSE 0 END)/COUNT(*),2) AS supplier_otif FROM supplier_deliveries;
E2: =IF(AND(B2<=A2,D2>=C2),"Yes","No") =COUNTIF(E2:E100,"Yes")/COUNTA(E2:E100)*100
#34Purchase Price Variance (PPV)
Definition
Difference between standard purchase cost and actual purchase cost.
Formula
(Actual price − Standard price) × Quantity
Why It Matters
Measures procurement cost control.
How to calculate
df['ppv'] = (df['actual_price'] - df['standard_price']) * df['qty_purchased'] total_ppv = df['ppv'].sum()
SELECT SUM((actual_price-standard_price)*qty_purchased) AS total_ppv FROM purchase_orders;
D2: =(B2-A2)*C2 (A=std_price, B=actual_price, C=qty) =SUM(D2:D100)
#35Supplier Defect Rate
Definition
% of supplier units received with defects or quality issues.
Formula
(Defective received units / Total received) × 100
Why It Matters
Links supplier quality to operational performance.
How to calculate
defect_rate = (df['defective_units'].sum() / df['received_units'].sum()) * 100
SELECT ROUND(100.0*SUM(defective_units)/SUM(received_units),2) AS defect_rate FROM supplier_receipts;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=defective, B=received)
#36Supplier Lead Time
Definition
Average time from PO issuance to supplier delivery.
Formula
Goods receipt date − PO date
Why It Matters
Critical for procurement planning and service.
How to calculate
df['supplier_lt'] = (df['goods_receipt_date']-df['po_date']).dt.days avg_slt = df['supplier_lt'].mean()
SELECT AVG(DATEDIFF(goods_receipt_date,po_date)) AS avg_supplier_lt FROM purchase_orders;
C2: =B2-A2 (A=po_date, B=receipt_date) =AVERAGE(C2:C100)
#37Purchase Order Cycle Time
Definition
Time required to create, approve, issue, and receive a PO.
Formula
PO completion date − PO initiation date
Why It Matters
Indicates procurement process efficiency.
How to calculate
df['po_cycle'] = (df['completion_date']-df['initiation_date']).dt.days avg_po_ct = df['po_cycle'].mean()
SELECT AVG(DATEDIFF(completion_date,initiation_date)) AS po_cycle_time FROM purchase_orders;
C2: =B2-A2 (A=initiation, B=completion) =AVERAGE(C2:C100)
#38Contract Compliance Rate
Definition
% of spend made according to negotiated contracts.
Formula
(Contract-compliant spend / Total spend) × 100
Why It Matters
Shows procurement discipline and savings capture.
How to calculate
ccr = (df[df['on_contract']==True]['spend'].sum() / df['spend'].sum()) * 100
SELECT ROUND(100.0*SUM(CASE WHEN on_contract=1 THEN spend ELSE 0 END)/SUM(spend),2) AS contract_compliance FROM spend_data;
=SUMIF(B2:B100,"Yes",A2:A100)/SUM(A2:A100)*100 (A=spend, B=on_contract Y/N)
#39Spend Under Management
Definition
% of total spend controlled through procurement processes.
Formula
(Managed spend / Total spend) × 100
Why It Matters
Measures procurement influence and governance.
How to calculate
sum_pct = (df[df['managed']==True]['spend'].sum() / df['spend'].sum()) * 100
SELECT ROUND(100.0*SUM(CASE WHEN managed=1 THEN spend ELSE 0 END)/SUM(spend),2) AS spend_under_mgmt FROM spend_data;
=SUMIF(B2:B100,"Yes",A2:A100)/SUM(A2:A100)*100
#40Supplier Concentration Risk
Definition
Share of spend concentrated in top suppliers.
Formula
(Spend with top N suppliers / Total spend) × 100
Why It Matters
Reveals supply risk and single-source dependency.
How to calculate
top_n = df.groupby('supplier')['spend'].sum().nlargest(5).sum() conc_risk = (top_n / df['spend'].sum()) * 100
SELECT ROUND(100.0*SUM(spend)/(SELECT SUM(spend) FROM spend_data),2) AS concentration FROM (SELECT supplier, SUM(spend) AS spend FROM spend_data GROUP BY supplier ORDER BY spend DESC LIMIT 5) top5;
Sort spend descending, then: =SUM(B2:B6)/SUM(B2:B100)*100 (top 5 rows / total spend)

5. Warehouse & Logistics KPIs

#41Warehouse Picking Accuracy
Definition
% of order lines picked correctly without error.
Formula
(Correctly picked lines / Total picked) × 100
Why It Matters
Directly impacts service, returns, and customer satisfaction.
How to calculate
wpa = (df['correct_lines'].sum() / df['total_lines'].sum()) * 100
SELECT ROUND(100.0*SUM(correct_lines)/SUM(total_lines),2) AS picking_accuracy FROM warehouse_picks;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=correct, B=total)
#42Dock-to-Stock Time
Definition
Time from inbound receipt at dock to stock availability in system.
Formula
Stock availability timestamp − Receipt timestamp
Why It Matters
Measures inbound warehouse efficiency.
How to calculate
df['dts_hours'] = (df['stock_avail_ts']-df['receipt_ts']).dt.total_seconds() / 3600 avg_dts = df['dts_hours'].mean()
SELECT AVG(TIMESTAMPDIFF(HOUR, receipt_ts, stock_avail_ts)) AS avg_dts_hours FROM inbound_receipts;
C2: =(B2-A2)*24 (A=receipt_ts, B=avail_ts) → hours =AVERAGE(C2:C100)
#43Warehouse Capacity Utilization
Definition
% of warehouse space or positions currently used.
Formula
(Used capacity / Total capacity) × 100
Why It Matters
Balances congestion risk versus asset efficiency.
How to calculate
util = (df['used_positions'].sum() / df['total_positions'].sum()) * 100
SELECT ROUND(100.0*SUM(used_positions)/SUM(total_positions),2) AS capacity_utilization FROM warehouse_snapshot;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=used, B=total)
#44Labor Productivity
Definition
Output per labor hour in warehouse or logistics operations.
Formula
Units handled / Labor hours
Why It Matters
Tracks workforce efficiency.
How to calculate
productivity = df['units_handled'].sum() / df['labor_hours'].sum()
SELECT ROUND(SUM(units_handled)/SUM(labor_hours),1) AS units_per_hour FROM labor_log;
=SUM(A2:A100)/SUM(B2:B100) (A=units, B=hours)
#45Transportation Cost per Unit
Definition
Logistics transportation cost per shipped unit/case/pallet.
Formula
Total transport cost / Total shipped units
Why It Matters
Makes transport efficiency easy to compare over time.
How to calculate
cost_per_unit = df['transport_cost'].sum() / df['shipped_units'].sum()
SELECT ROUND(SUM(transport_cost)/SUM(shipped_units),4) AS cost_per_unit FROM shipments;
=SUM(A2:A100)/SUM(B2:B100) (A=cost, B=units)
#46Freight Cost as % of Sales
Definition
Share of revenue consumed by freight spending.
Formula
(Freight cost / Net sales) × 100
Why It Matters
Connects logistics cost to commercial performance.
How to calculate
fc_pct = (df['freight_cost'].sum() / df['net_sales'].sum()) * 100
SELECT ROUND(100.0*SUM(freight_cost)/SUM(net_sales),2) AS freight_pct_sales FROM financials;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=freight, B=net_sales)
#47Truck Fill Rate
Definition
% of vehicle capacity utilized in shipments.
Formula
(Loaded volume or weight / Total truck capacity) × 100
Why It Matters
Reflects transport asset utilization.
How to calculate
tfr = (df['loaded_weight'].sum() / df['truck_capacity'].sum()) * 100
SELECT ROUND(100.0*SUM(loaded_weight)/SUM(truck_capacity),2) AS truck_fill_rate FROM shipments;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=loaded, B=capacity)
#48Average Delivery Lead Time
Definition
Average transit time from dispatch to customer delivery.
Formula
Delivery date − Shipment date
Why It Matters
Shows transportation speed and consistency.
How to calculate
df['transit_days'] = (df['delivery_date']-df['shipment_date']).dt.days avg_dlt = df['transit_days'].mean()
SELECT AVG(DATEDIFF(delivery_date,shipment_date)) AS avg_delivery_lt FROM shipments;
C2: =B2-A2 (A=ship_date, B=delivery_date) =AVERAGE(C2:C100)
#49Damage Rate in Transit
Definition
% of shipments or units damaged during transport.
Formula
(Damaged units / Total shipped units) × 100
Why It Matters
Measures handling and transportation quality.
How to calculate
damage_rate = (df['damaged_units'].sum() / df['shipped_units'].sum()) * 100
SELECT ROUND(100.0*SUM(damaged_units)/SUM(shipped_units),2) AS damage_rate FROM shipments;
=SUM(A2:A100)/SUM(B2:B100)*100 (A=damaged, B=shipped)
#50Logistics Cost to Serve
Definition
Total logistics cost to serve a customer, product, channel, or region.
Formula
Transport + Warehousing + Handling + Delivery costs
Why It Matters
Supports profitability analysis and network decisions.
How to calculate
df['cost_to_serve'] = ( df['transport'] + df['warehousing'] + df['handling'] + df['delivery'] ) cts_by_customer = df.groupby('customer')['cost_to_serve'].sum()
SELECT customer, SUM(transport_cost+warehousing_cost+handling_cost+delivery_cost) AS cost_to_serve FROM logistics_costs GROUP BY customer ORDER BY cost_to_serve DESC;
| A (transport) | B (warehouse) | C (handling) | D (delivery) | =SUM(A2:D2) per row; then SUMIF by customer/channel