This is the final part of our Q&A roundup following our Building Mobile Apps At Scale webinar with Gergely Orosz, Pooja Bhaumik, and Franz Busch. We hope these blogs provide you with a way of recapping the insights we gained, as well as offer something extra, with additional context and links to further resources.
In part one, we covered mobile development and process, and in part two, we examined engineering teams and culture. The third entry in the series, unlike those that came before, covers only a few questions but one big topic: refactoring vs rebuilding. It’s a decision every scaling mobile team is going to have to make eventually.
One could perhaps summarize the advice by quoting the title of a post on Snap’s engineering blog: Don't Rewrite Your App, Unless You Have To. But let’s allow our panel to elaborate.
If you want to watch back the full webinar, you can view the recording.
These are the questions we’ll be covering:
- Why did Uber decide to write a new app instead of refactoring the old one?
- How do you find the balance between delivering new features and taking some time to prepare a codebase for scale? What would be the right arguments you can bring to your stakeholders?
- What was the biggest challenge during the rewrite at Uber? I especially wonder how you handled feature developments requests at the same time?
- When legacy code and tech debt become a big problem, it's quite usual to arrive at an intersection of either rewriting the app from scratch or refactor the existing codebase step-by-step. How would you decide in this situation?
- How do you really remove legacy codebase out of your main codebase? Normally the new architecture does not fit with old architecture or legacy code.
Why did Uber decide to write a new app instead of refactoring the old one?
Gergely: “At Uber, it was a really interesting one. It was because we're a startup. And because the CEO said so, pretty much. We didn't have an external threat. A lot of companies rewrite because they have, we had a CEO who just hated that the app was being crowded. And he said, “sure, let's rewrite it”. And when the teams told him this will take like three or four months, he said, “fine”. I think he underestimated it.
But in some ways, I think Uber had this really weird opportunity that most companies don't have. So Facebook never had the opportunity to rewrite the Facebook app. You're never going to hear Facebook talk about their app architecture, because it's not as clean as Uber’s because they couldn't just throw everything out and start from scratch.
So on one end it was a bit of a vanity project, if you ask me. And on the other end... we were at a point where engineers really wanted to do it, design wanted to do it. And we thought it'll just take this short amount of time, and then it just burnt out the whole company. So it was not the best decision.
Also, Uber made this big mistake, which if you ask anyone they’ll agree: we adopted Swift very early. At that time, it was Swift 1.2, there was still no ABI compatibility. And performance was bad. We knew that performance was bad. What we did not know when we started the project was that the binary size increase was massive. And Uber had this huge problem that if it went over 100 megabytes in size, it could not be downloaded over 3G or 4G. And a lot of our first-time users only had that, they didn't have wifi. So that became a big sticking point.
We were at the point where we were close to finishing the rewrite and we almost decided to pull the plug because the app was getting too large to start with, and just go back to Objective C.”
How do you find the balance between delivering new features and taking some time to prepare a codebase for scale? What would be the right arguments you can bring to your stakeholders?
Pooja: “It kind of depends on which stage you're at. If you're, for example, building the product from scratch, you’d want to just ship it right now. And it's going to be like a do or die situation for you. You will not have the perfect scalable architecture in the beginning, it will have a lot of iterations along the course of the entire product building. In the beginning, I think just shipping will be the best.
However, you should also have sprints where you're supposed to refactor some of the controversial or the tricky parts of your code base, where you need to really refactor them and make them better. And sometimes you can have some dedicated people or a dedicated team to just refactor code base for scale or basically make the architecture better in certain parts.
Your stakeholders may be not really giving you time to refactor because that is probably not going to be their most important task yet you will have to fight for it and say how this actually helps in the long run.
Refactoring can also be part-by-part, you don’t have to do it all at once.”
Gergely: “One thing that I have said, and this goes for when you want to do this type of work and also when you want to find a platform team, there's two things that you can talk about. One is you can tell the business — the product manager, the product owner, for the most part — you can tell them what bad things will happen. If you don't do this, for example, our velocity will come to a halt or we're going to see a lot more regressions because of whatever. Or you can tell them the upside — if we do this, and will actually develop the features faster, or automation will run faster.
If you say what bad things will happen and they don't give you funding, and those bad things do not happen, people not will take it that seriously because the world is not going to end. Now on the other hand, if you focus on the good things that will happen, as time passes like you'll feel more and more of the pain then people will take you more seriously. So I suggest we focus on the good things that will happen.
And you can do two things: you can just ask ask ask or you can start doing it — like no one's stopping you, if you're a senior engineer on a team, from taking a little bit of time on the side and then saying ‘oh, I actually did this as well.’ But I would be very careful when you're saying, like, ‘oh, if we don't do this in like, three months, something terrible will happen.’ Because if that doesn't happen, your credibility will go down a little bit.”
When legacy code and tech debt become a big problem, it's quite usual to arrive at an intersection of either rewriting the app from scratch or refactor the existing codebase step-by-step. How would you decide in this situation?
Gergely: "Most companies and teams do step-by-step as it's more sensible.
Uber had a unique situation and a founder who did not care about the risk. It was a pretty reckless decision, if you ask me, but in the end the gamble paid off.
It goes down to how much you trust the team, what is the risk, what is the upside/downside etc."
How do you really remove legacy codebase out of your main codebase? Normally the new architecture does not fit with old architecture or legacy code.
Gergely: “At Uber, we rewrote the app and removed the old codebase (deleted it). This was a rare luxury. You usually go one step at a time, rewriting a smaller part, and removing the corresponding legacy code.”
What was the biggest challenge during the rewrite at Uber? I especially wonder how you handled feature developments requests at the same time?
Gergely: “From my view, it was the timeline. The platform team had many challenges with Swift. Read more here: Uber's Crazy YOLO App Rewrite, From the Front Seat.”