How Vahak Onboarded 800K Trucks Without Breaking the Marketplace
For: A COO or CTO at a mid-size freight brokerage or transport aggregator who is 6–12 months into building a two-sided marketplace and watching supply-side onboarding numbers climb while match rates stay stubbornly low and empty-mile costs refuse to move
Vahak scaled past 800,000 trucks on a two-sided freight marketplace without match quality collapsing under supply-side growth. The unlock wasn't better onboarding forms or more KYC fields — it was rebuilding the matching engine to learn from post-onboarding behavior (response latency, partial accepts, lane repetition) instead of relying on the sparse, inconsistent data drivers actually enter at signup. If you are running a freight aggregator where the dashboard shows growth but empty-mile costs won't budge, the fix is probably not more data collection. It is a different model target.
This is the engineering walkthrough of how that got built — what broke first, what the team tried before it worked, and which architectural calls generalize to any two-sided logistics marketplace.
The problem the team walked into
Vahak is an India-based freight and trucking marketplace connecting truck owners, transporters, and shippers. The core promise is simple: a load posted in Nagpur should find the right truck fast, at a fair rate, with minimal empty return.
When the platform was still under a few hundred thousand trucks, matching was tractable. Filters, geography, truck type, and a ranked list did most of the work. As supply grew, three things happened simultaneously:
- The number of eligible trucks per load exploded, so ranking mattered more than filtering.
- Data entered at onboarding — truck type, home lane, preferred routes — turned out to be wrong or stale for a large chunk of the base. Drivers picked whatever was closest in the dropdown.
- Shippers posted loads with under-specified requirements (weight rounded to the nearest ton, pickup times as "today"), which made it hard to score fit.
The visible symptom was a low load-to-truck conversion rate despite supply looking healthy on every dashboard. The invisible symptom was worse: the ML team couldn't train a useful ranking model because the labels — did this truck actually take this load? — were noisy, and the features were sparser than the feature list suggested.
This is the classic freight marketplace cold start problem. It looks like a data volume problem. It is actually a data quality and signal design problem.
What the team tried first (and why it didn't work)
Attempt 1: Fix onboarding
The first instinct — the one every team has — was to fix the input. Add more fields. Make truck type mandatory with photo verification. Add preferred lanes as multi-select. Ask for typical rate expectations.
Two things went wrong:
- Onboarding drop-off spiked. Every additional required field cost conversion. Truck owners onboard on a phone, often mid-shift, often with patchy connectivity. A ten-field form is a fifteen-field form is a form nobody finishes.
- The data got cleaner but didn't get truer. A verified photo of a truck doesn't tell you whether that driver actually prefers Nagpur–Hyderabad or just happened to run it once. Stated preference and revealed preference diverged badly.
Match rates moved by a small amount. Not enough to justify the funnel damage.
Attempt 2: Heavier ranking features from the same data
Next, the team tried to squeeze more from what they had — feature crosses, embeddings on truck-type and lane pairs, a gradient-boosted ranker on top. The model was better than the rule-based ranker on offline metrics but barely moved online conversion. The reason, in retrospect, was straightforward: the ground-truth labels the model was trained on were themselves generated by the old ranker's exposure bias. The model learned to reproduce the existing behavior slightly more efficiently. It did not learn what a good match actually looked like.
Attempt 3: Ask shippers to be more specific
Same idea, other side of the market. Force shippers to specify pickup windows in hours, exact weight, load type from a controlled vocabulary. Same result. Posting volume dropped. The shippers who complied were the ones who were already sophisticated. The long tail — the actual growth market — got worse.
Three attempts in, the team had a clearer read on the actual problem: onboarding data will always be sparse and noisy on both sides of a freight marketplace, and no amount of form redesign changes that. The model needed a different input.
The architectural call that unlocked it
The reframe was this: instead of treating the matching engine as a function of what users declared at signup, treat it as a function of what users did after signup. Behavioral signals accumulate passively. They don't require the driver to fill out anything. And they are honest — a driver who has accepted three Nagpur–Hyderabad loads has revealed something about their preference that no dropdown can capture.
Concretely, the matching layer was restructured around three categories of signal:
1. Response latency as a preference signal
How quickly a truck owner opens, views, or responds to a load notification is a strong indicator of fit. A driver who consistently opens loads on a specific lane within thirty seconds — even if they don't always accept — is telling you that lane matters to them. A driver who ignores a load for two hours before rejecting is telling you the opposite, regardless of what their profile says.
Latency is a passive signal. It costs the user nothing. It is available from day one of activity.
2. Partial-accept and negotiation patterns
In freight, most matches are not one-click. There is a back-and-forth: rate negotiation, pickup time adjustment, sometimes truck substitution. The pattern of that negotiation contains more information than the final outcome. A truck owner who counters on rate but never on lane is a rate-sensitive supplier on that lane. A driver who accepts quickly at posted rate on some lanes and negotiates hard on others is telling you where their real preference sits.
The team started logging every negotiation event, not just the terminal state, and feeding sequence features into the ranker.
3. Lane repetition and time-of-day cycles
Truck movement has structure. Drivers work loops, not random walks. A truck that ran Raipur–Bhilai twice this week is very likely to run it again next week. A driver who takes loads only between 6 AM and noon is a different supplier than one who runs overnight. These patterns are invisible on the onboarding form and obvious in the event log.
Rolling features — 7-day lane frequency, time-of-day histogram, seasonality on specific corridors — replaced the static "preferred lanes" field as the primary matching input.
The system change underneath
None of this works without event infrastructure that can keep up. The architectural changes that made it possible:
- An event bus as the source of truth for behavior. Every load view, notification open, negotiation message, and accept/reject became an event with consistent schema. The profile database stopped being the primary input to matching. The event stream did.
- A feature store for rolling behavioral aggregates. Lane frequency over 7/30/90 days, response latency percentiles, negotiation win rates — computed once, served to the ranker at request time. This is unglamorous plumbing and it was the single biggest lift.
- A two-stage ranker. A cheap candidate generator narrows tens of thousands of trucks to a few hundred using coarse filters (geography, truck class, active-in-last-N-days). A heavier model ranks those on behavioral fit. This kept latency acceptable as supply grew.
- Exposure-aware training. To avoid the feedback loop the earlier ranker suffered from, the training pipeline was reweighted to account for which trucks got shown in the first place. This is standard in mature ranking systems and often skipped in early marketplace builds.
What moved
The honest version: this was not a single-launch win. It was a sequence of shipped changes over many months, each moving conversion by a few percentage points. What generalizes is the direction, not the specific deltas.
Directionally, the wins were:
- Match relevance went up without changing onboarding. The model got smarter as users used the app. New drivers benefited from a warm start based on drivers with similar early behavior, not similar declared profiles.
- Empty-mile ratio improved on repeat lanes. Once the system knew a truck ran a loop, return-leg suggestions could be pushed before the driver finished the forward leg.
- Notification acceptance rates rose. Fewer, more relevant notifications beat more, generic ones. Driver churn on notification fatigue dropped.
- The supply side scaled without match quality degrading. This is the key one. When you add more supply to a naive matching system, quality goes down because ranking gets harder. With behavioral matching, more supply means more signal per lane, so quality goes up.
You can read more of the engagement context on the Vahak case study.
What this approach is bad at
Being honest about tradeoffs, because senior readers can smell hand-waving:
- True cold start on brand-new lanes is still hard. Behavioral matching depends on behavior existing. Open a new corridor with no history and you are back to filter-based matching until signal accumulates. There is no magic here.
- It is unforgiving of event log gaps. If your notification delivery is flaky or your app has offline modes that don't sync events reliably, your model learns from a distorted view of reality. Event infrastructure quality becomes a matching quality problem.
- Explainability drops. A rule-based match can be explained to a driver ("we showed you this because it matches your truck type"). A behavioral ranker is harder to justify in support conversations. This matters more than engineering teams initially think.
- It requires discipline about privacy and fairness. Behavioral signals can encode bias — for instance, if certain regions have historically had worse notification delivery, the model learns those drivers are "less responsive." Auditing for this is ongoing work, not a one-time review.
Lessons that generalize to any two-sided logistics marketplace
If you are 6–12 months into building a freight aggregator, a last-mile network, a container matching platform, or any other two-sided logistics marketplace, the transferable lessons:
1. Onboarding data is a floor, not a ceiling
Collect enough at onboarding to filter (truck type, geography, basic KYC) and stop. Do not try to collect enough to rank. Ranking data comes from usage.
2. Design the event schema before you design the model
The single biggest predictor of whether a marketplace can improve its matching over time is whether it has clean, consistent, complete event logs. If your events are inconsistent across app versions, or if key negotiation steps happen off-platform (WhatsApp, phone calls), your model ceiling is low no matter how good your ML team is. Fix instrumentation first.
3. Latency and non-action are signals
Most teams log accepts and rejects. Fewer log views. Almost none log "notification delivered, opened after 47 minutes, not acted on." That last one is often the most informative event you have. Log the non-events.
4. Solve the feedback loop early
If your ranker decides who sees what, and your training data is who accepted what, you have a feedback loop. Small early biases compound into permanent ones. Bake exposure correction into the training pipeline from the start. Retrofitting it later is painful.
5. The cold-start problem is a signal design problem, not a data volume problem
This is the frame shift. You do not solve freight marketplace cold start by gathering more data upfront. You solve it by designing the model target so that useful signal accumulates from the first user session and compounds thereafter.
How CodeNicely can help
The Vahak build is the most direct reference point if you are running a freight or transport marketplace and hitting the wall we described. The engagement covered the event infrastructure, feature store, and ranking architecture that made behavioral matching possible at scale — not a template solution, but the specific engineering calls that a marketplace at that stage needs to make.
If your situation is closer to "we have supply and demand on the platform but the matching engine is guessing," the useful conversation is about what your event logs actually contain, where the gaps are, and what the shortest path is to a ranker that improves with usage. That is the work we did on Vahak, and the same pattern applies to last-mile networks, equipment rental marketplaces, and B2B logistics aggregators. See our AI Studio for how we structure this kind of engagement.
Frequently Asked Questions
How much onboarding data do I actually need to launch a freight marketplace?
Enough to filter, not enough to rank. That usually means truck type, home region, basic KYC, and contact preferences on the supply side; origin, destination, weight range, and truck class on the demand side. Anything beyond that is better collected passively through usage. Adding fields past this floor almost always costs more in onboarding drop-off than it gains in match quality.
What is the freight marketplace cold-start problem and how is it different from other marketplaces?
Cold start in freight is unusual because both sides of the market have sparse, inconsistent onboarding data — drivers pick nearest dropdowns, shippers under-specify loads — and because match quality directly affects unit economics through empty miles. Unlike ride-sharing, where geography does most of the matching, freight requires fit on truck type, rate, timing, and lane preference simultaneously. The solvable version of the problem is designing the ranker to learn from behavioral signals that accumulate after signup, not from what users declared at onboarding.
What behavioral signals matter most for a truck load matching algorithm?
Three categories dominate: response latency (how fast a truck owner engages with a notification), negotiation patterns (what they counter on and what they accept as-is), and lane repetition (which corridors and times of day they actually run). These are honest signals — they reveal preference rather than state it — and they are available passively without asking the driver for more input.
How do I know if my event logging is good enough to support behavioral matching?
Two tests. First: can you reconstruct a user's full session — every load viewed, every notification opened, every message in a negotiation — from your event log alone? Second: are your event schemas consistent across app versions and platforms? If either answer is no, fix instrumentation before touching the ranker. Model quality is capped by event quality.
How long does it take and what does it cost to build something like this?
That depends heavily on your current event infrastructure, team, and starting point — a marketplace with clean instrumentation is in a very different place than one that needs logging rebuilt first. Contact CodeNicely for a personalized assessment based on where your platform actually is today.
The takeaway
The marketplace that scales is not the one that collects the most onboarding data. It is the one that designs its matching model so that every user session, every notification, every negotiation makes the model slightly smarter — without ever asking the user for more. If your dashboards show growing supply and flat match rates, the answer is almost certainly not another onboarding field. It is a different way of listening to the users you already have.
Building something in Logistics & Supply Chain?
CodeNicely partners with founders and tech teams to ship AI-native products that move metrics. Tell us about the problem you're solving.
Talk to our team_1751731246795-BygAaJJK.png)