Overview
Executive summary
The OTA merchandised fixed flight-and-hotel packages assembled offline — slow to refresh, weak on experience attach, and blind to origin-specific demand. Search results showed the same bundles to every traveler regardless of lead time, party size, or historical attach behavior.
We shipped a dynamic packaging platform: graph-based composition across live inventory, EBV-ranked bundles with learning-to-rank, demand-aware pricing bands, and a sub-120 ms serving path — so merchandising can pin campaigns without giving up real-time optimization.
Challenge
Business problems and how we solved them
1Static packages with stale inventory
Pre-built bundles sat in CMS for weeks — price drift and sold-out hotels eroded trust and conversion.
Technique · Live inventory federation + Redis snapshots + compose-on-search.
Solution · Adapters pull GDS, bedbank, and tours APIs every 5–15 minutes; composer builds feasible bundles at query time with sold-out pruning.
2Low flight+stay+experience attach
Fewer than 12% of flight bookings added a tour or transfer — high-margin experiences under-merchandised.
Technique · EBV model with attach history + LTR diversity for experiences.
Solution · LightGBM predicts bundle booking probability and margin; ranker boosts feasible experience legs when attach propensity exceeds threshold.
3One-size-fits-all search rankings
Same bundle order for all origins — Dubai weekend deals ranked equally for London and Singapore departures.
Technique · Origin-aware features + demand elasticity pricing.
Solution · 34-feature EBV includes origin market, seasonality, and device; price bands adjust ±8% by load factor without breaking display rules.
4Compose latency blocked real-time UX
Legacy combinatorial search timed out above 400 ms — product limited bundles to top 20 routes only.
Technique · Graph pruning + OR-Tools feasibility + warm caches.
Solution · Solver caps expansion at 80 candidates in 40 ms; top 50 origin–destination pairs pre-warmed; p95 serve under 120 ms globally.
System design
Architecture diagrams
Bundle pipeline, multi-component composition, EBV scoring, and the OTA services that power real-time dynamic packaging.
Search → compose → score → rank → serve, with a feedback loop from clickstream events.
Flight, hotel, and experience suppliers merged into one bookable package.
Traveler and inventory features → LightGBM EBV → LTR-ranked bundle list.
Storefront, bundle API, composer, ranker, inventory cache, and Kafka events.
Engineering
Inventory, composition, and MLOps
Inventory federation
Normalized adapters for GDS flights, bedbank hotels, and experience suppliers — snapshot to Redis with TTL aligned to supplier refresh windows.
- gds_flights
- bedbank_hotels
- tours_api
Composition engine
Directed graph expands candidate legs; OR-Tools prunes infeasible combos before EBV scoring.
Max candidates
80
Solver timeout
40 ms
Min margin
12%
Max layover
6 h
Serving path
FastAPI async handlers; pre-warmed composer pools; CDN-cached static bundle shells for top routes.
- dxb_weekend
- bkk_beach
- par_citybreak
Experimentation
RPV and attach-rate gates on every model promote; shadow traffic on new rankers before full rollout.
- 5%
- 25%
- 100%





