Where every number on this site comes from
Each figure below was computed in your browser, just now, by the same engine that runs in the demo and in the Python package. If you install the package and run the same dataset, you get the same values and the same plan hash. That is the only claim this page makes, and it is checkable.
42 cases across 5 beverage SKUs (12 / 10 / 8 / 6 / 6), on a standard 1219 × 1016 mm GMA pallet with an 1800 mm height limit.
1 case did not fit within the height and support rules and is reported unplaced rather than quietly dropped: SKU003.
- Formula
- (optimized 47.1% − baseline 40.5%) ÷ baseline
- Dataset
- BEVERAGE_ORDER — 42 cases
- Algorithm
- shelf first-fit-decreasing, height-layered, per-box settling
- Reproduce it
- palletize-optimize your own CSV, or run scripts/verify_engine_parity.py
- —The baseline is the same packer with optimisation off: order preserved, single orientation, identical support rules — a stack that could actually be built.
- —"An unoptimized stack" is a distribution, not one number. This is the MEDIAN of 32 orderings; across the 10th-90th percentile the uplift is +4% to +30%.
- —The orderings are seeded from the multiset of cases, so re-sorting your CSV cannot change the figure. An earlier version could be swung by 138 percentage points that way.
- —Density is placed case volume ÷ (pallet footprint × stack height).
- Formula
- 0.6 × support (0.943) + 0.4 × centre-of-mass (0.832)
- Dataset
- BEVERAGE_ORDER
- Algorithm
- footprint overlap against surfaces at each box’s base, plus weighted CoM offset
- Reproduce it
- the same function scores the plan in the browser, in Python, and in the validator
- —Support is measured by real z-adjacency, not by layer index. A box over a gap scores zero.
- —This is a geometric model, not a transport simulation: no crush strength, no pallet flex, no road dynamics.
- Formula
- sum over cases of: 2× traverse to the infeed, 2× descend to the pick, 2× descend to this case, grip + release + settle, plus a wrist rotation when the plan calls for one — each move under a trapezoidal velocity profile
- Dataset
- BEVERAGE_ORDER
- Algorithm
- per-case kinematic model against a named reference cell
- Reproduce it
- lib/palletizer/cycle.ts, compared case by case against palletizer_full/plan.py by scripts/verify_engine_parity.py in CI
- —cycle time modelled from geometry, not measured on hardware — 1000 mm/s peak, 1200 mm/s^2, traversing 150 mm above the stack so far (ceiling 2400 mm), infeed 1200 mm from pallet centre at 900 mm, last 60 mm at 35% speed, grip 0.45 s, release 0.30 s, rotation 1.80 s
- —This replaced a flat 7.5 s per pick, which costed a case in the far corner of the top layer exactly what it costed one dropped in the middle of the bottom layer. The new figure is slower and responds to geometry; both were models, and neither is a measurement.
- —No conveyor wait, changeover, fault recovery or operator interaction is modelled.
- Formula
- labour $189k + freight $287k + damage $62k
- Dataset
- the ROI model’s default inputs, applied to the reference plan
- Algorithm
- nine editable inputs; only density uplift and build time come from the plan
- Reproduce it
- every input is editable on /roi-calculator; the formulas are printed beneath it
- —85 pallets/day over 255 working days at $31/hr.
- —Manual build assumed at 24 min/pallet — change it and the number changes.
- —Freight saving assumes denser pallets mean proportionally fewer of them.
- —This is a model, not a quote, and not anyone’s measured result.
An earlier version of this site displayed figures the code did not produce: an 18.7% density uplift, a 1.00 stability score, $187k in annual savings and an 8–18 month payback. On the same dataset the engine computed different numbers, and the site’s own ROI calculator disagreed with its own homepage.
The headline figures are now generated by lib/palletizer/headline.ts, which calls the engine rather than storing literals — so they cannot drift again without the engine itself changing. Two other things were corrected at the same time: support is now measured against the surfaces a case actually rests on rather than by layer index, and the density baseline is a stack that could physically be built rather than a volume calculation that allowed boxes to float.
A third correction followed, and it is the one most worth being explicit about. Making the baseline genuinely unoptimized briefly made it depend on the order the cases arrived in — so the same 42 boxes produced anything from −56% to +83% depending purely on how a CSV was sorted. It is now the median of 32 orderings seeded from the cases themselves, which no caller can influence, published with its 10th–90th percentile spread.
The uplift figure moved twice during this work, and not because the packer improved. Optimized density did not change at all across any of it. What changed was the yardstick: first the baseline stopped being allowed to stack boxes on air, then it stopped depending on row order. Each correction was right on its own, and the cumulative effect on a headline number is exactly the kind of drift this page exists to make visible rather than to hide.
Plan hash for the reference order: plan_1789265567629. The Python package produces the same content hash for the same inputs; that equivalence is checked in CI by scripts/verify_engine_parity.py.