This may be an egregious question, but what does the Uber app actually do that makes it so big? It displays a map with some moving dots on them, allows you to pick a location, and asks the server for a route and price. Plus a bit of workflow for signup, credit card, reviews; not a huge number of screens.
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++)
Former Uber engineer/EM here: I worked on the Rider app.
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.
I also worked for Uber but on backend systems in the payments flow. Every single piece of app functionality mentioned above has at least one, if not multiple, backend systems and teams supporting it.
Like in the app, "payments" sounds like it would be a simple Stripe integration but it isn't. For one, that's way too expensive at Uber's scale. They build their own payment integrations to save fractions of a point that adds up to tens of millions of dollars in saved expenses.
There's real time systems to facilitate the trip, then the order processing systems to process that raw data, hydrate it, store it in multiple data warehouses, and publish it to Kafka to be consumed by literally hundreds of other services. The main money pipeline involved many services covering things such as rider incentives, driver incentives, rider fraud, driver fraud, tax calculations, rider payments across all of those aforementioned payment methods, receipts, invoices, driver disbursements, rider support, driver support, and more.
Then take in to account that almost all of those services were written for a world designed only for taking passengers from point A to point B with Uber Black but have huge added bloat to accommodate:
* Uber X
* Uber Pool
* Uber Eats
* Uber Freight
* Uber Moto
* Lime
* Jump
and proof of concept work for all sorts of new business ventures like Uber Elevate and ATG. All of that cruft is expensive to maintain and all of those actual product lines started as experiments.
When I left in 2019, there were two versions of the vast majority of those systems in production as all were being rewritten to handle the significant changes to Uber's business model from inception to now.
Additional edit: These services also require massive numbers of server hosts. All of the old stuff was written in Python, all the new stuff is in Go. That alone is saving Uber tens of millions per year just in hosting costs.
It genuinely blows my mind anyone who has written software couldn't have guessed at all of this from the beginning.
Uber PMs and engineers should be super proud. The fact that each user thinks that their one use-case is "all the app does" is fucking brilliant product design.
I've had over a thousand Uber rides (used it to commute) in 10+ countries and it's obvious there the way it seamlessly adjusts to each region but even otherwise I think I could have guessed just from the difference between SF and Seattle. There was a sort of joy of opening the app in a new region and finding unique options. Some sort of (maybe intentional) superstar-level product design.
Rickshaws in Seattle? Cash payment in India? Uber Taxi in SF? Sweet!
> The fact that each user thinks that their one use-case is "all the app does" is fucking brilliant product design.
Alternatively: The fact that they try to bundle all the world's use cases in some 100+ MB monstrosity of a client app is a tragicomic commentary on the misaligned incentives in the tech world's VC-driven wannabe-monopolies.
What happens when a user who travels unexpectedly discovers they need to download a new version of the app for where they are now? And what if they're on a low-bandwidth or capped cell plan and can't download a 100MB app easily, where 3/4 of the data is duplicates of stuff in their other 5 copies of the app?
What happens when a user tries to book an Uber from one area with a special app version to another area with a different special app version? This could easily generate tens of thousands of permutations.
What happens if the user is physically in one country right now, but is a national of another country and wants to pay for their Uber in their usual currency and payment method?
If the user ends up needing to have 20 copies of the app for various locations, how well will they sync ride history, changes in payment methods, and other such info?
I don't even work for Uber, and I thought of all of these complications in 10 minutes. The real Uber probably has 100x more complications that would arise from splitting location-specific functionality into location-specific apps.
Initial install bundle should be minimal and only have code that is required everywhere and or for downloading/installing more stuff.
It's not about creating 10,000 different permutations of an app, but downloading/installing content on demand.
If we are afraid that there might be problem that user later on has not enough bandwidth or issues like that, we'll start immediately downloading/installing after
initial bundle in order we think this user might need them.
This means much faster initial usage, much less bandwidth used in total.
Same with developing experience. You shouldn't have to compile code that is not important for your development exp. This way compiling wouldn't take much time, dev productivity would be increased tremendously.
For Android purposes: maybe it's allowed in the Play store? I'm not sure tbh. There are certainly other stores with other rules (and Uber is in many of them too), or they could distribute it themselves (but we can see how well that has worked for e.g. Fortnite), but you still need to handle any scenarios where it's required.
Sounds like base things, common for everything should be done using native app code and everything that varies that much should be made as PWA in WebView. You can download this PWA in the background too once app has installed if you are afraid you might not be able to do this on demand. I don't see why not use PWA? The performance implications in this case are minimal imo. And you have all the other fully fledged native features since your app is combination of both. Main arguments against PWA is that iOS doesn't support that well, but hell in this case you skip ALL problems with PWA since you have full capabilities already thanks to being generally native and you are downloading it from AppStore anyway.
In this case it could easily be reused within both Android and iOS without having to create duplicate business logic which I think already is a nightmare.
Airports logic I think should still be something that is defined using JSON/XML or w/e and algorithms should handle parsing that.
Or come on, there must be a way to get airports logic in an easier way. Does user have to update the app every-time when there's some minor airport update?
PWA won't give you access to random device APIs that you didn't open up for a specific use before needing them, which e.g. cameras, payment systems, etc often need. All that still needs to be native, and that can be substantial in some cases.
If it does, say you made a generic shim, you're effectively downloading and executing dynamic code. Maybe not by a technical definition, but that's not the point of Apple's rule, nor will they care about technical arguments when they reject it. There are plenty of examples of this happening in practice, I'm not talking hypothetically - it's why they have a carve-out explicitly for education apps. Even if you don't do stuff like that, and stay entirely in the webview, PWAs (unless it's actually being run in the browser, of course) are not allowed to make significant changes without going back through review.
edit: you can absolutely shrink your binary size with a PWA or similar though, yeah. There will definitely be other tradeoffs you have to make though, I'm not deeply familiar with those. Performance and integration with native libraries at the very least (e.g. map rendering).
By downloading dynamic code, in effect you're running N (or some combinatorial number of) different apps.
Granted, you can/should strongly isolate them so it's infeasible for one module to interfere with another. But as always, YMMV in practice. And good luck testing them all either way.
No, that's why it's beautiful product design. They know something about me. I am at location A and I have a problem: I want to be at B. They then solve that problem smoothly with reasonable defaults. They know this is the prime problem I have and that I have some top few variants on this.
Speaking of the defaults, the auto-suggests these guys have are fucking ridiculous too. Both Lyft and Uber. It's 4 AM in the morning and I've opened the app at home: offers me a ride to SFO. It's 11 PM in the evening on a Friday/Saturday and it offers me a ride to my friend's place. It's midnight and I'm at that friend's? They offer me a ride to my favourite club. I am one-click touching everywhere. These guys are good.
If anyone has a good reason to bundle every location’s use case into one app it’s Uber. A common Uber user scenario is someone who takes an Uber to the airport in one country, arrives in another and has poor internet capability for one of several reasons (roaming, poor mobile service, must connect to airport wifi, etc).
What solution do you imagine that isn't a worse user experience? I can think of lots of obvious ways to simplify the client, but they all seem likely to make things worse for me as a user in pretty predictable ways.
Thank you for all these details. I think it's a good sign when people think your app is simpler than it really is - the Uber app does a good job of hiding this complexity.
My experience with all this is that each time I opened the Uber app, I actually did not know what I was going to find. Taking an Uber a few times a month meant finding new UX patterns every time, sometimes features would be there, sometimes they wouldn't. It was very annoying to find that useful features had suddenly disappeared. After feeling that the UX was hostile due to this, and some IRL hostile experiences with drivers with a terrible support follow-up, I just dropped Uber for good. Alternative apps were more expensive but absolutely more stable.
I am not an app developer, so ignorant. Why not have different apps? Uber-India, Uber-Mexico, etc? Or if it is to be all one Global Uber app, why not have expansions that are downloaded for other regions as needed?
Would you want to download a different app every time you traveled to a new country? If you're in the EU/APAC with many countries close together and travel for business?
Uber works relatively well in every country you go to, including at one point, China. Not many apps have ever accomplished that.
I wouldn’t mind if the app started up and said, “download the $country_or_region extension,” but that is just me (assuming it doesn’t require re-creating an account, or re-entering billing details).
Get off the plane in a developing country. Some of those airports are not nice. Some of them are nice shells that are almost deserted, with no wifi and a couple vendors that won't take your American credit card. Your "World Plan" often works, sorta, but you can't always get data due to different radio bands or because the network is simply not good enough for a 100+mb download.
You'll either have to hop into a hopefully licensed taxi, or start walking in the dark in an industrial area (where airports usually are) in order to find a wifi hotspot or a street vendor that will sell you a SIM card.
It's not fun.
Why does it take 100MB to download the business rules for that particular country? It will take some data, but you will need some to book the taxi anyway.
Pretty much the last thing I want to do every time I step off a plane is download, install, and sign into a new app before I can get into a car to go to my hotel.
Imagine yourself at an airport and trying to order Uber, but be forced to download new 50 MB app. You would immediately try some other app like Bolt or Lyft.
I'm from EU country and it was so convenient to be able to use Uber in NYC the same way as I would in my home town.
Look, I get it that the app is complicated. I look at these apps from the perspective of a reverse engineer but invariably I find places where there is bloat just for the sake of being bloat. There is code that is provably not used, entire libraries that included just so that one small part of it can be used. I see time-related assets that have existed long past the date that they could have possibly been useful. I have seen apps that bundle entire scripting runtimes, apps that have half a dozen in-house telemetry libraries, apps that have megabytes of files in them in the hopes that they may be useful someday.
At this point it's really hard to believe the argument that "but our app is more complex that you could possibly understand" is valid. Compare your list with a Linux distribution from a handful of years ago: do you have more "screens" than that? Can you do more?
Eh. It doesn't seem particularly relevant to bring up Linux, with its hundreds of thousands of person-hours worth of volunteer contributions and an extremely technically focused BDFL gatekeeper.
It's a relatively well known fact that multi-team corporate projects have tech debt. There was a thread recently about Google Cloud being slow due to too-many-cooks-in-the-kitchen syndrome, and many ex-amazon folks say AWS UI is notoriously difficult to refactor for similar reasons.
I mean, Uber has had a huge number of people working on it too, with the incentive that they are paid to do a good job. Regardless of the eventual outcome, I have no misconceptions that Uber doesn't have some engineers who are extraordinary talented. And, the project is newer, too, with fewer guarantees on stability and fewer users to boot. I think it's a valid comparison to make at least–they are both huge, complex projects with a massive number of people working on them. Tech debt is inevitable, but I still think it is valid to call it out when it occurs and not try to excuse it with "but our app is super complicated, you can't possibly understand how complicated it is".
To be clear, I do think you have a valid point about e.g. unused assets and loading big libs to do trivial things, but IMHO, that's really a commentary on software development at large, rather than anything specific to Uber.
And there are cases, even in the Uber app, where thought has been put into optimizing both for upfront download size and internal complexity (the legal pages, for example)
Something that is worth considering is that a lot of what was said about the app being complicated is that it is also _dynamically_ complicated. For example, in the driver app, a feature was added to ensure drivers are wearing face coverings. The backend for that does AI-based fraud detection to prevent shenanigans like photos of photos. The picture upload flow is just one small part of a much more complex project that had to be rushed out because the covid pandemic happened. There are a bunch of similarly large impact things that touch several of the Uber apps simultaneously, often in non trivial ways and with tight timelines (e.g. features for compliance with specific legal requirements)
The reason I think Linux seems like a bad comparison is that if Linux contributors don't want to support some random driver for 3 years, that might be annoying but is generally just the way it is. Uber can't really afford to not do some of the complicated things it does in a timely manner.
What I don't really understand is why so much of the dynamic content ends up being native code on the client. For example, let's say you need to have some of legal compliance page. But there is always changes you have to make in a bunch of regions, and the flow is constantly changing, or whatever. But why can't this be a DSL you download and deserialize into views? Why does there have to be a hundred different native views for this that all must be part of the app? I'm hearing all these tail-end cases that one region hits and interacts with for seconds and I guess I don't really understand why these things are not handled server-side, making the app a dumb client. After all, isn't that how the website surely works?
I understand that Linux doesn't necessarily always have the product marketing deadlines or whatnot that Uber might have, but it's saddled with legacy code too. When things have security issues, or the API is just awful, at some point someone needs to fix it. Especially if your business is being decimated by a bug or you are lacking in APIs that meet your usecase. I don't think it's as poor as a comparison as you might thing it is.
I think a lot of it is driven by dysfunction and legacy at Apple. Their whole mindset is they want to review every version of the app manually and every bit of code that executes must be signed. They don't allow a lot of obvious software engineering approaches as a consequence, like partially downloading the app and streaming the rest on demand even though it's an obvious thing to do for mobile apps.
Note how in this story the Android and iOS teams started a big rewrite at the same time, but the story consists exclusively of fuckups on the Apple size. Apple impose an arbitrary cellular download limit. Apple designed a language that can't handle more than 9 dynamic libraries before it hits scaling issues. Apple prevent you from using interpreters or other techniques to change the app after it's installed, unless you use a WebView in which case it's OK for mysterious reasons. Apple don't help even when major brands are weeks away from wrecking their business by hitting these limits. Apple Apple Apple. Meanwhile the Android guys are sitting pretty with Java and now a migration to Kotlin, which is (a) a much better language than Swift and (b) is dogfooded at large scale on the IntelliJ project so you know it scales (had no scaling problems with Kotlin and I've been using it for the last five years).
I think the argument is more that even if you were to magically get rid of the cruft introduced by institutional bloat, the app will still necessarily be large given the nature of the business. Uber isn't some outlier here either; Lyft, Ola, Yandex, GoJek, Grab, etc etc all have comparable iOS app sizes.
It sounds stupid, but I'm going to say that they're all doing it wrong. One commenter in this thread brought up the Uber app for Android and it's a fraction of the size–clearly, market constraints can make it possible to do better?
It's a bit unfair to compare the mobile app with the Linux distro, given that mobile apps aren't supporting dynamic feature loading (or weren't at that time), so everything should be bundled. Imagine that any "screen" you need to access _must_ be bundled within the distro. So, compared to Linux distro – you should have your local mirror of all possible features any particular user would like to have. For example, Gentoo handbook says "Hosting a mirror requires a minimum of 550 GiB available disk space." 550 GiB just to run a Chromium? No – to have an opportunity to run it when you'll need it, because it's all or nothing. Either you get every program with all of its features, or get nothing at all.
Oh, no, I wasn't including "you can download packages" in this–I want it to be a fair comparison. Take a medium-weight Linux distribution and put it on a laptop and go on an island somewhere, if you want to tilt the comparison in the favor of Uber, which can of course still download assets from the internet and be backed by a server doing significant work for it. At that point I think it's still difficult to make the argument that Uber is somehow composed of more "screens" or "edge cases" that it needs to handle.
Interesting. I assume other multinational apps run into this problem as well. Is Apple considering support for apps with country-dependent payloads in the future? Otherwise seems like a lot of bloat across all major apps.
As someone who lives in the US, but (pre-covid at least) regularly travels to the UK (where I am from), I wish regional listing was not allowed _at all_. It's incredibly frustrating to have to carry two phones with different App Store accounts to be able to switch between the UK and US versions of things - Uber is one of the (vanishingly) few that gets this right and why they have consistently been my default choice for rides.
You don't need to carry two phones, you can sign out from App Store and then sign in with the other country account to install new apps. Updating works for both accounts even if the second country account is not currently logged in.
Pretty bad UX, it's clear it wasn't designed for this use case, you have to go into Settings, but it works if needed.
Maybe iOS could keep on hand the different versions you have, and automatically switch based on your current location? Generalize the "lazy loading" so app developers don't have to deal with the problem themselves
Yet, the last time I was throttled to 2G speed due to a problem with my carrier, the Uber app couldn’t even start (getting to the first interactive screen) in like five minutes. What’s the point of distributing the entire world’s data, which gotta change from time to time, when you can download the tiny requisite piece each time, especially considering that a relatively high speed Internet connection is required to use the app anyway?
Uber actually has a not-so-well-known product for this very problem: the mobile web version (m.uber.com)
It doesn't have nearly as much functionality as gregdoesit mentioned, but it's enough to service the use case of getting you from point A to point B when you're stuck w/ crappy connectivity.
The other not-so-well-known product is the Uber Lite app (iOS and Android) which was specifically made by Uber for this problem, particularly in the developing world.
Why display a link? Hybrid web/native apps are a tried-and-true strategy when you have massive complexity or dynamic content that you don't want to ship with your app. If you use it judiciously and tastefully the "native UI everything" people don't notice and come after you, either.
I actually built this product out (for both Uber and Lyft) - SMS/MMS-based ride requests (MMS only for sending google maps PNGs to confirm pickup location). I was about to convert it from a personal project (I used it to get rides on both services for a few years) to a "real" one open to customers, etc and then ran into snags with both APIs at around the same time. Uber's API changed to potentially require a web flow to confirm surge pricing (IIRC - now it's scheduled to be disabled entirely very soon) and Lyft's API was basically shut off entirely (there's a way to apply but I was unable to make any progress even through internal contacts at Lyft). I'll try and keep an eye out for any changes...
There are a lot of ways to frame these problems as interesting algorithms but it doesn't really strike me as something that is troubled by scale.
I've worked on similar problems where "everything is a special case" in some vein and it takes a few very clever minds to construct the algorithms and datastructures that can come to a good solution. But that's just it, it's the work of a few engineers and not thousands writing if-else blocks for each airport.
I still don't understand what Uber does that requires so many people getting paid so much money, the only thing that makes sense to me is they don't want them working for Lyft. It would be helpful for people to shed more light on how engineering resources are spent and what particular systems require so many hands to realize, but that's too valuable information to leak I'd imagine.
A good place to start would be to go through the Uber UI and click through every button and every page that exists.
Now create a driver profile and do the same thing.
Now create the multitude of other special profiles they have and do the same.
Now do the same for Uber Eats.
Now do the same for Eats but using the restaurants version of the app.
And the couriers.
Now get in on Uber Freight (and any other projects they have) and do all of the same.
Now do all of that again for their other platforms (iOS, Watch OS, Wear OS, Android, Web)
Now access their internal tools that make all of this possible and do the same.
Now think about localizing all of that. Handling special cases for different places/languages/legalities. Think of all the different payment integrations. Security issues. Infrastructure. Technical debt. AB testing. Metrics. Dev tooling.
And I've only begun to scratch the surface here. The point is there is a lot more than meets the eye, especially when operating on a global scale.
This is a common but specious argument. It is possible to make large, complicated apps without creating a monstrosity. That you are making something like this is a manifestation of an engineering culture that has too many cooks in the kitchen, a lack of specific engineering talent spent on finding issues and telling the teams shipping them to stop, people shipping libraries that they don't need and tech debt that was never pruned away. An app with 100x more people working on it should not be 100x larger, because it certainly won't have 100x more features in it. Sure, Uber is more than "a map and a couple views" but the fact remains that their app should never have been in the state that it was.
The Apple Maps app on iPhone, for example? If you make it fair and count the code that goes into the frameworks specifically for it, it's still tens of megabytes at the most. There is a huge part of it running server-side to support it, of course, but it is difficult to say that it is not a complicated app. Or consider the Mail app? It needs to deal with IMAP, and has custom flows for a number of named mail services (Gmail, Yahoo, etc.), and then it has to have special code to handle all the edge cases of "what happens if the user deletes a message here but it didn't sync, or Google sends us 503s sometimes if we do this, or…" You can make arguments that maybe it is slightly less or more complex than Uber, but it is just a couple dozen megabytes and not hundreds.
10s of megabytes? Where did you pull that number from? Since it is a system app, its true install size is hidden away from users. The comparable google maps app is 190 MB.
You should scratch below the surface because this isn't really explaining much - it does not sound like something that requires more than 100 people. Their legal team sounds like it should be twice that alone.
My point is that there is 100s of screens/features in the Uber app that you don't even know exist. And you have those same 100s of screens across their other apps. Multiplied across all of the different platforms. Plus any internal tools they use.
I'm curious, have you worked at a software company of Uber's scale? Not trying to be a dick here, genuinely curious because I hear these types of comments often here on HN and I wonder how many of those commenting have seen the scale from within.
My whole point here is I don't understand why "Uber scale" is so large. I have worked in large organizations - smaller than Uber, but we did more stuff (as in more complexity and diversity in products - shipping software and the hardware to run it, for example).
"100s of screens" is as meaningless to me as "thousands of lines of code" and wholly uninteresting because it seems like the front end is the least significant reason why Uber requires so many people to operate. That's why I'm interested in seeing how many people are assigned to projects and what they actually spend their time doing, because at scale you begin to experience inefficiencies due to scale for bad reasons if your incentives aren't aligned. From the original twitter thread that sounds like it was rampant at Uber.
Not sure how long you've been around, but "Uber scale" used to be a joke a few years ago because no one could understand why they would reinvent so many wheels because "they don't work at Uber scale." The joke being that Uber didn't need to be Uber scale to begin with, they just had investor money to burn.
I'm just a layman, but I often ponder this same "Why are some companies so big when a small team could do about the same thing?" and my mental theory currently is:
1. The amount of engineers scales very badly with respect to application complexity. I.e. you may need 100 or 1000 engineers to do something that "looks" about 2x as complex as something 10 engineers can do, and
2. The more complex solution tends to win in the market because on the one hand people value the application handling edge cases better, having shiny graphics, having slightly better UX, etc. and on the other hand you redeem the cost of paying those 1000 engineers thanks to software being free to copy and network effects / monopoly.
Google really is just an advertising company. Everything else "Alphabet" does is a rounding error next to ad revenue.
Microsoft and Amazon have multiple profitable lines of business.
Is Uber more like Google or more like Amazon? Is "Uber Eats" (underpaid contractors drive around takeaway dinners) distinct from "Uber" (underpaid contractors drive around people), or "Uber Black" (underpaid contractors with unwise car leases drive people around)?
> Google really is just an advertising company. Everything else
> "Alphabet" does is a rounding error next to ad revenue.
It's not like people would go and visit a page with just a list of ads; no matter how little revenue the other products around ads bring in, they bring eyeballs to the ads, and serve as a moat around ads.
> Google really is just an advertising company. Everything else
> "Alphabet" does is a rounding error next to ad revenue.
It's not like people would go and visit a page with just a bunch of ads; no matter how little revenue the other Alphabet products bring in, they bring eyeballs to the ads, and serve as a moat around ads.
At a growing massive company it's not about efficiency but total outcome. If 10x the engineers gives you 10% more revenue then that's worth it economically if the pie is large enough. 10% of 4 billion a year can pay for a lot of engineers. Once you're no longer growing then you need to focus on efficiency as more engineers rarely translates to more total revenue in that case.
Having a large number of engineers is fantastic for making the company valued higher.
Directors love having more engineers under them.
Overall I've been highly speedy with 4 engineers, and slowly adding a 5th. Sure there are limits, but I think limits makes us think about being more efficient with how we build. It is an entirely different mindset.
Once you decide to "go big" you end up in this situation where you usually literally throw a dozen engineers at the problem and the problem goes away. I've seen designers spend 6 months on a _single page_. Because they can. and they get paid crazy money for it.
A helpful way to think of it is by comparing how Uber and an OS GUI are different (since that's the comparison people are making, anyways)
With an operating system UI, the developer may reasonably know what the UI will look like, what features are present, where they are placed. With Uber, a single person may not know all the rules for a single feature, and the rules change frequently, sometimes in the most obtuse ways. Like when San Francisco decided to ban cars from one of its most important artery streets earlier this year (market st). Now not only you need to indicate to a rider that this is a thing, your UI also needs to to provide walking instructions to the nearest designated pickup spot, and the routing algorithm needs to not put drivers on market st. Oh, and don't forget Hebrew speaking tourists read right-to-left and that food delivery bicycles _are_ still allowed on market st. That's just one change in one city.
Consider that just about anything might change anywhere, any time. From how earning breakdowns are displayed for drivers in Sao Paulo (this differs by jurisdiction), to where the pickup locations are in Pearson airport in Toronto (airport rules change all the time), to what promos apply in Mexico City this week (which depends on marketing and finance analysis), to whether surges should be disabled in response to a terrorist attack, to what documents a driver signup rep should be scanning into the system as local regulations change.
Now build all the infrastructure required considering that the people on the ground reporting their local changes are not programmers, and conversely many of these changes may require making changes to the UIs that these people use, how the new data is aggregated, etc. There are literally thousands of greenlight hub / customer support employees worldwide using these internal tools, many don't speak english and timezones are all over the place. The nature of problems are often fuzzy, hyperlocal-specific (e.g. certain forms of fraud), or extremely meticulous (e.g. legalese, etc).
The trouble of scale comes with having to deal with numerous nebulously defined things from numerous stakeholders and having to distill which engineering teams are even responsible for which aspects of which thing. As the number of stakeholders grow, so does the risk of miscommunication, unclear chain of responsibility and other well-documented large organizations challenges.
That's a bad comparison and I'm not sure why people are making it - you're mistaking fundamentals. This isn't a UI problem, it's datastructures and algorithms. There are plenty of desktop apps with similar issues (representing a complex problem as a set of constraints and writing a solver to find a solution, and querying the solution for the data to display to a user).
I don't reject that there are troubles in concerting real world data into a representation for the constraint solver. But this isn't untrodden ground, and there's no reason a front end developer should need to care about it. The problems you're describing are far behind the UI; and if they're not your organization has immense problems.
> there's no reason a front end developer should need to care about it
Well, yes and no. You're right that trying to express every nook and cranny of the business rules as solely a UI problem is a wrong way of trying to understand the complexity. But a frontend developer does need to care about how to surface whatever complexity needs to be surfaced, and likewise, backend developers need to know how to model the complexity, and there needs to be some level of orchestration between all the moving parts. Remember, Uber is built on a microservice architecture, and many things that would be arbitrary hardcoded values in projects elsewhere (e.g. pricing) are instead tied to complex dynamic systems in Uber.
In the pricing example, when Uber added the option for drivers to set their own multipliers, it wasn't just a new slider in the driver app. It also affected the pricing AI model, the matching algorithm, how and when prices are displayed in the rider app, geofencing rules, etc etc.
When new regulations mandate that every commit that makes production changes in your city must have an appropriate audit trail, when you need to deploy a cheat-proof face mask detection AI model in response to a global pandemic, when you need to figure out how to make customer support cost $1 per engagement instead of $10, when you need to figure out how to make your network protocol faster in Bangalore, when you need to figure out how to make GPS more accurate in Manhattan, or when any of hundreds of fuzzy problems need solving, then saying that variations of all of these problems have been seen elsewhere misses the point that going from problem statement to deployed solution isn't always a trivial task.
The original question was why so many people work at Uber. The answer is that there are a lot more fuzzy problems than meets the eye.
We've previously spent a lot of resources also looking for ways to render native components through backend APIs (there was a team called screenflow that was laid off) but this was complex and wasn't able to support complex business needs. Uber does not want to remove app size at the cost of UX (ex. webviews).
Seems like a reasonable architectural choice early on when your app is live in 2 cities. Instead of changing the language of the app, they should have focused on its API architecture.
The items you've listed don't appear to be things that would contribute directly to the size (in MB as installed on the device) of the app. I don't think GP was making a comment about the complexity of the product, just the size of the installed app.
It seems a little strange to criticize someone for asking a question on a site where most users seem to value curiosity. Not everyone has a background that makes it as easy to imagine problems like these, and while you've given some possibilities, I would also be interested in knowing exactly what accounts for the size.
There are far better ways to ask the question than “What does the app even do, just seems like a map with a few dots” which has a heavy implication on the quality of the team that built it..
Evaluating map data inaccuracy? More than just a payment UI? Driver/passenger matching? Data analytics? (Doesn't that require information from multiple clients?) On the client?
I mean, you could push some of that to the client, but I'd understand why your app is gigantic and doesn't do app-ly job very well with all the background processing. And I'd be surprised the app hasn't been hacked to get at the analytics data, if not the payments.
There’s a lot of complexity behind making the user experience as simple as it is. One example: it’s my understanding that there is a lot of effort put into correcting for GPS error in areas like cities so the the little pickup location dot is in the right place. I imagine the entire system for that is a fair amount of offline processing, backend and client code.
> 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 negative / unpopular take: like air in a balloon a startup company will grow as large as its capital allows as it is purposefully using this capital to grow faster than natural market forces allow. In other words it has a big engineering team because it raised capital to get a big engineering team. Craigslist is a great example of bucking the trend in this regard.
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.
I think a combination of these is true. Uber certainly deals with more complexity in mapping than almost anyone. Their scale is massive. That being said: their engineering scale is massive as well. And if you have enough people, they will start adding things just for the sake of being busy. There is certainly someone at Uber writing code that is included in the app bundle that never runs. There are certainly assets being shipped that were relevant in 2016 but have since been forgotten. There is an engineer messing with some low-level powerful API for no real reason other than they find it interesting, and hurting the performance of something or the other by an order of magnitude. For political reasons, there is some non-optimal code shipping somewhere. At extremely large team sizes, it can be very difficult to find and fix these issues. But this is a social, not a technical, problem.
Experimentation / data-driven product development. You’re actually downloading 583 small variations of the same app, plus all the localized rules mentioned above, and it quickly adds up.
I’ve often wondered the same thing about Airbnb, DoorDash, and other unicorns where they hire the best engineers from Silicon Valley, yet their product seems like a rather basic CRUD tool.
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.
I doubt that the truly best engineers work there. But certainly at their scale you need really good ones at least.
They also have a huge need for speed. Shipping faster and winning a market is worth 10s of million in annual revenue and billions in valuation.
A lot of this is resume driven development as well. Solving a hard problem, even if it's an invented one, looks good on your resume. So does using the latest and greatest tech stack instead of a boring but functional one.
Joe the Data Scientist says that if the app dynamically does X then that could be worth $10 million a year. Steve the product manager says his change could be worth $1 million a year. And so on and so on. Most are wrong, some are right. If you have a small team you'll never implement any of it so you won't know. If you throw people at it then you can test all those things. And when your company makes billions a quarter it doesn't take much of a revenue lift to pay for a few dozen teams.
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++)