Formatted Translations
We take the listing of each booking request and fetch the city and country from the listing service and check to see if that destination was in our curated set of formatted destinations loaded into our i18n service. We then take the best fitting artwork and embed the localized destination text on it to generate the final postcard. If we don’t get a translation back, we fall back to serving the postcard without text.
Performance — Async Postcard Creation Flow
Putting a localized destination and a Belo icon onto artwork is a time-consuming operation given the high resolution artwork we used. We knew the image processing flow could take over 8 seconds on average to process an image so we needed to come up with a way to make our postcard API respond quickly. We also wanted to transfer these generated postcards into our primary image storage so we could leverage our existing media serving infrastructure, which introduced an additional 1–2 seconds of latency.
In order to still be performant, we went with a partly asynchronous approach where, during the live in product request, we only serve postcards that we’ve already generated and stored internally. If there was a request for a new postcard, we would instead return a fallback postcard and publish an event to a Kafka queue where an async consumer would call the processing service, wait for the asset to be generated and then transfer it into our system to be used for future requests.
As shown in the diagram below, we fetched the listing information and taxonomy information in parallel before computing the best matching artwork for the trip. Based on a pattern in how the postcards are stored, we would check in our media service to see if the postcard was generated already before either returning the card if it was found or kicking off the asynchronous flow if it was not found. At that point, our media service’s Kafka consumer would complete the flow by transforming the asset into a postcard and storing it in our system.
Pre-generation
We wanted to generate as many of the postcards as possible before the launch. If the postcard hasn’t been generated when a guest books a group trip, everyone on the booking will see the default, generic postcard. Our data science team helped determine top destinations, and we ran those inputs through our postcard generation pipeline to pre-generate as many postcards as possible and minimize the chance of falling back to a default postcard. Within a week of launching, more than 90% of trips had a custom postcard instead of a default and we inched closer to generating a postcard for all trips in the months after.
Creating postcards was a massive effort that required collaboration across multiple engineering, product, design, and data science teams to improve Airbnb’s group travel feature. Our frontline insights team continues to receive positive social media and external feedback on this update that adds delight to joining a group trip.
The solution highlights the importance of having the right internal tooling, image and text processing capabilities, and destination matching logic for solving something at Airbnb’s scale.
Postcards is one of the first major image processing use cases that the Media team built to support a new Airbnb feature. It highlights the power of media capabilities and innovative features we can build with them. If you like the type of work we do at Airbnb, please contact us & check out our careers page!
Thanks to the following engineers who helped to build this feature: Alan Wright, Aditya Punjani, Bill Lovotti, Jessica Chen, Miguel Jimenez