Case study – Upply: The PHP advantage: How we resisted the switch to Scala, rust, or go

After a pause, we’re excited to relaunch the publication of case studies in the Symfony community. Whether you’ve tackled challenging upgrades, solved complex technical issues, or transformed your team’s workflows, we want to hear from you! Share your experience and inspire others by reaching out to us at [email protected]

Let’s begin with a quick introduction: I’m Florent Laval, Chief Technical and Data Officer at Upply: the Tech platform striving to revolutionize freight transportation. I joined the company in 2017 as a Data Scientist and gradually transitioned to managing both data and IT teams by 2022.

This article is about the tough choice we faced in 2022, when we re-opened the discussion around changing the main back-end language we had been using since Upply’s inception: PHP — and why we ultimately decided to keep it. We won’t dive too much into the technical specifics of the language itself, as the principles we discuss can apply to any language decision.

Marketplace Challenges in a Fast-Evolving Environment

At Upply, we drive the digitalization of the supply chain by offering accessible, high-performance, and sustainable solutions. Our goal is to help users make smarter decisions, industrialize and optimize their freight shipments.

Smart: a machine learning-powered solution providing insights on freight prices worldwide (sea, air, and road freight), forecasts, and expert-written articles to help users stay informed and reduce costs or increase margins.
Connect: a freight marketplace where shippers can post loads, carriers can bid, and once a match is made, the shipment details are tracked in real-time, with payment processed in less than a week for carriers.

These two solutions require different architectural logics: Smart focuses on displaying data and machine learning outputs, while Connect demands a high-performance, stable marketplace.

Rebuilding the Marketplace: From Version 1 to Version 2

The first version of Connect was developed during the COVID period. However, it was built based on assumptions from Upply’s previous executive committee rather than user-centric needs. When it launched, it didn’t resonate with users — the platform lacked usability, and engagement never reached critical mass.

In 2022, after a change in the executive committee, I took on the technical lead role. My first big decision was to scrap Connect v1 and rebuild it from scratch, this time with a clear focus on user needs.

Performance, Scalability, and Reliability: What Our Architecture Demands

Starting from scratch gives you the opportunity to rethink everything, which inevitably leads to asking some tough questions. Technical choices at such times can be fundamental, and poor decisions can create massive technical debt that lingers through multiple generations of developers. These issues become “company constraints” — too heavy to fix and something you just have to live with.

Key Architectural Decisions: Monolith vs Microservices

As we embarked on the Connect v2 project, we discussed everything — from the overall architecture (monolith vs. microservices, queues vs. event-driven systems, CQRS, etc.) to deeper questions, like which programming language to use.

We’ll dive deeper into each of these technical topics in future articles. Let us know in the comments which one you’d like to read about first.

Should We Stick with PHP or Move to Scala, Rust, or Go?

One major question that arose: should we stick with our PHP Symfony stack, or should we migrate to something fancier and more suited to our performance needs — perhaps Scala, Rust, or Go?

This was an easy question to ask but a tough one to analyze. And even harder to implement if we decided to.

In Connect v2, shippers post loads, carriers offer quotes, and shippers must select or reject offers in real time. Once a shipment is accepted, both parties are kept informed of each step of the shipment’s journey. This required a system that could process events in a specific order, ensuring that real-time updates were reliable and accurate.

For instance, you can’t load a truck if the shipment has already been delivered. While this seems obvious from a business standpoint, handling event sequences correctly in code, at scale, can be tricky. And beyond accuracy, the system needed to handle massive volumes of transactions efficiently — a slow marketplace is simply a failed marketplace. These constraints had to be central in every architectural decision.

PHP: From Skepticism to Success in a Scalable System

When you think about PHP, especially for a complex system like a marketplace, the initial reaction is often skepticism. PHP has a long history, but it’s often seen as a “legacy” language. Compared to modern languages like Scala, Rust, or Go, PHP is frequently criticized for its performance, scalability, and modern development capabilities.

PHP vs Modern Languages: Can It Handle the Load?

At Upply, our initial discussions echoed these concerns. Could PHP really handle the load, the concurrency, and the real-time data processing we needed? This is where Scala (known for its scalability and functional programming), Rust (for high performance and memory safety), and Go (praised for its efficient concurrency) seemed like strong contenders and attractive alternatives.

But here’s where PHP surprised us. Over the years, it has evolved, especially with modern frameworks like Symfony that provide a robust ecosystem capable of supporting large-scale applications. By applying the right architectural patterns — like microservices, event-driven systems, using roadrunner, CQRS — we realized that our PHP Symfony stack could meet the high-performance requirements needed for our upcoming marketplace.

What PHP might lack in “hype” or modern cachet, it makes up for in stability, developer productivity, and a mature business-oriented ecosystem. Ultimately, the success of our platform wasn’t about the language itself but how we architected the system using the right tools and practices.

Assessing the Migration Costs: PHP vs Scala, Rust, and Go

When considering a migration, it’s not just about rewriting code. The true cost includes opportunity costs, learning curves, and the inherent risks involved. Migrating from PHP to Scala, Rust, or Go would have required a substantial investment in training and recruitment. While each language offers specific advantages — Scala for scalability, Rust for performance and safety, and Go for simplicity and concurrency — but each introduces its own complexities.

Why We Ruled Out Rust Early On

At a high level, we quickly ruled out Rust. Despite its innovation and high performance, Rust is the most complex language on our list. After a cost-benefit analysis, we realized that while Rust could boost performance, the productivity losses due to the learning curve outweighed the gains for our team.

Rust is a fantastic language, but if you have an experienced team in another language, the cost-benefit analysis is crucial. You need to weigh performance gains against the learning curve for your specific use case. In our case, Scala, Go and PHP would perform a bit worse, but we would benefit from all other factors a language may possess.

The Recruitment and Onboarding Challenge

Speaking of key factors: recruitment and onboarding should be included in your main focal points. Scala, and Go developers are in high demand, but the talent pool is relatively smaller compared to PHP. Hiring experts in these languages would be costly and time-consuming, potentially delaying key projects.

Moreover, onboarding new hires or training our existing team would have taken time, impacting our ability to quickly deliver value to users on a short-term point of view, which might still be interested for your stakeholders if you’re in a time of needed results.

I need to add a special note on these specific other languages: Scala and Go talent pools are a bit different and need to be apprehended in a different way as well.

Scala’s Talent Pool: Highly Skilled but Limited

The Scala talent pool, while highly skilled, is quite limited. Many Scala developers initially learned more mainstream languages like Java or PHP before transitioning to Scala. While this means the talent pool is generally more experienced, scaling a team with Scala developers can be challenging due to the smaller number of available candidates.

Go’s Talent Pool: Growing but Younger

On the other hand, Go developers tend to be younger and less experienced, as Go is increasingly being taught as a first language in some countries. Go’s simplicity and performance make it attractive, but the pool of experienced developers is still growing, which can pose challenges when building highly scalable, complex systems.

PHP’s Talent Pool: Abundant but Volatile

Conversely, PHP developers are more abundant, but the talent quality is more volatile. Since PHP is one of the most widely used programming languages, you’ll find a mix of bad, mediocre, and great developers. However, the advantage is that you have a larger pool of talent to select from, and the recruitment process can be streamlined by focusing on identifying top talent.

We knew that to ensure success, we’d need to be cautious during recruitment, spending extra time to identify great PHP developers. While this process might be more time-consuming upfront, it ensures that we build a team capable of delivering high-quality work quickly (note: pssst, we’re recruiting 👀).

Balancing Talent Quality and Team Experience

At Upply, our PHP team already had extensive experience. Shifting to a new language like Scala or Go would introduce risks, such as dissatisfaction and turnover, as developers might feel less comfortable or productive in a language they don’t know well.

Ultimately, the decision to remain with PHP wasn’t purely technical. It was driven by a combination of team expertise, recruitment challenges, and a need for long-term sustainability. Migrating to another language would have affected not only our codebase but also our people and culture.

Why PHP Was the Right Call for Our Team and Marketplace

Ultimately, our choice to stick with PHP was based on pragmatism and long-term vision. It wasn’t about favoring one language over another, but about making sure we had a sustainable and scalable architecture while leveraging the strengths of our current team.

By choosing PHP, we avoided the considerable costs and risks associated with transitioning to Scala, Rust, or Go. While these languages offer compelling advantages for high-performance systems, PHP allowed us to continue building at speed, with a team ready to deliver from day one. PHP’s mature ecosystem and large community also give us the flexibility to scale our team without friction, ensuring we can meet both our technical and organizational goals.

PHP for the Future: Evolving Without Lock-In

This decision has borne fruit. With Connect v2, we’ve built a marketplace that’s fast, reliable, and user-friendly. Our PHP-based event-driven micro-services architecture handles high volumes efficiently, allowing us to iterate quickly and meet user demands without sacrificing performance.

Looking forward, our decision to stay with PHP doesn’t lock us in forever. As the tech landscape evolves, we continue to evaluate options like Scala, Rust, and Go to ensure we’re always using the best tools for our needs. For now, though, PHP remains the best fit for our team, our users, and our business.

Interestingly, we’ve already begun integrating Go for some of our microservices, specifically to boost performance between our back-end and front-end or public gateways. As mentioned before, Go is a language that is easier to understand and learn, with amazing -but limited- libraries.

The key takeaway: Choosing the right language matters, but it’s just one part of a much larger puzzle. What truly matters is how well that language fits the business’s needs, the team’s strengths, and the ability to scale both technology and talent effectively.

Thanks to Anès, Julien, Stanislav, Maxime.

Article also available here.

Upply is the digital platform for freight transport professionals. Upply designs and develops cutting-edge and innovative solutions to help shippers, carriers and forwarders exploit the full potential of digitisation for their business.

Combining transport expertise and Data Science, since 2018 Upply has developed its leading solution, Smart, for benchmarking, tracking and analysing global freight rates. With Smart, supply chain players can make fully enlightened decisions and optimise their transport investments.

Through its Connect digital platform, Upply directly connects shippers with road hauliers and freight forwarders. As an operational tool, Connect simplifies transport operations by automating their processes.

To develop these unique technological solutions, Upply employs data scientists, logistics professionals and digital experts. The company is based in Paris and counts 60 employees.

Sponsor the Symfony project.

Symfony Blog

Read More

Latest News

PHP-Releases

PHP 8.3.15 released!

PHP 8.2.27 released!

PHP 8.1.31 released!

Generated by Feedzy