Reference
Solver
A multi-start first-fit-decreasing search over extreme points, scored by the objective you pick.
Objectives
| Objective | Then ranks by | Ties fall through to |
|---|---|---|
MIN_CARTONS | Fewest physical cartons. | Utilization, then cost. |
MIN_COST | Carton cost plus a freight proxy on billable weight. | Carton count, then utilization. |
MIN_DIM_WEIGHT | Total billable weight — the greater of gross and dimensional. | Carton count, then utilization, then cost. |
BEST_FIT | Highest aggregate volume utilization. | Carton count, then cost. |
Units placed outranks all four: a cheaper plan that leaves goods on the bench is not a plan. BEST_FIT uses aggregate utilization — goods volume over total cavity — because a mean can be raised by adding another small, full box.
How candidates are searched
| Step | Rule |
|---|---|
| Order | 6 orderings by default, 12 at most. Fragile items always sort last. |
| Position | Every live extreme point, in every permitted pose. |
| Score | Lowest y, then lowest z, then lowest x, then greatest contact area. |
| Repeat | Regenerate extreme points, prune dominated ones, place the next unit. |
| Keep | The best whole packing under the objective. Ties keep the incumbent. |
The 12 orderings, in the sequence they are tried
- 1
volume-descLargest volume first - 2
longest-edge-descLongest edge first - 3
footprint-descLargest footprint first - 4
height-descTallest first - 5
weight-descHeaviest first - 6
group-clusteredGrouped sets first - 7
surface-area-descLargest surface area first - 8
density-descDensest first - 9
shortest-edge-descThickest first - 10
footprint-then-heightLayer building - 11
weight-then-volumeHeaviest, then largest - 12
volume-ascSmallest volume first
The first 6 run by default. The rest earn their keep on awkward mixes and are reached only when a deeper search is asked for.
Constraints
| A placement is rejected when | Because |
|---|---|
| It leaves the cavity | Padding is already subtracted from every face. |
| It overlaps a placed box | Axis-aligned intersection test. |
| Support is too low | Floor contact, or enough top-face area under it. |
| A box below cannot bear it | Non-stackable, fragile, or over maxStackWeight anywhere down the stack. |
| The carton is over its cap | Contents mass past maxWeight. |
| No pose is allowed | Orientation lock rules out every fitting rotation. |
Anything that cannot be placed anywhere comes back in result.unpacked with a reason, and result.success turns false. The HTTP status stays 200 — the run happened.
Options and plan ceilings
| Name | Type | Req | Description |
|---|---|---|---|
| allowMultipleCartons | boolean | no | Split the order across cartons. Default true. |
| maxCartons | integer 1–200 | no | Cartons for one shipment. Engine default 20; your plan caps it. |
| respectStockOnHand | boolean | no | Honor quantity on hand. Default true. |
| supportThreshold | number 0–1 | no | Base area that must be supported. Default 0.7; 0 disables. |
| keepGroupsTogether | boolean | no | Keep same-groupKey lines in one carton. Default true. |
| strategies | integer 1–12 | no | Orderings to try. More orderings, better packs, more compute. |
| dimWeightDivisor | number 1–100000 | no | Overrides your carrier divisor for this run. |
| Ceiling | Free / Pro |
|---|---|
| Cartons per shipment | 3 / 50 |
| Search strategies | 3 / 10 |
A value above your ceiling is clamped, not rejected — the run succeeds with the plan’s limit applied.
Determinism
| Guarantee | How |
|---|---|
| Same request, same plan | Byte-identical, forever, on any machine. |
| No randomness | No Math.random anywhere in the engine. |
| No clock in scoring | The time budget bounds the search, not the ranking. |
| Stable iteration | Cartons sorted by SKU; no unordered map traversal. |
| Stable ties | An equal score keeps the incumbent, so the earlier ordering wins. |
| Stored verbatim | A job keeps its request and result, so /jobs/:id replays exactly what shipped. |
One field varies between runs: summary.computeMs. Exclude it when you diff two results.
Performance
| Driver | Effect |
|---|---|
| Units in the order | Roughly quadratic — every unit is tried at every live point. |
| Candidate cartons | Linear. Restrict with cartonIds when a bench stocks a subset. |
| Strategies | Linear. Each is a full re-pack under a different ordering. |
| Orientation locks | Fewer poses is faster; identical poses are deduplicated. |
| Flexible cartons | Near free — volume and footprint, not 3D placement. |
| Time budget | 5 seconds server-side. On expiry the best plan found so far is returned, with a warning. |
"summary": { "strategy": "volume-desc", "candidatesEvaluated": 84, "computeMs": 37 }