Part 2 of the Uber Data Infrastructure Series
Important Note: This article is based on my understanding after reading the Uber Engineering blog and various articles about their cloud migration. I’m trying to demystify and explain these concepts in an accessible way. If you want to understand exactly what Uber built, please refer to the original articles linked in the Further Reading section.
Previously: Part 1 - Building the Original Infrastructure explained how Uber built a custom data platform with Kafka, HDFS, Spark, Flink, and more.
This article explains why Uber decided to migrate everything to Google Cloud Platform (GCP) and how they did it without breaking anything.
Introduction: Why Change a Working System?
By 2020, Uber had built one of the world’s most sophisticated data infrastructures:
- ✅ Handled 137 million monthly users
- ✅ Processed 1 million+ events per second
- ✅ Stored petabytes of data
- ✅ Powered real-time decisions in milliseconds
So why change it?
Think of it like this: Imagine you built your own power plant, water system, and phone network for your house. It works great! But:
- You need 50 employees to maintain it 24/7
- It costs $1 million/year to run
- When you want to expand, you need to rebuild everything
- You can’t go on vacation because someone needs to watch it
Wouldn’t it be easier to just plug into the city’s utilities?
That’s exactly what Uber realized about their data infrastructure.
The Problems with the Original System
Problem 1: Crushing Complexity
The reality: Managing 7 different distributed systems is incredibly hard.
Uber's data infrastructure in 2020:
System 1: Apache Kafka
- 100+ servers
- 3 engineers dedicated to it
- Upgrade every 6 months
System 2: HDFS (Storage)
- 1,000+ servers
- 10 engineers managing
- Constant disk failures
System 3: Apache Hudi
- Built by Uber, maintained by Uber
- 5 engineers full-time
System 4: Apache Spark
- 500+ servers
- 5 engineers managing
System 5: Apache Flink
- 200+ servers
- 4 engineers managing
System 6: Apache Pinot
- 100+ servers
- 3 engineers managing
System 7: Presto
- 200+ servers
- 3 engineers managing
TOTAL:
- 2,000+ servers to manage
- 35+ engineers JUST for infrastructure
- Plus: networking, security, monitoring teams
- Grand total: 300+ engineers
That's an entire company just to run infrastructure!
The Real Cost of Complexity
Engineer costs alone:
- 300 engineers × $200K average salary
- = $60 million/year just in salaries!
- Plus infrastructure costs: $100M/year
- Total: $160M/year
And engineers could be building features instead!
Problem 2: Slow Scalability
The problem: Can’t scale quickly when you manage your own hardware.
Real example from Uber:
Scenario: Expanding to India (2019)
Traditional approach (what Uber did):
Month 1-2: Find data center in India
Month 3-4: Order servers (long lead times)
Month 5-6: Ship and install hardware
Month 7-8: Configure networking
Month 9-10: Install and test software
Month 11-12: Train local team
Result: 12 months, $20 million
Cloud approach (what they wanted):
Week 1: Enable GCP region in India
Week 2: Deploy infrastructure (copy config)
Week 3: Test
Week 4: Launch
Result: 1 month, $2 million
10x faster, 10x cheaper!
Problem 3: Inflexible Capacity
The problem: Must plan capacity 6-12 months in advance.
Traditional infrastructure:
- Predict next year's growth: "We'll grow 50%"
- Order servers: 3-6 months lead time
- Install: 2-3 months
- Results: 6-12 months later
What actually happens:
❌ Grow slower than expected? Wasted money on unused servers
❌ Grow faster than expected? Run out of capacity, can't serve users
❌ Seasonal spikes? Must provision for peak (waste 70% of capacity off-peak)
Example:
New Year's Eve: 10x normal traffic
- Need: 10,000 servers for 1 day
- Reality: Must buy 10,000 servers permanently
- Cost: $50M for servers used 1 day/year!
Problem 4: Geographic Constraints
The problem: Data regulations require data to stay in each country.
Uber operates in 70+ countries
Regulations:
- EU data must stay in EU (GDPR)
- China data must stay in China
- Brazil data must stay in Brazil
- Australia data must stay in Australia
- Etc.
Uber's challenge:
Need to replicate ENTIRE infrastructure in each region
- 2,000 servers × 10 regions = 20,000 servers
- 300 engineers × 10 regions = 3,000 engineers (impossible!)
- Cost: $160M × 10 = $1.6 billion/year (impossible!)
Reality: Could only expand to new countries very slowly
Problem 5: Innovation Bottleneck
The problem: Engineers spend time managing infrastructure instead of building features.
Before (2020):
- 300 engineers managing infrastructure
- 500 engineers building features
- Ratio: 37% on infrastructure!
What Uber wanted:
- 100 engineers managing infrastructure (cloud)
- 700 engineers building features
- Ratio: 12% on infrastructure
Result: 200 more engineers building features!
The Solution: Move to Google Cloud Platform (GCP)
In 2020, Uber made a bold decision: Migrate their entire data infrastructure to Google Cloud Platform.
Why Google Cloud?
Uber evaluated three major cloud providers:
| Factor | AWS | Azure | Google Cloud | Winner |
|---|---|---|---|---|
| BigQuery | ❌ No equivalent | ❌ Synapse (not as good) | ✅ Best analytics database | GCP |
| Data tools | Good | Good | Excellent (built for Google scale) | GCP |
| Pricing | Standard | Standard | Cheaper for data workloads | GCP |
| Hadoop support | Yes | Yes | Yes (Dataproc) | Tie |
| Existing relationship | No | No | Yes (Maps partnership) | GCP |
Uber chose GCP primarily because of BigQuery — which could replace 3 systems (Hudi + Pinot + Presto) with one!
The New Architecture: GCP Version
Old vs New: Side-by-Side Comparison
(100+ servers)"] OH["HDFS
(1000+ servers)"] OHU["Hudi
(maintenance nightmare)"] OS["Spark
(500+ servers)"] OF["Flink
(200+ servers)"] OP["Pinot
(100+ servers)"] OPR["Presto
(200+ servers)"] end subgraph NEW["NEW SYSTEM (GCP Managed)"] direction TB NP["Pub/Sub
(fully managed)"] NG["Cloud Storage
(fully managed)"] NB["BigQuery
(replaces 3 systems!)"] ND["Dataflow
(fully managed)"] NDP["Dataproc
(managed Spark)"] end OLD ==>|"3-year migration"| NEW style OLD fill:#fee,stroke:#f00 style NEW fill:#dfe,stroke:#0f0
Component Replacements
| Old System | GCP Replacement | What Changed |
|---|---|---|
| Kafka (100+ servers) | Pub/Sub (0 servers) | Google manages everything |
| HDFS (1,000+ servers) | Cloud Storage (0 servers) | Infinite storage, pay per GB |
| Hudi + Pinot + Presto | BigQuery (0 servers) | 3 systems → 1 system! |
| Spark (500+ servers) | Dataproc (auto-scaling) | Spin up/down as needed |
| Flink (200+ servers) | Dataflow (auto-scaling) | Fully managed |
Total servers managed:
- Before: 2,000+ servers
- After: 0 servers!
The Migration Strategy: How Uber Did It
Principle 1: Zero Downtime
Non-negotiable: Can’t stop serving 137 million users during migration!
Uber’s approach:
Phase 1: Build parallel infrastructure
├─ Old system: Serves production (100% of traffic)
├─ New system: Built in parallel (0% of traffic)
└─ Duration: 6 months
Phase 2: Shadow testing
├─ Old system: Serves production (100% of traffic)
├─ New system: Receives copy of data (0% of traffic)
├─ Compare results: Are they identical?
└─ Duration: 6 months
Phase 3: Gradual migration
├─ Old system: 90% of traffic
├─ New system: 10% of traffic (test users)
├─ Monitor: Any issues?
└─ Duration: 12 months
Phase 4: Full migration
├─ Old system: 0% of traffic (shut down)
├─ New system: 100% of traffic
└─ Duration: 6 months
Total time: 30 months (2.5 years)
Principle 2: Minimize User Disruption
Goal: Data engineers shouldn’t need to rewrite their code.
How Uber achieved this:
Problem: Engineers had thousands of Spark jobs
Bad approach:
"Rewrite all your code for GCP!"
Result: Years of work, high risk of errors
Uber's approach:
Keep the same interfaces:
- Spark jobs run on Dataproc (managed Spark)
- Same code, different infrastructure
- Engineers don't even notice!
Migration complexity:
- Infrastructure team: High (rebuilding everything)
- Data engineers: Low (minimal code changes)
- Data scientists: Zero (no changes needed)
Principle 3: Phased Migration by Use Case
Strategy: Migrate least critical systems first, learn, then tackle critical systems.
Uber’s migration order:
Phase 1: Analytics & Reporting (Non-Critical)
├─ Risk: Low (if it breaks, business continues)
├─ Complexity: Medium
├─ Migrated: Pinot → BigQuery
├─ Duration: 6 months
└─ Learning: How to use BigQuery effectively
Phase 2: Batch Processing (Medium Critical)
├─ Risk: Medium (affects daily reports)
├─ Complexity: High
├─ Migrated: Spark → Dataproc
├─ Duration: 12 months
└─ Learning: Auto-scaling, cost optimization
Phase 3: Storage (Critical)
├─ Risk: High (can't lose data!)
├─ Complexity: Very High
├─ Migrated: HDFS → Cloud Storage + BigQuery
├─ Duration: 12 months
└─ Learning: Data governance, security
Phase 4: Real-Time Systems (Most Critical)
├─ Risk: Very High (affects user experience)
├─ Complexity: Extreme
├─ Migrated: Kafka → Pub/Sub, Flink → Dataflow
├─ Duration: 6 months
└─ Learning: Performance tuning, failover
Total duration: 36 months (3 years)
The New System: Component Deep Dives
1. Google Cloud Pub/Sub (Replaces Kafka)
What it is: Google’s fully managed event streaming service.
Before (Kafka) vs After (Pub/Sub)
Before (Kafka):
✅ Performance: 1M events/second
❌ Management: 100+ servers to manage
❌ Scaling: Manual (add servers)
❌ Monitoring: Build custom dashboards
❌ Upgrades: Quarterly maintenance windows
❌ Team: 3 engineers full-time
❌ Cost: $2M/year (servers + engineers)
After (Pub/Sub):
✅ Performance: 1M+ events/second (same or better)
✅ Management: Zero servers
✅ Scaling: Automatic
✅ Monitoring: Built-in dashboards
✅ Upgrades: Google handles it
✅ Team: 0 engineers (Google manages)
✅ Cost: $1M/year (pay per message)
Savings: $1M/year + 3 engineers freed up
How Pub/Sub Works (Simplified)
(Fully Managed)"] PUBSUB --> SUB1["Subscription 1:
Real-time processing"] PUBSUB --> SUB2["Subscription 2:
Analytics"] PUBSUB --> SUB3["Subscription 3:
Storage"] SUB1 --> CONSUMER1["Dataflow"] SUB2 --> CONSUMER2["BigQuery"] SUB3 --> CONSUMER3["Cloud Storage"] style PUBSUB fill:#fef3c7,stroke:#d97706 style CONSUMER1 fill:#d1fae5,stroke:#059669 style CONSUMER2 fill:#dbeafe,stroke:#2563eb style CONSUMER3 fill:#fce7f3,stroke:#db2777
Real Migration Example
Old Kafka code (before):
Properties props = new Properties();
props.put("bootstrap.servers", "kafka1:9092,kafka2:9092,kafka3:9092");
props.put("group.id", "uber-analytics");
KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
New Pub/Sub code (after):
// Almost identical!
ProjectSubscriptionName subscription =
ProjectSubscriptionName.of("uber-project", "uber-analytics");
Subscriber subscriber = Subscriber.newBuilder(subscription, receiver).build();
Migration time: Hours (not months!)
2. Google Cloud Storage (Replaces HDFS)
What it is: Infinite, durable, object storage in the cloud.
Before (HDFS) vs After (Cloud Storage)
Before (HDFS):
✅ Performance: Good
❌ Capacity: Limited (must buy more disks)
❌ Servers: 1,000+ servers to manage
❌ Disk failures: Weekly (replace failed disks)
❌ Expansion: Order disks 3 months in advance
❌ Team: 10 engineers full-time
❌ Cost: $50M/year (hardware + data centers + engineers)
After (Cloud Storage):
✅ Performance: Excellent (Google's network)
✅ Capacity: Infinite (no limits)
✅ Servers: Zero
✅ Disk failures: Never (Google handles it)
✅ Expansion: Instant (just write more data)
✅ Team: 0 engineers (Google manages)
✅ Cost: $20M/year (pay per GB stored)
Savings: $30M/year + 10 engineers freed up
Cost Comparison: 1 Petabyte of Data
HDFS (self-managed):
- Servers: 50 servers × $10K each = $500K
- Data center space: $100K/year
- Power & cooling: $200K/year
- Network: $50K/year
- Disk replacements: $100K/year
- Engineers: 1 engineer × $200K = $200K/year
Total: $1.15M/year
Cloud Storage:
- Storage: 1 PB × $20/TB/month = $20K/month
- Data transfer: ~$50K/month
Total: $840K/year
Savings: $310K/year per petabyte!
Plus: No engineers needed, scales instantly
3. BigQuery (Replaces Hudi + Pinot + Presto)
The game-changer: One system replaces three!
The Magic of BigQuery
What it does:
Old system needed 3 tools:
1. Hudi: Store and update data
2. Pinot: Fast analytics queries
3. Presto: SQL queries across systems
BigQuery does all three:
1. Stores petabytes of data ✓
2. Queries in milliseconds ✓
3. Uses standard SQL ✓
Plus:
4. Auto-scales ✓
5. Zero management ✓
6. Integrates with everything ✓
Before (Hudi + Pinot + Presto) vs After (BigQuery)
Before:
❌ 3 systems to learn
❌ 3 systems to maintain
❌ Data duplicated 3 times (storage waste)
❌ Complex data syncing
❌ 400+ servers across 3 systems
❌ 11 engineers managing
❌ Query time: 100-500ms (Pinot), 1-10s (Presto)
❌ Cost: $30M/year
After:
✅ 1 system to learn
✅ 0 systems to maintain (Google manages)
✅ Data stored once
✅ No syncing needed
✅ 0 servers
✅ 0 engineers managing
✅ Query time: 100ms - 5s (depending on query)
✅ Cost: $15M/year (pay per query)
Savings: $15M/year + 11 engineers freed up
Complexity reduction: 66% (3 systems → 1)
Real BigQuery Example
-- Query billions of rides instantly:
SELECT
city,
COUNT(*) as total_rides,
AVG(fare) as avg_fare,
SUM(fare) as total_revenue
FROM `uber-data.trips.rides`
WHERE date >= '2024-01-01'
AND date < '2024-02-01'
GROUP BY city
ORDER BY total_revenue DESC
LIMIT 10
-- Query performance:
-- Data scanned: 500 GB
-- Query time: 2.3 seconds
-- Cost: $2.50 (for this one query!)
-- Same query on old system:
-- Required: Running Presto cluster 24/7
-- Cost: $70/day ($2,500/month) even if query runs once!
BigQuery’s Secret Sauce
1. Columnar Storage (Like Pinot)
Stores data in columns (not rows)
Query: "Average fare in NYC"
- Only reads "fare" column
- Ignores other columns
- 10-100x faster than reading full rows
2. Separation of Storage and Compute
Traditional database:
- Storage and compute tied together
- Must pay for compute 24/7
- Can't scale independently
BigQuery:
- Storage separate from compute
- Pay for compute only when querying
- Auto-scales compute for each query
Example:
Small query: Uses 10 nodes, costs $0.10
Huge query: Uses 1,000 nodes, costs $10
Both finish in ~same time!
3. Automatic Optimization
BigQuery automatically:
- Chooses best indexes
- Partitions data optimally
- Compresses data
- Caches frequent queries
- Parallelizes queries
Engineer's job:
- Just write SQL
- BigQuery optimizes everything
4. Dataproc (Replaces Spark Clusters)
What it is: Managed Apache Spark/Hadoop service.
Before (Self-Managed Spark) vs After (Dataproc)
Before (Self-Managed Spark):
❌ Cluster setup: 2-4 weeks
❌ Always-on clusters: Waste money during idle time
❌ Scaling: Manual (provision more nodes)
❌ Monitoring: Build custom tools
❌ Upgrades: Complex, risky
❌ Cost: $40M/year (servers + engineers)
❌ Team: 5 engineers managing
After (Dataproc):
✅ Cluster setup: 90 seconds!
✅ Ephemeral clusters: Spin up for job, shut down after
✅ Scaling: Auto-scales based on job size
✅ Monitoring: Built-in dashboards
✅ Upgrades: Click button (or automatic)
✅ Cost: $20M/year (pay per job)
✅ Team: 1 engineer managing
Savings: $20M/year + 4 engineers freed up
The Ephemeral Cluster Magic
Old approach (always-on):
Morning (8am):
- Cluster: Running (100 nodes)
- Utilization: 80%
- Cost: $100/hour
Midday (12pm):
- Cluster: Running (100 nodes)
- Utilization: 90%
- Cost: $100/hour
Night (2am):
- Cluster: Running (100 nodes)
- Utilization: 5% (mostly idle!)
- Cost: $100/hour (wasting $95/hour!)
Daily cost: $2,400
Wasted: ~$1,000/day (idle time)
Monthly waste: $30,000!
New approach (ephemeral):
Job 1 (8:00am): Need 50 nodes for 30 minutes
- Spin up 50-node cluster
- Run job
- Shut down cluster
- Cost: $25
Job 2 (9:00am): Need 200 nodes for 15 minutes
- Spin up 200-node cluster
- Run job
- Shut down cluster
- Cost: $50
Job 3 (10:00am): Need 20 nodes for 1 hour
- Spin up 20-node cluster
- Run job
- Shut down cluster
- Cost: $20
Night (2am): No jobs
- No clusters running
- Cost: $0 ✅
Daily cost: ~$1,200
Savings: 50% compared to always-on!
5. Dataflow (Replaces Flink)
What it is: Fully managed service for stream and batch processing.
Before (Flink) vs After (Dataflow)
Before (Flink):
✅ Performance: Excellent (sub-100ms)
❌ Complexity: Very high (hardest system to manage)
❌ Scaling: Manual, tricky
❌ State management: Complex (where to store state?)
❌ Failover: Build custom logic
❌ Team: 4 engineers full-time
❌ Cost: $15M/year
After (Dataflow):
✅ Performance: Excellent (sub-100ms, same as Flink)
✅ Complexity: Low (Google manages)
✅ Scaling: Auto-scales automatically
✅ State management: Handled by Google
✅ Failover: Automatic
✅ Team: 0.5 engineers (part-time)
✅ Cost: $10M/year
Savings: $5M/year + 3.5 engineers freed up
Real-Time Use Case: Surge Pricing
How it works on Dataflow:
(Pub/Sub)"] --> DATAFLOW["Dataflow Pipeline"] DATAFLOW --> WINDOW["Windowing
(5-minute windows)"] WINDOW --> AGG["Aggregation
(count per zone)"] AGG --> CALC["Calculate
supply/demand"] CALC --> SURGE["Determine
surge multiplier"] SURGE --> BIGQUERY["Store in
BigQuery"] SURGE --> PUBSUB["Publish
to Pub/Sub"] style DATAFLOW fill:#fef3c7,stroke:#d97706 style BIGQUERY fill:#dbeafe,stroke:#2563eb
# Dataflow pipeline (simplified):
def calculate_surge(events):
return (
events
| "Window into 5 min" >> beam.WindowInto(FixedWindows(300))
| "Key by zone" >> beam.Map(lambda e: (e.zone, e))
| "Count requests" >> beam.CombinePerKey(CountRequests())
| "Count drivers" >> beam.CombinePerKey(CountDrivers())
| "Calculate surge" >> beam.Map(calculate_surge_multiplier)
| "Write to BigQuery" >> beam.io.WriteToBigQuery(...)
)
# Dataflow handles:
✅ Auto-scaling (10 to 1000 workers)
✅ State management (remembers counts)
✅ Failover (if worker dies, restart)
✅ Monitoring (built-in metrics)
Engineer's job:
- Just write the pipeline logic
- Dataflow handles infrastructure
Migration Challenges & Solutions
Challenge 1: Performance Differences
Problem:
HDFS (on-premises):
- Local disk access: 1-5ms latency
- Network within data center: <1ms
Cloud Storage (GCP):
- Network access: 10-50ms latency
- Across internet: Can spike higher
Result: Some jobs 2-5x slower!
Uber’s solution:
1. Use persistent disks for hot data
- Frequently accessed data on fast disks
- Cold data in Cloud Storage
2. Optimize data layout
- Partition data effectively
- Use compressed formats (Parquet)
3. Leverage BigQuery
- Instead of reading files, query BigQuery
- BigQuery optimized for cloud access
Result: Performance back to baseline (or better!)
Challenge 2: Cost Management
Problem:
First month on GCP:
- Bill: $8M (expected: $5M)
- Overage: $3M!
Why?
- Data egress charges (moving data out)
- Inefficient query patterns
- Always-on development clusters
- Not using reserved instances
Uber’s solution:
1. Reserved instances
- Commit to baseline usage: 40% discount
2. Committed use discounts
- Commit to 1-3 years: 50-70% discount
3. Query optimization
- Use partitioned tables
- Limit SELECT * queries
- Cache frequent queries
4. Ephemeral dev clusters
- Auto-shut down after 2 hours idle
- Saved $500K/month!
5. Data lifecycle policies
- Move old data to cold storage
- Delete temp data automatically
Result: Reduced costs to $5M/month target
Challenge 3: Data Governance
Problem:
GDPR compliance:
- EU users' data must stay in EU
- Can't accidentally move to US
Risk:
- Data engineer runs query
- BigQuery job in US region
- Reads EU data
- Violation! Huge fines!
Uber’s solution:
1. Regional isolation
- EU data: Only in EU regions
- US data: Only in US regions
- Enforced with IAM policies
2. Data access proxies
- Engineers don't access data directly
- Go through proxy that enforces rules
- Proxy logs all access
3. Automated compliance checks
- Daily scans for violations
- Alert security team immediately
- Auto-remediation where possible
Result: Zero compliance violations!
Challenge 4: Team Training
Problem:
300 data engineers used to:
- Spark on YARN
- Hive SQL
- Custom tools
Now need to learn:
- BigQuery SQL (different dialect)
- Dataproc
- Cloud Console
- New monitoring tools
Uber’s solution:
1. Gradual transition
- Keep old system running during training
- Learn at own pace
2. Internal training program
- "GCP Boot Camp": 2-week intensive course
- Hands-on labs
- Office hours with experts
3. Internal documentation
- Migration guides
- Best practices
- Common pitfalls
4. Champions program
- Early adopters help teammates
- Share lessons learned
5. Abstraction layers
- Build wrappers that hide complexity
- Engineers write same code, runs on GCP
Result: 90% of engineers productive in 3 months
The Results: What Changed
Result 1: Massive Cost Savings
Before (2020):
Infrastructure: $100M/year
- Servers: $50M
- Data centers: $30M
- Network: $10M
- Maintenance: $10M
Engineers: $60M/year
- 300 engineers × $200K average
Total: $160M/year
After (2024):
Infrastructure: $60M/year
- GCP services: $60M
- (No servers, data centers, etc.)
Engineers: $20M/year
- 100 engineers × $200K average
- 200 engineers redeployed to product work
Total: $80M/year
SAVINGS: $80M/year (50% reduction!)
Result 2: Speed Improvements
Development time:
Before: 3-6 months to launch new data product
- Provision infrastructure: 1-2 months
- Setup and configure: 1 month
- Develop: 1-2 months
- Test and deploy: 1 month
After: 2-4 weeks
- Provision infrastructure: 0 days (instant!)
- Setup and configure: 1 day
- Develop: 1-2 weeks
- Test and deploy: 1 week
Improvement: 5-10x faster!
Scaling time:
Before: 3-6 months
- Plan capacity
- Order servers
- Install and configure
- Deploy
After: Automatic
- Traffic spike? Auto-scales in minutes
- New region? Enable in days
- Seasonal demand? Scales up/down automatically
Improvement: 100x faster (months → minutes)
Result 3: Reliability Improvements
System uptime:
Before: 99.9% (9 hours downtime/year)
- Hardware failures
- Human errors
- Upgrade issues
After: 99.99% (52 minutes downtime/year)
- Google's infrastructure
- Automatic failover
- No manual upgrades
Improvement: 10x fewer outages
Data durability:
Before: 99.99% (risk of data loss)
- 3 copies of data
- But: Data center fire = could lose region
After: 99.999999999% (11 nines!)
- Google replicates across regions
- Virtually impossible to lose data
Improvement: 10,000x more durable
Result 4: Global Expansion
New region setup:
Before: 6-12 months, $10-20M
- Find/build data center
- Order and install hardware
- Hire local team
- Deploy and configure
After: 1-2 weeks, $1-2M
- Enable GCP region
- Copy configuration
- Test
- Launch
Improvement: 10-20x faster, 10x cheaper
Uber's expansion since migration (2020-2024):
- Launched in 20 new countries
- Doubled total markets (35 → 70 countries)
- Total cost: $30M (would have been $300M before!)
The GCP migration enabled Uber's global expansion!
Result 5: Innovation Velocity
Before migration:
- 300 engineers on infrastructure
- 500 engineers on product
- Ratio: 37% infrastructure
After migration:
- 100 engineers on infrastructure
- 700 engineers on product
- Ratio: 12% infrastructure
Impact:
- 200 engineers freed up
- Building features, not managing servers
- Faster innovation
- More products shipped
New capabilities enabled:
1. Real-time fraud detection
- Needed: Scale to analyze 10M transactions/second
- Before: Impossible (limited capacity)
- After: Built on Dataflow (auto-scales)
2. Global demand forecasting
- Needed: Process 1 PB of data daily
- Before: Would take 12 hours (too slow)
- After: BigQuery processes in 1 hour
3. AI-powered pricing
- Needed: Train models on 5 years of data
- Before: Would take weeks, huge compute cost
- After: Dataproc spins up 10,000 nodes, done in hours
4. Real-time driver bonuses
- Needed: Calculate bonuses in real-time
- Before: Batch processing (next day)
- After: Dataflow processes in milliseconds
These features wouldn't exist without GCP migration!
Lessons Learned: Uber’s Advice
Lesson 1: Phased Migration is Critical
Uber’s advice: Don’t try to migrate everything at once.
Uber's approach:
Year 1: Migrate 10% of workloads
- Learn the platform
- Discover issues
- Build confidence
Year 2: Migrate 50% of workloads
- Apply lessons learned
- Optimize costs
- Train teams
Year 3: Migrate remaining 40%
- Tackle critical systems last
- After gaining experience
What NOT to do:
❌ "Big bang" migration (switch everything overnight)
❌ Migrate critical systems first
❌ Rush to meet arbitrary deadline
Result: Zero major incidents!
Lesson 2: Run Both Systems in Parallel
Uber’s advice: Run old and new systems side-by-side during migration.
The "shadow mode" approach:
1. New system receives copy of all data
2. Both systems process in parallel
3. Compare results continuously
4. Only switch when identical for 30 days
Benefits:
✅ No risk to production
✅ Discover issues before they impact users
✅ Can roll back instantly if needed
✅ Build confidence gradually
Cost:
❌ Running two systems = 2x cost temporarily
✅ But: Worth it for zero-risk migration
Uber's timeline:
- Parallel run: 6 months per system
- Extra cost: $30M
- Value: Priceless (zero production incidents)
Lesson 3: Cost Optimization Takes Time
Uber’s advice: Initial cloud costs will be higher. Optimize over time.
Uber's cost journey:
Month 1: $8M (60% over budget!)
- Haven't optimized yet
- Learning platform
Month 3: $7M (40% over budget)
- Applied some optimizations
- Still learning
Month 6: $6M (20% over budget)
- Most optimizations done
- Getting there
Month 12: $5M (on budget!)
- Fully optimized
- Using reserved instances
- Efficient query patterns
Key insight: Budget for learning curve!
Lesson 4: Invest in Training
Uber’s advice: Your engineers are your most important asset.
Uber's training investment:
- 2-week boot camps: $500K
- Internal documentation: $200K
- Office hours (expert time): $300K
- External trainers: $100K
Total: $1.1M
Return on investment:
- Faster adoption: Saved 6 months
- Fewer errors: Prevented costly mistakes
- Better optimization: Saved $3M/year
ROI: 300% in first year!
Lesson: Training pays for itself quickly
Lesson 5: Don’t Lift-and-Shift Forever
Uber’s advice: Start with lift-and-shift, but modernize afterwards.
Uber's two-phase approach:
Phase 1: Lift-and-Shift (Year 1-2)
- Move to GCP IaaS
- Minimal changes to code
- Fast migration
- Benefits: Faster scaling, less management
Phase 2: Modernization (Year 2-4)
- Adopt PaaS services (BigQuery, Dataflow)
- Refactor applications
- Slower, requires code changes
- Benefits: Lower costs, better performance
Why two phases?
✅ Phase 1: Quick wins, low risk
✅ Phase 2: Maximize benefits
❌ Trying to do both at once: Too complex, high risk
Current status (2024):
- 70% modernized to PaaS
- 30% still on IaaS
- Target: 90% PaaS by 2026
What’s Next for Uber?
Current State (2024)
Infrastructure:
✅ 100% on GCP
✅ 0 self-managed servers
✅ 70% using PaaS services
✅ 30% using IaaS (still migrating)
Cost:
✅ $80M/year (down from $160M)
✅ 50% cost reduction
✅ Still optimizing
Team:
✅ 100 engineers on infrastructure (down from 300)
✅ 200 engineers redeployed to product
✅ Faster innovation
Future Plans (2024-2026)
1. Complete PaaS Migration
Goal: Move remaining 30% from IaaS to PaaS
- Replace remaining self-managed Spark → Dataproc
- Migrate all storage to BigQuery/Cloud Storage
- Adopt Vertex AI for ML workloads
Expected benefits:
- Additional 20% cost savings ($16M/year)
- Reduced complexity
2. Multi-Cloud Strategy
Goal: Don't depend on single cloud provider
- Primary: GCP (current)
- Secondary: AWS (for specific workloads)
- Disaster recovery: Azure
Benefits:
- Avoid vendor lock-in
- Negotiate better pricing
- Resilience (if one cloud goes down)
Challenge:
- Increased complexity
- Team needs to learn multiple clouds
3. Real-Time Everything
Goal: Move from batch to real-time processing
- Real-time earnings (not next-day)
- Real-time fraud detection (not minutes)
- Real-time analytics (not hourly)
Enabled by:
- Dataflow's streaming capabilities
- BigQuery's streaming inserts
- Pub/Sub's low latency
Expected benefits:
- Better user experience
- Faster fraud detection
- More accurate pricing
4. AI/ML Everywhere
Goal: Leverage AI for everything
- Demand forecasting
- Dynamic pricing optimization
- Route optimization
- Driver-rider matching
- Fraud detection
- Customer support automation
Enabled by:
- Vertex AI (managed ML platform)
- BigQuery ML (SQL-based ML)
- TensorFlow on Dataproc
Investment: $50M over 3 years
Expected ROI: $200M in increased efficiency
Summary: The Complete Transformation
The Journey
2015-2020: Built Custom Infrastructure
- 7 specialized systems
- 2,000+ servers
- 300 engineers
- $160M/year
- 99.9% uptime
2020-2023: Migrated to GCP
- 3-year journey
- $30M migration cost
- Zero production incidents
- Phased approach
2024: Fully on Cloud
- 5 main GCP services
- 0 servers
- 100 engineers
- $80M/year
- 99.99% uptime
Transformation:
- 50% cost reduction
- 10x faster to scale
- 5-10x faster development
- 10x better reliability
- 200 engineers freed for product work
Old vs New: Final Comparison
| Aspect | Before (Self-Managed) | After (GCP) | Improvement |
|---|---|---|---|
| Cost | $160M/year | $80M/year | 50% reduction |
| Servers | 2,000+ | 0 | 100% reduction |
| Engineers | 300 | 100 | 67% reduction |
| Uptime | 99.9% | 99.99% | 10x fewer outages |
| Scaling time | 3-6 months | Minutes | 1,000x faster |
| New region | 6-12 months, $10-20M | 1-2 weeks, $1-2M | 10x faster, 10x cheaper |
| Dev time | 3-6 months | 2-4 weeks | 5-10x faster |
| Complexity | Very High (7 systems) | Medium (5 services) | 30% reduction |
Key Takeaways
- Cloud isn’t always cheaper immediately
- Year 1: Costs more (running both systems)
- Year 2+: Massive savings
- ROI: Positive after 18 months
- Migration takes time
- Uber: 3 years for complete migration
- Can’t rush it
- Phased approach is critical
- The benefits are real
- 50% cost savings
- 10x faster scaling
- Freed engineers for innovation
- Enabled global expansion
- It’s not just about technology
- Team training is critical
- Change management is key
- Cultural shift required
- Managed services win at scale
- Even Uber (with massive engineering team)
- Chose managed over self-managed
- Focus engineers on product, not infrastructure
What This Means for You
If You’re a Startup
Lesson: Start with cloud from day 1!
DON'T build like old Uber:
❌ Self-managed infrastructure
❌ Custom systems
❌ Years of engineering effort
DO start with cloud:
✅ Use managed services (BigQuery, etc.)
✅ Scale automatically
✅ Focus on product, not infrastructure
Your tech stack should be:
Phase 1 (0-100K users): $100-1K/month
- PostgreSQL (managed)
- Redis (managed)
- Simple analytics
Phase 2 (100K-1M users): $1K-10K/month
- Cloud SQL or Aurora
- Redis/Memcached
- BigQuery for analytics
Phase 3 (1M-10M users): $10K-100K/month
- BigQuery for data warehouse
- Pub/Sub for events
- Dataflow for processing
Only at 10M+ users:
- Consider what Uber does
- But still on managed services!
If You’re Mid-Size (Currently Self-Managed)
Lesson: Migrate to cloud, but take your time.
Migration timeline:
Year 1: Plan and pilot
- Assess current infrastructure
- Calculate TCO (total cost of ownership)
- Run pilot projects
- Build business case
Year 2-3: Migrate
- Start with non-critical systems
- Run in parallel
- Train team
- Optimize costs
Year 4: Complete and optimize
- Finish migration
- Shut down old infrastructure
- Celebrate savings!
Expected savings:
- 30-50% cost reduction
- 5-10x faster development
- Fewer engineers on infrastructure
If You’re Enterprise
Lesson: Follow Uber’s playbook.
Uber's proven approach:
1. Phased migration (3 years)
2. Run in parallel (shadow mode)
3. Migrate by risk level (low to high)
4. Invest in training ($1M+)
5. Start with lift-and-shift
6. Then modernize to PaaS
7. Optimize costs continuously
Expected outcomes:
- 40-60% cost savings (long-term)
- Faster innovation
- Global expansion enabled
- Better reliability
Investment required:
- Migration cost: $10-100M (depending on size)
- Time: 2-5 years
- ROI: 2-3 years
Conclusion: The Future is Managed Services
Uber’s journey teaches us:
- Even the most sophisticated companies are moving to cloud
- Uber built one of the world’s best data platforms
- Still chose to migrate to GCP
- Managed services > self-managed at any scale
- Migration is hard but worth it
- 3 years of effort
- $30M migration cost
- $80M/year savings
- ROI in < 18 months
- Focus on your core business
- Uber’s business: Ridesharing
- Not: Running data centers
- Cloud lets them focus on what matters
- The benefits compound over time
- Initial: Just cost savings
- Later: Faster innovation, global expansion
- Long-term: Competitive advantage
The bottom line: If Uber can simplify their infrastructure with cloud, you can too!
Further Reading
- Uber’s GCP Migration Blog Post - Official announcement
- Google Cloud Case Study: Uber - Detailed case study
- BigQuery Documentation - Learn BigQuery
- Dataflow Documentation - Stream/batch processing
- Cloud Migration Best Practices - Migration guide
- TCO Calculator - Calculate your savings
Series Navigation:
- ← Part 1: Building the Original Infrastructure
- Part 2: Modernizing with GCP ← You are here