Why Using a Single Programming Language Makes NextRoll's Cookieless Bidding System Better


Designing and building a groundbreaking system from scratch is always exciting and a little scary. As a team, engineers face many decisions that are meant to shape the challenges and opportunities that current and future contributors will handle as well. Choosing a language is one of those critical decisions.

At NextRoll, we made a significant investment in Rust for our infrastructure rebuild, and we are already starting to witness the positive results in terms of team efficiency and maintainability.

Our primary motivation for transitioning to Rust stemmed from our pursuit of enhanced performance. With the imminent demise of third-party cookies, we anticipated a surge in the volume of requests our bidding system would need to handle. Rust's efficiency and speed were paramount considerations, as we aimed to manage this anticipated influx without incurring substantial increases in infrastructure costs. 

It's well-known that switching between languages on a daily basis can be mentally taxing, both for the original authors and for those reviewing the code. Such transitions can make us more error-prone and cause us to spend more time than usual on tasks.

One specific challenge that significantly hampers our development and maintenance endeavors is a highly complex system that relies on three distinct languages interacting with each other. The complexity primarily arises from this intricate language integration. Debugging, testing, and comprehending such a system pose formidable challenges, leading to a high likelihood of errors.

By adopting Rust as our primary language, we've gained the ability to write any piece of code needed by our system while leveraging existing logic, with testing suites that can run seamlessly across entire workflows. This capability is particularly valuable in a complex solution like the Privacy Sandbox’s PAAPI (Protected Audiences API), where multiple components interact harmoniously. One standout example is how Rust empowers our in-browser bidding logic. 

Using Rust compiled to WebAssembly (WASM) in our in-browser bidding logic instead of JavaScript allows us to share code between the bidding logic and other pieces of the system, creating a seamless integration that offers several significant advantages:

  • Code reusability: By writing core functionality in Rust, we can reuse the same codebase across multiple platforms and environments. This means that algorithms, data structures, and business logic implemented in Rust for the bidding logic can also be utilized in server-side components.

  • Consistent behavior: Sharing code between all parts of the system ensures consistent behavior across all pieces, avoiding bugs introduced by translating logic to different languages.

  • Reduced maintenance overhead: With code shared between WASM and server-side components, maintenance becomes more streamlined. Updates, bug fixes and optimizations applied to the codebase automatically propagate across the entire system, eliminating the need for redundant changes and reducing the risk of inconsistencies.

  • Improved collaboration: Shared code promotes collaboration among developers working on different parts of the system. Teams can focus on refining and enhancing functionality within their respective domains, with the benefit of being able to see how they affect other parts of the system, functioning as an immediate knowledge-sharing tool.

  • Enhanced testing: Test suites written in Rust can validate functionality across the whole system, ensuring comprehensive coverage and faster identification of issues.

Our adoption of Rust for our PAAPI solution has been transformative. It has not only improved our technical capabilities, but has also fostered a more collaborative and efficient development environment. As we continue to explore the full potential of Rust within our organization, we look forward to further innovations and improvements in our projects.

Pablo López Viqueira is a Staff Software Engineer for NextRoll.