I appreciate the difficulties of getting an app to fit in a fixed space having worked on a point of sale system that had to run on a MIPS device with 32MB of Flash, of which half was occupied by Windows CE. It's not really clear to me why Uber's app needs to be so large and complicated other than the availability of a large amount of money, high-powered engineers, and shiny new unproven technologies.
(The compact app fit in about eight megs in the end, plus another meg or so for the file which defined all the screens; it was written in the least trendy, unsexiest framework known to man, Windows MFC in C++)
The “there are only a few screens” is not true. The app works in 60+ countries, with features shipped in the app that often for a country, and - in rare cases - a city.
The app has thousands of scenarios. It speaks to good design that each user thinks the user is there to support their 5 use cases, not showing all the other use cases (that are often regional or just not relevant to the type if user - like business traveler use cases).
Uber builds and experiments with custom features all the time. An experimental screen built for London, UK would be part of the app. Multiply this by the 40-50 product teams building various features and experiments outside the core flows you are talking about (which core flows are slightly different per region as well).
I worked on payments, and this is what screens and components are in the Uber app:
- Credit cards (yes, this is only a a few screens)
- Apple Pay / Google Pay on respective platforms
- PayPal (SDK)
- Venmo (SDK)
- PayTM (15+ screens)
- Special screens for India credit cards and 2FA, EU credit cards and SCA, Brazil combo cards and custom logic
- Cash (several touch points)
- AMEX rewards and other credit card rewards (several screens)
- Uber credits & top-ups (several screens)
- UPI SDK (India)
- We used to have Campus Cards (10 screens), Airtel Money (5), Alipay (a few more), Google Wallet (a few) and I other payment methods I forget about. All with native screens. Still with me? This was just payments. The part where most people assume “oh, it’s just a credit card screen”. Or people in India assume “oh it’s just UPI and PayTM”. Or people in Mexico “oh, it’s just cash”. And so on.
Then you have other features that have their own business logic and similar depths behind the scenes when you need to make them work for 60 countries: - Airport pickup (lots of specific rules per region)
- Scheduled rides
- Commmuter card functionality
- Product types (there are SO many of these with special UI, from disabled vehicles, vans, mass transport in a few regions etc)
- Uber for Business (LOTS of touchpoints)
- On-trip experience business logic
- Pickup special cases
- Safety toolkit (have you seen it? Very neat features!)
- Receipts
- Custom fraud features for certain regions
- Customer support flows
- Regional business logic: growth features for the like of India, Brazil and other regions.
- Uber Eats touchpoints
- Uber Family
- Jump / Lime integrations (you can get bikes / scooters through the app)
- Transit functionality (seen it?)
- A bunch of others I won’t know about.
Much of the app “bloat” has to do with how business logic and screens need to be bundled in the binary, even if they are for another region. E.g. the UPI and PayTM SDKs were part of the app, despite only being used for India. Uber Transit was in a city or two when it launched, but it also shipped worldwide.
And then you have the binary size bloat with Swift that OP takes about.
Apparently all this location-specific business logic has to be in the app itself and is not downloadable on demand.
I never work for Uber but I can easily imagine the following problems:
* Map data is not a solved problem. Tons of inaccurate data especially on non-english speaking countries.
* As someone mentioned about payments, different country requires different payment platform integrations.
* Payment is just one aspect of money, you need to build a treasure-like logic to run a marketplace between drivers and passengers.
* The matchmaking algorithm itself is interesting enough problem. It has to be efficient for the company to make the most amount of money.
* Tons of internal data are produced and required to be understood. This requires ML/data analytic talents.
> The app looks simple from the user perspective. But on the global scale the business rules are insanely complicated. Every region has custom rules/regulations. Different products have different workflows. Some regions have cash payments. Every airport has different pick rules...
A more positive take: if you look at the specifics of how many regions Uber is (was) in, and that each region has cities each of which have wildly different regulatory environments, you can imagine the permutations of complexity they had to deal with. Then you add in growing internal business experiments like Eats or mobility (Jump) and it's easy to see how this balloons out of control pretty fast.
It justifies the employment of 400 iOS engineers, it also lets you book taxi rides.
Apparently with Uber it’s the infrastructure design and back-end algorithms for trip routing and driver management that are “so great.” The SV hype machine helps a lot too.
Problem here with Swift came down to
- Apple not dogfooding its own tech . Hell they did not even help us or other major companies like AirBnB and LihnkedIn (We formed a workforce on this problem with them which then forced the download limit to be upped by apple)
- Engineers deciding to adopt a language which they thought was great (and turned out not to be at the time) because they did not do the right analysis upfront for such a significant project. 'Wow look at this shiny new cool tool, lets use it' (Oversimpiification, swift was more pleasant to write with and you could be more productive which was no doubt a factor here)
Also, while management at the time didnt care for the remote offices much, I think the AMS team played a critical role in the success here. With the recent layoffs that occurred, I heard that they were fired.
Another fun story, we were trying to bring down our build times on our CI builds which were 1hr+ while battling macstadium and their crappy infrastructure with tens/hundreds of patches incoming each day.
> So said brilliant engineer in Amsterdam, built an annealing algorithm in the release build to reorder the optimization passes in such a way to as minimize size. This shaved a whooping 11 mbs off the total machine code size and bought us enough runway to keep development going.
> This terrified the Swift compiler engineers, they were worried that untested complier pass orders would expose untested bugs
This would scare me too.
> I had privately had the “we need to stop” conversation with my director. He told me that if this project fails he might as well pack his bags. The same was true for his boss all the way up to the VP. There was no way out.
This brings up an interesting point. The author attributes some decisions in the thread to the "sunk cost fallacy". The business costs were sunk, but if the employees and management are too afraid for their job to make the "cut your losses" decision, the costs are not really sunk, at least not in the minds of the right people.
The story arc is almost always the same: starts out very promising and moves quickly, then at some point the wheels come off but everyone keeps going.
Anyway, Joel Spolsky nailed it 20 years ago: https://www.joelonsoftware.com/2000/04/06/things-you-should-...
Seems less like they weren't offering answers, so much as the answer wasn't "but we'll do some stuff and fix Swift!"
Though the 6 library limit and how that wasn't a gigantic red flag on the language is baffling.
I couldn't find that specific quote, though, and being 25 years back it could be a false memory of who said it (I did read it somewhere, if you were on the team at the time, please speak up!). Here are a couple of illustrations[0][1].
[0] http://read.pudn.com/downloads196/ebook/923902/ShowStopper!-...
[1] http://www.proudlyserving.com/archives/2007/09/dave_cutler_w...
As an engineer, I understand I'm a vehicle for success at a startup. Even if I ultimately get burnt out and quit. If I make important changes, that maybe only I could have thought of before I quit, it probably becomes a good investment to hire me.
Uber managed to hire enough of the "right" vehicles for success to get to the point where they shipped a platform rewrite at massive scale. By all high level objective metrics, this is probably success story.
The one metric I think could derail the projects success isn't really documented--what was the human cost to this effort? I bet you looking at a graph of turnover at Uber you could probably identify exactly when this project happened. I'm curious if the engineering turnover from such a massive effort was enough to offset the benefit.
This is one of the main reasons why I have no intention of going back to BigTech any time soon. I am sure the author is an extremely capable engineer but he is obviously missing the elephant in the room: that the root problem is app growth and feature creep caused by uncontrolled growth of the eng. workforce (who are all incentivized to ship their code because it's good for promotion). As if app growth was some kind of god-given fate that can't be changed! But instead of fighting the real (organizational, political) issues within the company, they blame it on technical issues (Swift is not mature! 100 MB app size limit is too low! etc.). Incredible.
The larger community benefited from our learnings.
No. The larger community would have benefited if you had written a story about how someone in the org. stood up to management, fought the feature creep, the crazy app growth and doubling eng. each year, and brought the whole project back to sanity. But that didn't happen.
So my advice. Everything in Computer Science is a trade off. There is no universally superior language. Whatever you do, understand what the tradeoff are why you are making them. Don’t let it descend into a political war between opinionated factions.
No disrespect, but no choice / tradeoff in the world would have led to a satisfactory outcome if you have hundreds of engineers burying this app under an avalanche of code day after day. The tools / tech are alright. The company is not.
I really like this point.
Speaking for myself, I didn’t add any Swift to any codebase I worked on until after 3.0 shipped because it was pretty clear that the language just wasn’t quite ready yet.
I’m genuinely surprised no one ever thought to just email Chris Lattner or invite him out for a drink to say ‘hey, confidentially between you and me we’re thinking about rewriting our app in your new language. Are there any other apps with this order of magnitude of LOC written in Swift yet?’
Uber's culture of "letting builders build" is fine, as long as teams have the ability to change things early and quickly. I think top-down decision making and monumental bloating of eng teams made things very difficult over time.
> I had privately had the “we need to stop” conversation with my director. He told me that if this project fails he might as well pack his bags. The same was true for his boss all the way up to the VP. There was no way out.
> With only a week left we decided eat the 8 figures and drop support for iOS 8.
I'll say this: If I were an Uber investor I would be pretty angry. And the story just gets worse from there.
This is a story of gross incompetence. It's not an engineering disaster, it's a management disaster. This is classic "inmates running the asylum". ( https://www.goodreads.com/book/show/44098.The_Inmates_Are_Ru... )
This is the story of some hackers who got in good at a big company with lots of money and sturm und drang so they had no adult supervision while they partied while pretending to be actual engineers. (That they were pretending to themselves too doesn't make it any better.)
The writing was on the wall, but rather than own up and take responsibility they double down and keep messing things up for months and years.
> This is when the real brilliant engineers started to shine.
This is when they get pulled from other tasks to clean up your mess! (cf. Broken window fallacy.) Those real brilliant engineers should be doing other better things than dark rituals to appease the Swift compiler gods.
Look, we all make mistakes. There's a blog post from an engineer at a company I used to work for complaining about the pointless middleware I wrote years earlier. (I feel ya bro, I told them at the time that it was pointless.) Here's the thing: I got out of that place when I realized that the folks running it weren't really competent. (And, sure enough, they got pushed out by the investors and now the company is a "Wallstreet darling". So... Yay?)
I've burned enough investor money in my career that I don't think it's funny anymore. (I never really did think it was funny, I don't like waste, but I was young. REDACTED was only my second official job, and in hindsight it was really crazy. I mean, they built a skating half-pipe in the office! At the time, everybody thought that was real cool.)
It was also, coincidentally, the company where I most respected the key technical decision-makers, because they had the will to discontinue a product that a few customers already were using, because it wasn't meeting its criteria.
LinkedIn adopted Swift back in 1.2. I would love to read some war stories of how things there have progressed over the years.
Source: https://www.youtube.com/watch?v=X9waDi787uo (14:15-15:30, 39:26-40:37)
At an interview with them a few years ago, I was told they had been moving towards rewriting the app in Objective-C.
I'm following George Hotz's tinygrad that is a CPU+GPU deep learning framework under 1000 lines of code with great interest where all engineers are trying to shave lines of code while maintaining readable code (it's like a game when you set rules):
https://github.com/geohot/tinygrad
Here's the GPU ops part:
https://github.com/geohot/tinygrad/blob/master/tinygrad/ops_...
It's interesting to me that the author feels that things were great with Uber in 2016 pre-Trump and that Trump's election was the catalyst for the negative sentiment. Susan Fowler's famous post was early 2017, and maybe _posting_ it was catalyzed by the issues surrounding Trump, but clearly the serious cultural problems she described at Uber had been going on for some time before that.
I'm trying to figure out what to make about a lot of these mis-steps. On the one hand, many of them seem preventable: you could imagine identifying ahead of time that load time and binary size might be risks for the new app and scale-testing these very early in the process to de-risk it. You could imagine testing the new app long enough (and widely enough) to discover the location issues (drivers going to the wrong blocks, etc.). You could imagine foreseeing users being upset about suddenly needing their location data when they're not using the app. Obviously hindsight is 20/20, but is there also a pattern (that we see all the time, especially in Silicon Valley it seems) of not really thinking through the consequences of a lot of decisions, especially where things like user privacy are concerned?
Admittedly the things I've worked on has been games and CAD systems so the internal data models and simulation are a lot more complicated than the UI, but I think that holds for a lot of apps.
Twitter owns an company called MoPub that broadcasts user location information to the adtech industry.
This doesn't make much sense. When you open the app to schedule a pickup, and you have location tracking enabled while you use the app, Uber should be apprised as to your current location within seconds. Where you were before you opened the app should not matter.
It would be useful if the author could clarify this.
As one of the people who started a petition to Apple to disallow developers from disabling location tracking only while using the app (i.e. all the time or never, which Uber tried to force at the time), I am partly responsible for the outcome. But from what I can tell, no customers were worse off as a result.
If Uber has data showing otherwise, that would be interesting.
http://nathanmock.com/archives/how-i-accessed-employee-setti...
That being said it’s a common problem in growth startup. Prioritization is hard. Too many engineers doesn’t mean problems get solved. They need to be able to talk to each other and execute with what’s essential to users.
Growth is a curse and a blessing.
Was the move to Swift inevitable and they started too early or should they have stayed with - and still be using - Objective-C?
I've read plenty of these stories where a rewrite was a total disaster. (Most famously, Netscape.) I've seen and/or lived through some too. (One where a major distributed system was completely changing its storage model, and it was thought refactoring was impossible. In hindsight, it was achievable and would have saved _years_.)
Anyone have examples of regretting a refactoring to the same extent?