Go back

Travel pricing is a real-time problem. Fares change by the hour. Hotel rates fluctuate with occupancy. A price shown at 9am may be invalid by 9:05. Any system that caches aggressively will display stale results; any system that fetches live on every query will be too slow to use.

Roavo's pricing engine sits between those two failure modes. The architecture has three layers: a pre-fetched candidate pool, a live validation layer, and a delta reconciliation queue.

The candidate pool runs continuous background queries against our inventory partners, maintaining a rolling 15-minute snapshot of available options for high-demand routes and date windows. This is what we query first when a user searches — it returns in under 200ms.

The live validation layer then fires async requests against the inventory APIs for the top 20 candidates in the candidate pool, confirming current availability and price. Results update in the UI progressively as they return. Users see fast initial results that stabilise within 1.5 to 2 seconds.

The delta queue handles the gap: when the live validation returns a price meaningfully different from the cached candidate, it writes an invalidation event that updates the pool for subsequent queries on the same route. This keeps the pool accurate without requiring a full refresh cycle.

Building this required close work with our data partners on rate limits, retry policies, and error classification. A timeout is different from an inventory unavailability is different from a rate limit response — each requires a different fallback strategy. We spent significant time on the error taxonomy before the system became reliably usable.

The architecture is designed to handle significant query volume from launch. We have modelled capacity to roughly 50x our projected initial load before revisiting the partitioning strategy. We will publish more on the infrastructure stack as we move through beta and beyond.