CINXE.COM

Yelp Engineering and Product Blog

<!DOCTYPE html> <html > <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1"> <title>Yelp Engineering and Product Blog</title> <meta name="description" content="Revenue Automation Series: Building Revenue Data Pipeline Yizheng Zhang, Software Engineer; Yirun Zhou, Software Engineer Feb 19, 2025 Background As Yelp’s business continues to grow, the revenue streams have become..."> <link rel="amphtml" href="https://engineeringblog.yelp.com/amp/" /> <link rel="stylesheet" href="/css/main.css"> <link rel="canonical" href="https://engineeringblog.yelp.com/"> <link rel="alternate" type="application/rss+xml" title="Yelp Engineering and Product Blog" href="https://engineeringblog.yelp.com/feed.xml" /> <script>(function (d, w) { var supportsSVG = ( !!d.createElementNS && !!d.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ).createSVGRect ); var cdnPath = 'https://s3-media0.fl.yelpcdn.com/assets/srv0/svg_icons/6d7801a1d87c/assets/svg_sprite.js'; var head = d.getElementsByTagName('head')[0]; function fallback() { var link = d.createElement('link'); link.rel = 'stylesheet'; link.href = 'https://s3-media0.fl.yelpcdn.com/assets/srv0/svg_icons/336d3e77904c/assets/sprite.css'; head.appendChild(link); } if (!supportsSVG) { fallback(); return; } if (!w.yelp) { w.yelp = {}; } w.yelp.__injectSvgSpritesheet = function (svg) { document.body.insertAdjacentHTML('afterbegin', svg); delete window.yelp.__injectSvgSpritesheet; } function onError() { d.documentElement.className = [ d.documentElement.className, 'icon-svg-unavailable' ].join(' '); fallback(); return true; } var script = d.createElement('script'); script.async = true; script.onerror = onError; script.src = cdnPath + '?callback=window.yelp.__injectSvgSpritesheet'; head.appendChild(script); }(document, window));</script> <noscript> <link rel="stylesheet" href="https://s3-media0.fl.yelpcdn.com/assets/srv0/svg_icons/336d3e77904c/assets/sprite.css"> </noscript> <!-- Load KaTeX Math Rendering. From blog post markdown can use \\( \alpha \\) to render TeX. --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css" integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq" crossorigin="anonymous"> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.js" integrity="sha384-y23I5Q6l+B6vatafAwxRu/0oK/79VlbSz7Q9aiSZUvyWYIYsd+qj+o24G5ZU2zJz" crossorigin="anonymous"></script> <script defer src="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/contrib/auto-render.min.js" integrity="sha384-kWPLUVMOks5AQFrykwIup5lo0m3iMkkHrD0uJ4H5cjeGihAutqP0yW0J6dpFiVkI" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script> </head> <body class="ytype responsive front-page"> <div class="main-header main-content-wrap main-header--slim"> <div class="content-container clearfix"> <div class="arrange arrange--18 arrange--middle"> <div class="arrange_unit"> <h1 class="main-header_logo" id="logo"> <a href="http://yelp.com/engineering">Yelp</a> </h1> </div> <div class="arrange_unit nowrap"> <h2 class="main-header_title"><span>Engineering</span></h2> </div> <div class="arrange_unit arrange_unit--fill"> <div class="main-header_nav nowrap responsive-hidden-small responsive-hidden-medium"> <ul class="header-nav" id="header-nav"> <li class="header-nav_item"> <a class="header-nav_link" href="http://yelp.com/engineering">Home</a> </li> <li class="header-nav_item"> <a class="header-nav_link tabon" href="/">Blog</a> </li> <li class="header-nav_item"> <a class="header-nav_link" href="https://yelp.github.io">Open Source</a> </li> <li class="header-nav_item"> <a class="header-nav_link" href="https://yelp.com/engineering/awe">AWE</a> </li> <li class="header-nav_item"> <a class="header-nav_link" href="https://yelp.com/engineering/whats-it-like">What's it like?</a> </li> </ul> </div> </div> </div> </div> </div> <div class="main-content-wrap--full"> <div class="content-container main-heading"> <h1>Engineering Blog</h1> </div> <div class="content-container"> <div class="posts"> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2025/02/revenue-automation-series-building-revenue-data-pipeline.html">Revenue Automation Series: Building Revenue Data Pipeline</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/darwin.png" alt="Yizheng Zhang, Software Engineer; Yirun Zhou, Software Engineer" class="photo-box-img darwin-image"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Yizheng Zhang, Software Engineer; Yirun Zhou, Software Engineer <br> </li> <li class="post-date"> Feb 19, 2025 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>Background As Yelp’s business continues to grow, the revenue streams have become more complex due to the increased number of transactions, new products and services. These changes over time have challenged the manual processes involved in Revenue Recognition. As described in the first post of the Revenue Automation Series, Yelp invested significant resources in modernizing its Billing System to fulfill the pre-requisite of automating the revenue recognition process. In this blog, we would like to share how we built the Revenue Data Pipeline that facilitates the third party integration with a Revenue Recognition SaaS solution, referred to hereafter as the...</p> <p><a href="/2025/02/revenue-automation-series-building-revenue-data-pipeline.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/revenue-enhancement.webp"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2025/02/search-query-understanding-with-LLMs.html">Search Query Understanding with LLMs: From Ideation to Production</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/darwin.png" alt="Loc Trinh, Software Engineer; Ali Rokni, Tech Lead; John Hawksley, Group Tech Lead" class="photo-box-img darwin-image"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Loc Trinh, Software Engineer; Ali Rokni, Tech Lead; John Hawksley, Group Tech Lead <br> </li> <li class="post-date"> Feb 4, 2025 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>How we bring LLM intelligence to millions of daily searches at Yelp. From the moment a user enters a search query to when we present a list of results, understanding the user’s intent is crucial for meeting their needs. Were they looking for a general category of business for that evening, a particular dish or service, or one specific business nearby? Does the query contain nuanced location or attribute information? Is the query misspelled? Is their phrasing unusual, so that it might not align well with our business data? All of the above questions represent Natural Language Understanding tasks where...</p> <p><a href="/2025/02/search-query-understanding-with-LLMs.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/2025-01-31-search-query-understanding-with-llms.jpg"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2025/01/enhancing-neural-network-training-at-yelp.html">Enhancing Neural Network Training at Yelp: Achieving 1,400x Speedup with WideAndDeep</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/austinzh.jpg" alt="Yunhui Zhang, Software Engineer" class="photo-box-img"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Yunhui Zhang, Software Engineer <br> </li> <li class="post-date"> Jan 22, 2025 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>At Yelp, we encountered challenges that prompted us to enhance the training time of our ad-revenue generating models, which use a Wide and Deep Neural Network architecture for predicting ad click-through rates (pCTR). These models handle large tabular datasets with small parameter spaces, requiring innovative data solutions. This blog post delves into our journey of optimizing training time using TensorFlow and Horovod, along with the development of ArrowStreamServer, our in-house library for low-latency data streaming and serving. Together, these components have allowed us to achieve a 1400x speedup in training for business critical models compared to using a single GPU...</p> <p><a href="/2025/01/enhancing-neural-network-training-at-yelp.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/2025-01-22-enhancing-neural-network-training-at-yelp.jpg"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2024/12/revisiting-compute-scaling.html">Revisiting Compute Scaling</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/darwin.png" alt="Ilkin Mammadzada and Ankit Tripathi, Site Reliability Engineers" class="photo-box-img darwin-image"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Ilkin Mammadzada and Ankit Tripathi, Site Reliability Engineers <br> </li> <li class="post-date"> Dec 13, 2024 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>As mentioned in our earlier blog post Fine-tuning AWS ASGs with Attribute Based Instance Selection, we recently embarked on an exciting journey to enhance our Kubernetes cluster’s node autoscaler infrastructure. In this blog post, we’ll delve into the rationale behind transitioning from our internally developed Clusterman autoscaler to AWS Karpenter. Join us as we explore the reasons for our switch, address the challenges with Clusterman, and embrace the opportunities with Karpenter. Clusterman and its challenges At Yelp, we used Clusterman to handle autoscaling of nodes in Kubernetes clusters. It is an open-source tool we initially designed for Mesos clusters and...</p> <p><a href="/2024/12/revisiting-compute-scaling.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/2024-12-06-revisiting-compute-scaling.jpg"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2024/12/modernization-of-yelp's-legacy-billing-system.html">Revenue Automation Series: Modernizing Yelp's Legacy Billing System</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/darwin.png" alt="Simon Zeng, Payments Tech Lead; Supriya Lal, Commerce Platform Group Tech Lead" class="photo-box-img darwin-image"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Simon Zeng, Payments Tech Lead; Supriya Lal, Commerce Platform Group Tech Lead <br> </li> <li class="post-date"> Dec 6, 2024 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>This blog focuses on how Yelp successfully implemented a multi-year, cross-organizational initiative to modernize its billing processes. The goal was to automate its revenue recognition system by enhancing integration capabilities with third-party financial systems, all while maintaining the accuracy and reliability our users expect. Summary When Yelp first developed its billing system a decade ago, the database design was based on the requirements known at that time. These initial choices laid the foundation for the billing system, upon which multiple Yelp systems and processes were built. However, as the company evolved, it became evident that these design choices were not...</p> <p><a href="/2024/12/modernization-of-yelp's-legacy-billing-system.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/billing_as_foundation.png"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2024/11/loading-data-into-redshift-with-dbt.html">Loading data into Redshift with DBT</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/christoarno.png" alt="Christopher Arnold, Software Engineer" class="photo-box-img"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Christopher Arnold, Software Engineer <br> </li> <li class="post-date"> Nov 6, 2024 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>At Yelp, we embrace innovation and thrive on exploring new possibilities. With our consumers’ ever growing appetite for data, we recently revisited how we could load data into Redshift more efficiently. In this blog post, we explore how DBT can be used seamlessly with Redshift Spectrum to read data from Data Lake into Redshift to significantly reduce runtime, resolve data quality issues, and improve developer productivity. Starting Point Our method of loading batch data into Redshift had been effective for years, but we continually sought improvements. We primarily used Spark jobs to read S3 data and publish it to our...</p> <p><a href="/2024/11/loading-data-into-redshift-with-dbt.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/dbt-redshift-preview.png"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2024/10/how-we-improved-our-android-navigation-performance-by-~30.html">How we improved our Android navigation performance by ~30%</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/paulm.jpg" alt="Paul Martin, Core Android Tech Lead" class="photo-box-img"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Paul Martin, Core Android Tech Lead <br> </li> <li class="post-date"> Oct 8, 2024 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>In 2019, Yelp’s Core Android team led an effort to boost navigation performance in Yelp’s Consumer app. We switched from building screens with multiple separate activities to using fragments inside a single activity. In this blog post, we’ll cover our solution, how we approached the migration and share learnings from along the way as well as performance wins. Where we started circa 2018 Navigating between screens in an Android app is often when the app and device are under the most strain. The new screen and its dependencies are quickly created, which can lead to slow or frozen frames. Prior...</p> <p><a href="/2024/10/how-we-improved-our-android-navigation-performance-by-~30.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/2024-10-08-android-logo.jpg"> </div> </div> </article> <article class="article-excert"> <div class="clearfix layout-block layout-a row--responsive"> <div class="column column-alpha column--responsive"> <h3 class="alternate"><a href="/2024/10/migrating-from-postgres-to-mysql.html">Migrating in-place from PostgreSQL to MySQL</a></h3> <div class="post-info"> <div class="ypassport ypassport-slim media-block"> <div class="media-avatar"> <div class="photo-box pb-30s"> <img src="/images/authors/alext.png" alt="Alex Toumazis, Software Engineer" class="photo-box-img"> </div> </div> <div class="media-story"> <ul class="user-passport-info"> <li class="user-name user-display-name"> Alex Toumazis, Software Engineer <br> </li> <li class="post-date"> Oct 7, 2024 </li> </ul> </div> </div> </div> <div class="post-preview"> <p>The Yelp Reservations service (yelp_res) is the service that powers reservations on Yelp. It was acquired along with Seatme in 2013, and is a Django service and webapp. It powers the reservation backend and logic for Yelp Guest Manager, our iPad app for restaurants, and handles diner and partner flows that create reservations. Along with that, it serves a web UI and backend API for our Yelp Reservations app, which has been superseded by Yelp Guest Manager but is still used by many of our restaurant customers. This service was built using a DB-centric architecture, and uses a “DB sync”...</p> <p><a href="/2024/10/migrating-from-postgres-to-mysql.html">Continue reading</a></p> </div> </div> <div class="column column-beta column--responsive"> <img src="/images/previews/2024-09-27-postgresmysql.jpg"> </div> </div> </article> </div> <div class="pagination-block"> <div class="arrange arrange--stack arrange--baseline arrange--6"> <div class="page-of-pages arrange_unit arrange_unit--fill"> Page 1 of 41 </div> <div class="pagination-links arrange_unit"> <div class="arrange arrange--baseline"> <div class="arrange_unit page-option current"> <span class="pagination-links_anchor"> 1 </span> </div> <div class="arrange_unit page-option"> <a class="available-number pagination-links_anchor" href="/page/2"> 2 </a> </div> <div class="arrange_unit page-option"> <a class="available-number pagination-links_anchor" href="/page/3"> 3 </a> </div> <div class="arrange_unit page-option"> <a class="available-number pagination-links_anchor" href="/page/4"> 4 </a> </div> <div class="arrange_unit page-option"> <a class="available-number pagination-links_anchor" href="/page/5"> 5 </a> </div> <div class="arrange_unit"> <a class="u-decoration-none next pagination-links_anchor" href="/page/2"> <span class="pagination-label responsive-hidden-small">Next</span> <span aria-hidden="true" style="width: 24px; height: 24px;" class="icon icon--24-chevron-right icon--size-24 icon--currentColor"> <svg role="img" class="icon_svg"> <use xlink:href="#24x24_chevron_right" /> </svg> </span> </a> </div> </div> </div> </div> </div> </div> </div> <div class="main-content-wrap main-content-wrap--separated"> <div class="content-container"> <div class="main-footer"> <div class="main-footer_section main-footer_menu clearfix"> <div class="main-footer_item"> <div class="footer-menu"> <h3 class="footer-menu_header">About</h3> <ul class="footer-menu_list"> <li class="footer-menu_item"> <a href="http://yelp.com/about">About Yelp</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/careers?country=US">Careers</a> </li> <li class="footer-menu_item"> <a href="http://www.yelp-press.com/">Press</a> </li> <li class="footer-menu_item"> <a href="http://www.yelp-ir.com/">Investor Relations</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/guidelines">Content Guidelines</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/static?p=tos">Terms of Service</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/tos/privacy_policy">Privacy Policy</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/static?p=thirdpartyterms#adchoices">Ad Privacy Info</a> </li> </ul> </div> </div> <div class="main-footer_item"> <div class="footer-menu"> <h3 class="footer-menu_header">Discover</h3> <ul class="footer-menu_list"> <li class="footer-menu_item"> <a href="http://yelp.com/local_yelp">The Local Yelp</a> </li> <li class="footer-menu_item"> <a href="http://officialblog.yelp.com/">Yelp Blog</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/contact">Contact Yelp</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/faq">FAQ</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/yelpmobile">Yelp Mobile</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/developers">Developers</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/rss">RSS</a> </li> </ul> </div> </div> <div class="main-footer_item"> <div class="footer-menu"> <h3 class="footer-menu_header">Yelp for Business Owners</h3> <ul class="footer-menu_list"> <li class="footer-menu_item"> <a href="https://biz.yelp.com/">Claim your Business Page</a> </li> <li class="footer-menu_item"> <a href="http://yelp.com/advertise">Advertise on Yelp</a> </li> <li class="footer-menu_item"> <a href="https://www.seatme.yelp.com/">Yelp SeatMe</a> </li> <li class="footer-menu_item"> <a href="https://biz.yelp.com/support/case_studies">Business Success Stories</a> </li> <li class="footer-menu_item"> <a href="http://biz.yelp.com/support">Business Support</a> </li> <li class="footer-menu_item"> <a href="https://biz.yelp.com/blog">Yelp Blog for Business Owners</a> </li> </ul> </div> </div> </div> <div class="main-footer_city-landscape-img responsive-hidden-small" role="presentation"></div> <div class="main-footer_copyright"> Copyright &copy; 2004–2025 Yelp </div> </div> </div> </div> <script> (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-30501-54', 'auto'); ga('send', 'pageview'); </script> </body> </html>

Pages: 1 2 3 4 5 6 7 8 9 10