DEV Community

Mark Cohen
Mark Cohen

Posted on Fully Autonomous

Calculating dimensional weight for UPS and FedEx shipments in JavaScript

If you build checkout, fulfillment or label tooling for an e-commerce store, sooner or later someone asks why the shipping quote didn't match the carrier invoice. Nine times out of ten the answer is dimensional (DIM) weight.

Carriers don't just bill by what a box weighs. They bill by the greater of:

  • the actual weight, and
  • the dimensional weight, which is based on the box's size.

Here's how to compute it correctly, and the edge cases that trip up most implementations.

The formula

dim_weight = (length × width × height) / divisor
Enter fullscreen mode Exit fullscreen mode

All dimensions are in inches and the result is in pounds. For most domestic UPS and FedEx daily-rate shipments the divisor is 139. (USPS uses 166, and only for packages over one cubic foot.) Divisors can differ by account and contract, so keep it configurable.

A small, testable implementation

/**
 * Billable weight for a parcel, in whole pounds.
 * @param {object} p
 * @param {number} p.lengthIn  - inches
 * @param {number} p.widthIn   - inches
 * @param {number} p.heightIn  - inches
 * @param {number} p.weightLb  - actual weight in pounds
 * @param {number} [p.divisor=139]
 */
function billableWeight({ lengthIn, widthIn, heightIn, weightLb, divisor = 139 }) {
  // Carriers measure to whole inches, so round each side first.
  const [l, w, h] = [lengthIn, widthIn, heightIn].map(Math.round);
  const dim = (l * w * h) / divisor;

  // Both values round UP to the next whole pound before comparing.
  const dimLb = Math.ceil(dim);
  const actualLb = Math.ceil(weightLb);

  return {
    dimWeightLb: dimLb,
    actualWeightLb: actualLb,
    billableLb: Math.max(dimLb, actualLb),
    billedOnDim: dimLb > actualLb,
  };
}

console.log(billableWeight({ lengthIn: 18, widthIn: 14, heightIn: 12, weightLb: 6 }));
// { dimWeightLb: 22, actualWeightLb: 6, billableLb: 22, billedOnDim: true }

console.log(billableWeight({ lengthIn: 14, widthIn: 12, heightIn: 10, weightLb: 6 }));
// { dimWeightLb: 13, actualWeightLb: 6, billableLb: 13, billedOnDim: true }
Enter fullscreen mode Exit fullscreen mode

Same 6 lb product, two box sizes: 22 lb billed versus 13 lb billed. That gap is real money on every order.

Edge cases worth handling

  1. Rounding order matters. Round each dimension to a whole inch first, then compute, then round the weight up. Doing it in a different order will drift from the invoice by a pound on some packages.
  2. Store the sealed box size, not the product size. Most "my quote was wrong" bugs come from using product dimensions from the catalog instead of the carton actually used.
  3. Insulated and perishable shipments. Foam coolers plus gel packs or dry ice make boxes big and light, so cold-chain shippers are billed on DIM weight almost every time. Flag billedOnDim in your UI so ops teams can see it.
  4. Keep the divisor per carrier and per account. Negotiated contracts sometimes change it.
  5. Carriers re-measure. If your stored dimensions are wrong, the carrier will bill the correction later as an adjustment line, often weeks after the order.

Turning it into a report

A useful thing to give an operations team is a simple monthly report: for each SKU and box combination, how many packages were billed on DIM weight and by how much. Right-sizing the top few boxes is often the cheapest shipping saving a store can make, before even talking about rates.


I work on shipping costs at The Shipping Savers, where we review e-commerce and perishable shippers' UPS and FedEx invoices line by line. If you want the non-code version, we also wrote a guide on how to read a FedEx invoice, including where DIM weight and adjustments show up on the bill.

Top comments (0)