Virtual Packer: How Faire estimates shipping costs at checkout
How Faire combines multimodal machine learning, live carrier rates, and retraining to estimate shipping costs before an order is packed
Virtual Packer: How Faire estimates shipping costs at checkout
Combining multimodal machine learning and live carrier rates to estimate shipping costs before an order is packed

Picture a boutique owner in Austin browsing Faire, our online wholesale marketplace. They have filled a cart with brands that match the boutique’s character — candles, ceramic mugs, and a few sets of greeting cards — and they’re about to check out. Before they place the order, one cost is still unknown: shipping — and it comes straight off their margin.
How much will it cost to ship? It’s an easy question to ask and a deceptively hard one to answer. At the moment of checkout, we don’t yet know — brands ship directly to retailers from their own warehouses. We don’t know which carrier the brand will use, whether they’ll ship ground or overnight, or how they’ll pack the order. The real cost won’t be known for days. Yet the retailer needs a number they can trust right now, since it factors directly into whether the order is worth placing at all.
For a long time, our Applied Science team answered with a natural starting point: a model built on each brand’s past shipping behavior. It was fast and stable, but wrong often enough to matter. So we started from a different question. Rather than look up what similar orders cost in the past, we simulate the order as a physical shipment, predicting what it will weigh and how many packages it will need, then price those virtual packages using live carrier rates.
We call it the Virtual Packer. Today it runs on 80% of eligible orders, with 35% fewer impactful estimation errors than our previous approach — and we built it to stay accurate as carrier prices shift. Here’s how.
Why estimating shipping cost is genuinely hard
From the outside, shipping looks like a lookup problem: weigh the box, check a carrier rate table, done. That intuition holds for a warehouse that controls its own inventory — one that knows the weight and dimensions of every product it ships and packs every order itself. Neither is true for Faire. We’re a marketplace: brands sell on our platform, but fulfill orders from their own warehouses. Here are a few other complicating factors:
- Product weights and dimensions aren’t known cleanly. Brands often leave catalog fields blank or enter inaccurate values. Even when the data is complete, we can’t verify it, because we never physically handle the products. Most weights and dimensions are therefore inferred from catalog data, images, and shipping history. That uncertainty sits at the base of every estimate, and errors there compound through every layer above it.
- Brands control the packing. Every brand decides how to pack its own products. The same order of 50 candles might ship from one brand as two snug packages and from another as five. We don’t see the actual packages until the brand fulfills, yet package count and weight are the biggest drivers of cost, because carriers price on both.
- Brands choose the carrier and service level. Each brand brings its own logistics setup — some ship on Faire’s carrier rates, others use their own carrier agreements. On top of that, service choices vary widely: some brands ship ground by default, others lean on two-day or next day air as expedited options. Two identical carts from two different brands can cost very different amounts to move.
- Carrier rates change constantly. Carriers revise their pricing on a regular cadence, then layer on seasonal surcharges and fuel adjustments throughout the year. An estimate based on last quarter’s rates can quickly become out of date.
- The origin isn’t always known. Many brands operate multiple warehouses, and we don’t know at checkout which one will fulfill the order. A shipment from a warehouse two hundred miles from the retailer costs very differently from one crossing the country — same products, same carrier service, very different price.
Getting the number wrong is costly in both directions. Overestimate, and we add friction at exactly the wrong moment: a retailer who sees a shipping estimate higher than expected may hesitate, trim the cart, or abandon checkout entirely. Underestimate, and we trade a smoother checkout for a worse surprise later — the retailer is quoted one number, sees a higher one at fulfillment, and unintentionally feels misled. The goal is to be accurate enough that a retailer can make a real buying decision without feeling burned either way.
Our first approach was caught in exactly that squeeze. We built a model on each brand’s historical shipping behavior: past shipping costs, typical shipment weights, how shipping cost tended to scale with order value. It had real virtues; it was fast, required no external API calls, and generalized well across brands. But it was blind to the two variables that move cost the most — what a specific order will physically weigh and occupy, and what carriers are charging today.
The evolution toward a Virtual Packer
We didn’t jump straight to simulating shipments. The first instinct, naturally, was to make the historical model better. We added richer brand-level features — longer rolling averages, seasonality signals, order-size buckets, category mix. Each addition bought a small, real improvement, and each one made the ceiling more obvious. No matter how much history we fed in, the model could not answer the question that actually determines cost: what will this order weigh, how many packages will it need, and what will a carrier charge to move it today? History describes the average order. It says nothing about the one in front of us.
Instead of asking “What did similar orders cost in the past?” we started asking “What would this exact order cost to ship right now?”. Answering it requires knowing what the order will look like as a physical shipment before anything has been packed. Virtual Packer builds a synthetic version of the shipment from machine-learning predictions, then prices that synthetic shipment using real carrier rates. The name is literal. We pack the order virtually first so we can quote it for real.
The system works in four layers, each feeding the next:
- Product-level models come first. For every item in the catalog, a multimodal neural network predicts its physical characteristics, including weight and dimensions, from product attributes, category, and shipping history. A neural network lets us draw on product images and descriptions alongside structured catalog signals — the visual and textual cues that often carry the clearest indication of what something weighs. A 12-ounce soy candle, a stoneware mug, a flat box of letterpress cards: each gets a predicted weight and a predicted size. These per-item predictions are the atoms everything downstream is built from.

Product-level multimodal neural network: vision, text, and tabular inputs → per-modality attention gates → fused layers → predicted weight
- Order-level models assemble the shipment. The next layer aggregates those item predictions into a picture of the whole order: total weight, total volume, and — crucially — the number of parcels the brand is likely to use. These are separate gradient-boosted trees (XGBoost), one per output, each taking the per-item weight and dimension predictions from Layer 1 as inputs. We’re not just summing weights; we’re estimating how items get grouped into packages, because a 40-pound order in one parcel prices very differently from the same 40 pounds split across three. The output is a synthetic shipment: a concrete set of predicted packages, each with a weight and dimensions.
- Live carrier rates turn the shipment into a price. We send those predicted packages to EasyPost, a carrier rate API, which returns real-time quotes from carriers for the specific origin-to-destination route. This is the step a brand-history model can never replicate: instead of guessing from the past, we get the same kind of live quote a shipper would see handing a package across the counter — for this order, on today’s rate cards, between these two locations.
- A final model reconciles the estimate. Live quotes are necessary but not sufficient. They assume our virtual packing matches reality, which it never does perfectly. So a final model — gradient-boosted trees, using XGBoost — takes the live carrier quotes alongside brand-level context and order features, and outputs the number the retailer actually sees. The live rates do the heavy lifting; the model learns and corrects for the systematic ways real fulfillment diverges from our simulation — a brand that consistently uses one more package than we predict, say, or one whose real rates run higher than EasyPost’s quotes.

Virtual Packer’s four-layer pipeline: per-item predictions → virtual packing → live carrier rates → final estimate
Two things made us comfortable putting this in front of retailers. The first was disciplined engineering around a tradeoff we accepted: every Virtual Packer estimate now depends on a real-time carrier API call in the critical path of checkout — latency we’d rather not spend, and a dependency on an external service. So we built around it carefully with tight timeouts, caching where rates are stable, and a graceful fallback to the historical model if a live quote doesn’t return in time.
The second was evidence. Before the Virtual Packer served a single live estimate, we ran it in shadow mode, generating predictions in parallel with the production system, on real traffic, without showing them to anyone. That let us compare both models against actual shipping costs once orders were fulfilled with zero risk to the checkout experience. The verdict was clear: the Virtual Packer cut the rate of estimates large enough to negatively impact the retailer experience by 35% relative to our brand-history model.
Extending coverage to multi-brand orders
A more accurate model only helps the orders it actually runs on, and at first the Virtual Packer didn’t run on all of them. We launched it for single-brand orders — the common case, and the simplest one, because there’s exactly one brand to pack virtually and one carrier quote to fetch. But retailers often buy from multiple brands in a single session, and those multi-brand carts are some of our most valuable orders. Each brand in them ships independently.
Looping over brands sequentially would be too slow — stacking several carrier API calls blows the latency budget and leaves the retailer watching a spinner. So instead we fan it out: the rate lookups for every brand run concurrently, and we assemble the per-brand results into a single order estimate once they return. A five-brand cart resolves in roughly the time of a one-brand cart, because the slowest carrier call — not the sum of all of them — sets the pace. That one change moved Virtual Packer coverage from half of eligible orders to 80%.
Keeping the model fresh
The Virtual Packer’s biggest strength is that it prices on live carrier rates — but staying accurate over time is a harder problem, and it’s one the final model is especially exposed to. The brand-history model eventually caught up to rate changes, but with a lag: price shifts took weeks or months to show up meaningfully in the training signal. The Virtual Packer’s final model drifts faster — because it was trained on historical carrier rate levels, its accuracy depends directly on its training data reflecting what carriers charge now. Let it sit untouched for a few months and the gap between what it learned and what carriers actually charge widens. For this model, freshness is a core requirement.
Early on, keeping the model fresh was a manual ritual. A data scientist would pull a fresh training set, run the training pipeline, review the results, prepare a model deployment, and coordinate the release with engineering. Each cycle took days of focused work across two roles, so it happened only every several months. Between refreshes, the model spent most of its life a little out of date.
To fix this, we’ve automated the whole loop. A scheduled pipeline now runs the full retrain end to end: it pulls fresh training data, trains a new candidate model, and evaluates that candidate head-to-head against the version currently in production on a held-out set. Crucially, it only promotes the new model if it clears the bar: if the candidate measurably beats the incumbent, the pipeline stages it for release. If not, the live model stays put. The one human step left is a quick review of the candidate’s results before we flip the switch. What used to take days of hands-on work now takes a few hours of review — and we retrain on a cadence of weeks instead of months.

The automated retraining loop: fresh data → train → evaluate → promote or reject
What’s next
We started with a model built on brand shipping history and ended with a system that constructs a virtual shipment for most orders, prices it with live carrier rates, and keeps itself current automatically. Along the way, impactful estimation errors dropped by 35%, coverage grew from half of eligible orders to 80%, and a retrain that once consumed days of manual effort now runs largely on its own.

Impactful shipping cost estimation errors over time — three engineering milestones, each leaving a visible mark on the curve
None of it was solved by a single clever model. The accuracy gain came from reframing the question, the reach came from unglamorous latency engineering, and the durability came from treating model freshness as a first-class requirement.
Next, we plan to extend Virtual Packer in three directions:
- A unified model for order assembly. The order-level models today are separate gradient-boosted trees that take the weight and dimension outputs from the product neural network — a clean handoff, but a lossy one. The neural network learned a richer internal representation of each product than two numbers can carry. We want to stop discarding what Layer 1 worked hard to learn. The upgrade we’re working on: a single multi-head neural network at the order level that consumes product embeddings directly and jointly predicts weight, volume, and parcel count, with predictions that share structure rather than being learned in isolation.
- Freshness for the full stack. Automated retraining covers the final Virtual Packer model today, but that model sits on top of the product- and order-level models that predict weights, dimensions, and parcel counts. Those upstream models drift too, as the catalog grows and brands’ packing habits evolve. Freshness for the final model is solved — but the product- and order-level models beneath it aren’t yet on the same pipeline. Pulling them in closes the loop: the entire stack refreshes on a regular cadence, not just the top.
- International orders. The Virtual Packer’s architecture was designed to be carrier-agnostic — which means extending it outside North America is less a redesign than a carrier coverage problem. The carrier landscape is more fragmented there and rate behavior more varied, but the same pipeline applies. Getting coverage and accuracy right across international markets, without rebuilding what we have, is where we’re headed.
A theme connects these: the architecture is deliberately modular. Each layer can be improved or retrained on its own, and the system doesn’t much care whether a given layer is gradient-boosted trees today or a neural network tomorrow. That separation is what lets us keep raising the ceiling without rewriting the whole stack.
And it all adds up to something bigger for our customers. Accurate estimates are the foundation, but Faire’s shipping work doesn’t stop there. Through Ship with Faire, we negotiate the carrier rates directly — which means lower shipping costs for retailers, and more accurate estimates too, because we’re predicting costs on rates we already know. As we build out fulfillment from Faire’s warehouse, bundling orders makes shipping more efficient for retailers and feeds richer data back into the models. Taken together, it’s about giving independent retailers the same shipping advantages that large retailers take for granted.
None of this was one person’s work — it took scientists, engineers, and product thinkers pulling in the same direction. This would not have been possible without the contributions of Ben Klassen, Helen Gu, Kindeep Kargil, Luke Ning, Ricardo Oda, Sai Pradeep, and Vasilis Papanikolaou.
If you want to do the science, build the systems, and own the outcomes — we’re hiring. Come build with us at faire.com/careers.
메타데이터
- post_id
- a17509fac73d
- slug
- virtual-packer-how-faire-estimates-shipping-costs-at-checkout-a17509fac73d
- url
- https://craft.faire.com/virtual-packer-how-faire-estimates-shipping-costs-at-checkout-a17509fac73d
- canonical_url
- https://craft.faire.com/virtual-packer-how-faire-estimates-shipping-costs-at-checkout-a17509fac73d
- author_url
- https://medium.com/@guptakhil
- status
- ok
- fetched_at
- 2026-08-01 02:36:35