Marketplace · partner operations

KAYAK · 2023–Present · Partner placement tooling

Bulk operations for a 1M-combination problem

KAYAK's business travel marketplace runs on partners buying placement. The tooling behind it was built for one decision at a time, and partners were configuring campaigns one route at a time while a manual review queue sat in the middle. I rebuilt it around bulk operations and model-driven guidance, and took the human approval step out of the loop entirely.

Role
Product Designer · owned the partner tooling surface end to end
Team
Product, engineering, ML, partner operations
Timeline
2023–Present
Scope
Approval flow, bulk configuration, bid guidance, experimentation

The bottleneck

A human in the middle of every placement

Partners on KAYAK's business travel marketplace buy placement against routes. To change what they were buying, a partner submitted a request, and then waited, because every request landed in a manual review queue before anything went live.

The queue was doing real work: catching malformed bids, checking eligibility, preventing partners from buying things that didn't make sense. But it was doing that work serially, by hand, on roughly 1,500 requests a year, and the cost was paid entirely in partner waiting time. Every day a request sat in review was a day a partner wasn't spending.

The obvious fix was to make the review faster. I argued for removing it. A queue that exists to catch invalid configurations is a queue that exists because the system permits invalid configurations in the first place.

Mock to add

The old approval flow, annotated

Submit → queue → manual review → live. Mark where the wait accumulates, and roughly how long each hop took. Redraw it rather than screenshotting partner-facing UI.

Where the elapsed time actually went.

Removing the review

Moving validation into the flow itself

The redesign moved the validation from a person at the end to the structure of the flow itself. Partners select targeted routes inside a model that can't express an invalid state, so there's nothing left for a reviewer to catch. This is the bidless targeted-routes flow, where the constraint lives in the interface rather than in a downstream human.

The result was 1.29 days returned per request. It exceeded the KPI set for the project, and the number that actually matters is what that compounds to.

Finish the arithmetic. The per-request measurement is KAYAK's. The annualisation is just multiplication on it, and it's the difference between a metric that sounds small and one that sounds like a business case.

What this cost

Deleting a review step means deleting the place where a human would have caught the thing the system didn't anticipate. That's a real trade, and it only works if the constraint model is genuinely complete. The honest version is that we moved risk from "caught late by a person" to "prevented early by a structure", which is better when the structure is right and worse when it isn't.

Bulk at scale

Targeted Routes V2.0

Removing the wait exposed the next problem: the flow was still one-at-a-time. A partner operating across a real route network was configuring placements individually, which meant the tooling scaled linearly with a business that didn't.

V2.0 restructured it around bulk operations: 500 placements per workflow, 1M+ combinations per request. The interaction problem there isn't the volume, it's comprehension at volume: at a million combinations nobody can review a list, so the design has to let someone specify intent, see the shape of what that produces, and catch the case where the shape is wrong before committing.

That's a fundamentally different design problem from anything else in this portfolio. There's no conversation, no model output, no ambiguity to resolve. There's a dense operational surface where the user is an expert, the stakes are financial, and the failure mode is a confident bulk action against the wrong set.

Nobody reviews a million rows. Six orders of magnitude between what a partner touches and what the system resolves is why this couldn't be a longer list. The design had to show the shape of an action instead of its contents.

Mock to add

The bulk configuration surface

The moment a partner specifies intent and sees the resulting set before committing, ideally with the preview/confirm state visible, since that's the safeguard the whole design rests on.

Model output as a decision

Optimizations

Partnering with ML engineering, I designed Optimizations, a bid-guidance surface that turns model output into something a partner can act on. The model produces a recommendation; the surface lets a partner model and compare the incremental impact of an operational change before committing spend.

The design principle is the same one that runs through the AI chat work, arrived at from the opposite direction: the system shouldn't assert an outcome it can't guarantee. A recommendation presented as a number reads as a promise. The same recommendation presented as a comparison between scenarios reads as what it is: guidance the partner is still deciding against.

Mock to add

Optimizations, the comparison state

Two scenarios side by side with the incremental delta between them, before commit. The argument is that the model's output is framed as a comparison, not a promised number, so the frame has to be visible.

The model recommends. The partner decides. The same containment idea as keeping prices out of the chat: don't let the system state an outcome it can't stand behind.

The thing nobody asked for

An internal A/B testing platform

Reading experiment results at KAYAK meant going through an analyst. That was a bottleneck of exactly the same shape as the approval queue: a person in the middle of a loop that should have been self-serve, and it was slowing down every team, not just mine.

Nobody assigned this. I designed KAYAK's internal A/B testing platform so PMs and engineers could read experiment results directly, removing the analyst dependency from the iteration loop. It's the piece of work I point to when someone asks what I do that isn't in the brief.

What it returned

Time back to the people spending money

~1,900
Partner-days returned per year by the bidless flow
1M+
Combinations handled per bulk request
500
Placements configurable in a single workflow

Derived figures: 1.29 days returned per request × ~1,500 requests a year. The per-request measurement is KAYAK's; the annualisation is arithmetic on it.