YouTube2Text

Basic System Design for Uber or Lyft | System Design Interview Prep — Transcript

by Interview Pen · 3,727 words · 511 segments · language en · Watch on YouTube

Full transcript

  1. 0:00So today we're going to be learning how
  2. 0:01to build a ride sharing service
  3. 0:03something like Uber or Lyft some basic
  4. 0:06requirements for something like this is
  5. 0:07the writer needs to be able to pick a
  6. 0:09point on a map and they need to be able
  7. 0:11to view the ETA and the price at that
  8. 0:13time once they're ready to call the ride
  9. 0:15they need to be able to pay the rider
  10. 0:16needs to be able to be matched to a
  11. 0:18driver and then the driver needs to be
  12. 0:19able to accept the ride and finally the
  13. 0:21rider needs to receive information about
  14. 0:23the driver such as their type of their
  15. 0:25car so they can recognize them and then
  16. 0:27the driver's location needs to be sent
  17. 0:29to the rider in real time so taking a
  18. 0:30look at how we're going to structure a
  19. 0:32system like this we of course need the
  20. 0:34drivers and the Riders and we need a
  21. 0:36database to store all the information
  22. 0:37about them and the trips that they're
  23. 0:39making and then taking a look at our
  24. 0:41requirements there's some other services
  25. 0:42that we're going to need first things
  26. 0:44first we're going to need a map so that
  27. 0:45we can serve maps to the user we're
  28. 0:48going to need a service that knows the
  29. 0:50ETA so we need a ride service that can
  30. 0:52calculate the ETA and has information
  31. 0:54about the locations of every driver
  32. 0:56we're going to need a pricing service
  33. 0:58which is going to calculate the price
  34. 0:59pricing based on load the writer is
  35. 1:01going to need to pay for their ride so
  36. 1:03we need a payment service and the
  37. 1:04drivers and riders need to be matched
  38. 1:06together so we'll introduce a service
  39. 1:07that can handle that putting this all
  40. 1:09together if each service was responsible
  41. 1:11for sending updates to every other
  42. 1:13service that needed information about it
  43. 1:15this would be pretty difficult to do and
  44. 1:17you can see just by the lines I'm
  45. 1:19drawing that this gets pretty messy this
  46. 1:21tightly couples all of our systems so
  47. 1:22for example when a rider requests a ride
  48. 1:24it would need to go out to the matching
  49. 1:26service to get matched to a driver go
  50. 1:28out to the pricing service so the
  51. 1:30pricing service can update its price by
  52. 1:31load it would need to update that in the
  53. 1:33database and then when the driver
  54. 1:35approves it would need to send that
  55. 1:36approval to the rider and to the ride
  56. 1:38service etc etc etc and this is pretty
  57. 1:41difficult to maintain if you're enjoying
  58. 1:42this video we have plenty more awesome
  59. 1:44data structure algorithm and system
  60. 1:46design explanations on interviewpen.com
  61. 1:48you can ask us any questions you have
  62. 1:50about any kind of topics surrounding
  63. 1:52data structures and algorithms and
  64. 1:53system design we released two to four
  65. 1:55videos a week you can run your code you
  66. 1:57can talk to a personalized AI teaching
  67. 1:58assistant and yeah the size pretty great
  68. 2:00anyway enjoy the video so in order to
  69. 2:02solve these issues we're going to
  70. 2:03introduce an event bus the event bus can
  71. 2:05be implemented just with Kafka and
  72. 2:07essentially what it's going to do is
  73. 2:09take information about our Riders and
  74. 2:11our drivers and any real-time updates
  75. 2:13that they make and then any service that
  76. 2:15needs access to that information can
  77. 2:17just subscribe to the event bus and get
  78. 2:19that data so this makes things a lot
  79. 2:20cleaner and much easier to maintain as
  80. 2:23we're building out each of these systems
  81. 2:24so now that we know what sort of
  82. 2:26problems we're solving and the high
  83. 2:27level structure of this system let's
  84. 2:30take a look into each one of these
  85. 2:31issues and see how we can solve this
  86. 2:33problem so first let's take a look at
  87. 2:35our Rider and our driver apis so a
  88. 2:37couple of things that we need to
  89. 2:38consider when we're building these out
  90. 2:39is we need to be able to handle a very
  91. 2:41large number of users accessing these
  92. 2:43apis there's going to be a lot of users
  93. 2:45on our platform and each one of them is
  94. 2:47going to be making multiple requests to
  95. 2:49these apis every single time they make a
  96. 2:51trip so we need to be able to handle
  97. 2:53that load to do that we're going to
  98. 2:54introduce a load balancer in front of
  99. 2:56each of these apis and then we can
  100. 2:57horizontally distribute our API onto
  101. 2:59multiple notes the next thing to
  102. 3:01consider is that there's a lot of
  103. 3:02real-time data going on here so for
  104. 3:04example the driver needs to update the
  105. 3:07location and the rider needs to receive
  106. 3:08updates about that location change in
  107. 3:11real time so one option for this would
  108. 3:12of course be HTTP polling so the writer
  109. 3:14could simply go out to our API say every
  110. 3:17two seconds and then once the driver
  111. 3:19updates the location the writer would
  112. 3:21eventually receive that update this
  113. 3:22introduces a couple of problems the
  114. 3:24first one is there's latency on the
  115. 3:26rider's side so the driver updates the
  116. 3:28location we now have to wait two seconds
  117. 3:30for the next time the rider pulls the
  118. 3:32API in order to get that location update
  119. 3:34and the other problem that's perhaps
  120. 3:35more important is that this introduces a
  121. 3:37huge amount of load on our Rider API
  122. 3:39because now every single user that's
  123. 3:41using our app now has to pull this API
  124. 3:44every two seconds we have to scale this
  125. 3:45API to be huge in order to handle that
  126. 3:48amount of load so a much more scalable
  127. 3:49solution to this problem would be to use
  128. 3:51web sockets websockets enables our Rider
  129. 3:53app to maintain a persistent connection
  130. 3:55with our API and the API can actually
  131. 3:57push data back down to the app this
  132. 3:59means that when the driver updates their
  133. 4:00location for example the rider can
  134. 4:02simply receive that update immediately
  135. 4:04by pushing the data to the app so taking
  136. 4:07a look back at our high level overview
  137. 4:08we can see we've swapped out our API for
  138. 4:11our completed solution so now let's take
  139. 4:13a look at the next piece of the puzzle
  140. 4:15which is the database there's a few
  141. 4:16things that our database needs to hold I
  142. 4:18used to hold information about the
  143. 4:20driver and the rider so they can see
  144. 4:21their own information and also
  145. 4:23information about each other once
  146. 4:24they've been matched and we also need
  147. 4:26information about each trip so drivers
  148. 4:28and Riders will likely want to see their
  149. 4:29own trip history and we need to be able
  150. 4:31to use this record in order to
  151. 4:33coordinate things like matching a driver
  152. 4:35to a rider or coordinating a pickup
  153. 4:37location so for every user we need a
  154. 4:39phone number and a name of course and
  155. 4:42we'll also need an email and a password
  156. 4:43hash that we can use to identify the
  157. 4:45user when logging them in for a rider
  158. 4:47we'll of course need payment information
  159. 4:48so that they can quickly pay for their
  160. 4:50ride and on the driver's side we'll need
  161. 4:52the ride type so for example Uber has
  162. 4:54uberX and Uber black so we need to be
  163. 4:56able to know which designation this
  164. 4:58driver is so we can specify the price
  165. 5:00and we also need information about their
  166. 5:02car so that the rider can identify them
  167. 5:04and finally we need the last known
  168. 5:06location of the driver so that when the
  169. 5:08rider opens the app they can immediately
  170. 5:10see that last location on a map then for
  171. 5:13each trip we need the rider ID and
  172. 5:15Driver ID that that trip has been
  173. 5:17assigned to we need the price and the
  174. 5:19location and destination of the trip
  175. 5:20along with a date we'll also need the
  176. 5:22ride type so we can assign the rider the
  177. 5:25correct driver and we'll also want to
  178. 5:27include a status that says whether the
  179. 5:28drive is in progress canceled completed
  180. 5:31waiting for a driver Etc so I start here
  181. 5:34things that we'll need to query by so of
  182. 5:36course a driver will need to see its own
  183. 5:38information and the writer will also
  184. 5:40need to be able to see its own
  185. 5:41information furthermore for a trip we'll
  186. 5:43want to be able to find the trips that
  187. 5:45are associated with a specific driver or
  188. 5:46a specific Rider we'll also want to be
  189. 5:48able to look up status but only in the
  190. 5:50context of a specific driver or Rider ID
  191. 5:53so for example a common query pattern
  192. 5:55would be show me all of the in-progress
  193. 5:57trips associated with this driver so
  194. 5:59let's take a look at how we'll actually
  195. 6:00structure our database given that
  196. 6:02information it's important to know that
  197. 6:03this is going to be a very high traffic
  198. 6:05database drivers and writers are going
  199. 6:07to be constantly updating this data as
  200. 6:09their ride progresses and furthermore
  201. 6:11the driver is going to be sending
  202. 6:12frequent location updates that need to
  203. 6:15be persisted to the database every
  204. 6:16couple of seconds so it's really
  205. 6:18important that we scale our database
  206. 6:19horizontally and the easiest way to do
  207. 6:21that is with sharding the way sharding
  208. 6:23works is essentially that we can split
  209. 6:25our data onto multiple nodes and each
  210. 6:27node can hold a subset of the data in
  211. 6:29order to determine which node our data
  212. 6:31is actually stored on we can use a Shard
  213. 6:33key when you're looking for a Shard key
  214. 6:34it's important to have high cardinality
  215. 6:36and low frequency and that allows the
  216. 6:38data to be efficiently split across
  217. 6:39multiple partitions so for our trips and
  218. 6:42for our drivers and Riders we'll use ID
  219. 6:44and since this is a unique identifier
  220. 6:46for the trip or driver or Rider this
  221. 6:49satisfies both of these requirements
  222. 6:50furthermore this allows us to quickly
  223. 6:52look up a record by ID because looking
  224. 6:55at the ID we can immediately determine
  225. 6:57which of these nodes the data is on and
  226. 6:59look up their record very quickly
  227. 7:00however we still need to search for
  228. 7:03driver ID and writer ID on our trip so
  229. 7:05in order to do that we're going to
  230. 7:06introduce a global index the global
  231. 7:08index is essentially just another
  232. 7:10Charlotte database where each record
  233. 7:11contains the ID that we're going to
  234. 7:14index on and a reference to the main
  235. 7:17table so for these two Global indexes
  236. 7:19we'll have one that's sharded by driver
  237. 7:22ID and one that's started by Rider ID
  238. 7:24and then within each of these partitions
  239. 7:25we can actually sort the data by the
  240. 7:27status and that will allow us to quickly
  241. 7:29look up by status so to give an example
  242. 7:32if we're looking for in-progress trips
  243. 7:34with a specific driver ID we can use
  244. 7:36that driver ID to immediately determine
  245. 7:38which node the data is stored on and
  246. 7:40then since the data is sorted within
  247. 7:42that partition we can then find the
  248. 7:44records with a specific status very
  249. 7:46quickly let's take a look back at our
  250. 7:47high level overview again we can see
  251. 7:49that our database is now including our
  252. 7:51trips database our writer database and
  253. 7:53our driver database along with the
  254. 7:55indexes that we need to efficiently
  255. 7:56access that data now taking a look at
  256. 7:58the next piece of the puzzle we we can
  257. 8:00look at the map and payments
  258. 8:01infrastructure and see how those will
  259. 8:02work first let's take a look at the map
  260. 8:04there's a few key jobs that the map
  261. 8:06needs to perform the first one is it of
  262. 8:07course these just serve map images to
  263. 8:09the user it needs to perform geocoding
  264. 8:12which means it's converting a street
  265. 8:13address into a latitude and longitude
  266. 8:15that will allow our users to actually
  267. 8:17look up a location that they're going to
  268. 8:19drive to without having to enter a
  269. 8:21specific latitude and longitude for that
  270. 8:23location and we also need to be able to
  271. 8:24get directions and that will allow our
  272. 8:26drivers to pick up our Riders and know
  273. 8:28where to go now we could build our own
  274. 8:30map service however there's a bunch of
  275. 8:33other services out there that already do
  276. 8:35this such as mapbox and Google Maps so
  277. 8:37we'll just use one of those for this
  278. 8:38example taking a look at our payments
  279. 8:39infrastructure the writer of course
  280. 8:41needs to pay for their rides the driver
  281. 8:42needs to get paid and in order to do
  282. 8:44this we could again build our own
  283. 8:46payments infrastructure or we could
  284. 8:47simply use one of many solutions out
  285. 8:49there such as stripe if you're
  286. 8:50unfamiliar with stripe the way that it
  287. 8:52works is a user can push a payment to
  288. 8:55stripe and then once the payment
  289. 8:56finishes processing stripe will call a
  290. 8:58web hook that we set setup so in our
  291. 9:00situation the user is going to pay for
  292. 9:02their ride stripe will send an update to
  293. 9:04this web hook and then our web hook will
  294. 9:05add an event to our Kafka event queue so
  295. 9:08that we can continue processing the ride
  296. 9:10so looking at this entire thing in
  297. 9:12context we can see that we're using
  298. 9:13mapbox for our map service and we can
  299. 9:15see that stripe and our web hook are
  300. 9:17then pushing information to our Kafka
  301. 9:19event bus you'll notice that all of
  302. 9:21these services are attached to the
  303. 9:23client side of our Rider and drivers and
  304. 9:26that's because stripe and mapbox are
  305. 9:27both designed to interact directly with
  306. 9:29a client for the map of course there's
  307. 9:30no authorization necessary because it's
  308. 9:32all it's doing is serving map tiles and
  309. 9:35looking up locations and for stripe any
  310. 9:37processing that we'll do to make sure
  311. 9:39that the user paid the right amount for
  312. 9:41example will be done within this web
  313. 9:42hook so the next problem we need to
  314. 9:44solve is the pricing model so pricing
  315. 9:46for Uber for example varies by demand
  316. 9:48they call this surge pricing at Uber the
  317. 9:51way it works is essentially if there's
  318. 9:53higher demand in an area for example a
  319. 9:55concert just ended and 200 people are
  320. 9:58all trying to call an Uber were from the
  321. 10:00same location they're actually going to
  322. 10:01increase the price in order to take
  323. 10:03advantage of the higher demand so in
  324. 10:04order to actually calculate price in
  325. 10:06this situation we need information about
  326. 10:08demand and processing every trip in
  327. 10:10batch would be far too slow for us so
  328. 10:12let's take a look at how we can
  329. 10:13Implement a streaming pipeline to make
  330. 10:15this actually work so our price API of
  331. 10:17course needs to be able to get
  332. 10:18information about demand and we're going
  333. 10:20to store that demand in a redis
  334. 10:22in-memory database so we can access it
  335. 10:24very quickly then in order to get the
  336. 10:25demand data into redis we're going to
  337. 10:27use spark spark if you're unfamiliar is
  338. 10:29a distributed data analytics engine and
  339. 10:32it essentially allows you to take in a
  340. 10:33data set and then perform various
  341. 10:35queries on it such as filtering sorting
  342. 10:38aggregating grouping and joining things
  343. 10:40together if you've ever used the pandas
  344. 10:43python Library spark is a lot like that
  345. 10:45except that it allows jobs to be
  346. 10:46distributed across a bunch of workers so
  347. 10:48the way we're going to use spark is with
  348. 10:50a separate feature that it has called
  349. 10:52structured streaming structured
  350. 10:53streaming allows spark to subscribe to a
  351. 10:56Kafka event bus and then whenever it
  352. 10:58receives an event it will process that
  353. 11:00in a streaming fashion and then push the
  354. 11:03resulting data to some other data source
  355. 11:05so for our example we'll have ride
  356. 11:07requests that are an event in our Kafka
  357. 11:09event bus spark will subscribe to those
  358. 11:11events aggregate them based on time and
  359. 11:13location and push them to this redis
  360. 11:15database so taking a look at our whole
  361. 11:17solution now we can see that spark is
  362. 11:20now subscribed to our Kafka event bus we
  363. 11:22can see that our drivers can now access
  364. 11:25this price API to get access to the
  365. 11:28calculated price given the load and our
  366. 11:31drivers can now access the pricing API
  367. 11:33which will calculate the price based on
  368. 11:35load so now let's finally take a look at
  369. 11:37the last piece which is the rides and
  370. 11:39matching services so for rides there's a
  371. 11:41couple of very simple things that it
  372. 11:42needs to do it needs to efficiently find
  373. 11:44drivers in a given area and it needs to
  374. 11:47calculate the ETA for the ETA that's a
  375. 11:49pretty simple problem we just need some
  376. 11:51sort of service that can make that
  377. 11:52calculation we could either build our
  378. 11:54own service that takes into account
  379. 11:55demand and other characteristics about
  380. 11:57the driver or we could simply use mapbox
  381. 12:00or Google Maps like we showed in the map
  382. 12:02service for driver locations however
  383. 12:04this is an interesting problem we don't
  384. 12:06know the exact location of the driver
  385. 12:08we're looking for we only know that we
  386. 12:09want to find one that's in some radius
  387. 12:11of where the rider is so we can't just
  388. 12:14index based on the exact location we
  389. 12:16need some way to index off of an area so
  390. 12:18to do that we're going to use an
  391. 12:20algorithm that Uber developed called H3
  392. 12:22and what H3 does is it splits the world
  393. 12:25into a bunch of hexagonal areas and it
  394. 12:27assigns an ID to each one of these cells
  395. 12:30then it groups all of the drivers into
  396. 12:32these cells so we can efficiently look
  397. 12:34up a specific cell and all the drivers
  398. 12:37within it there's a couple of
  399. 12:38interesting points about cell IDs first
  400. 12:40one is that they can be calculated from
  401. 12:41longitude and latitude so if I'm a
  402. 12:43writer here I can see that I'm in cell D
  403. 12:45and I can efficiently look up that cell
  404. 12:47another interesting point is that one
  405. 12:49sale ID can be used to calculate
  406. 12:51adjacent cell IDs so if I'm in cell D I
  407. 12:53can look up all the other cells around
  408. 12:55it based on that so if I'm a writer
  409. 12:57located here I can simply look up all
  410. 13:00seven of these hexagons then I can draw
  411. 13:02a circle around me and I can find all of
  412. 13:05the rides that are within that radius
  413. 13:07then using the ETA service that we have
  414. 13:10here we can look up the ETA for each one
  415. 13:12of those and find out which one is
  416. 13:13closest to us now taking a look at how
  417. 13:15we actually match a rider to a driver we
  418. 13:18simply need to subscribe to the event
  419. 13:19that a rider requests a ride and then
  420. 13:21once that happens we can find the
  421. 13:23closest driver using our ride service
  422. 13:25that we just talked about and then we
  423. 13:26need to tell the driver API to either
  424. 13:28accept or decline the ride if they
  425. 13:30accept we need to notify the rider who
  426. 13:32can then look up information about the
  427. 13:34driver and the driver needs to get
  428. 13:36directions to the pickup location and if
  429. 13:38the request is declined we need to
  430. 13:39Simply repeat this whole process for the
  431. 13:41next closest driver so taking a look at
  432. 13:42our entire system here we can see that
  433. 13:44we have all of the parts completed let's
  434. 13:45just do another quick overview of
  435. 13:47everything that happens when we're using
  436. 13:49this system a driver is going to be able
  437. 13:51to use a map to find a specific location
  438. 13:53they can then go out and they can find
  439. 13:55the price at that given location and
  440. 13:57they can use this ride server us to find
  441. 14:00the ETA and then once they're ready they
  442. 14:02can pay using stripe and they can be
  443. 14:04matched to a driver using the matching
  444. 14:06service all of this data will be
  445. 14:07persisted to this database to be looked
  446. 14:09up later and real-time updates about the
  447. 14:11driver's location can be sent to the
  448. 14:13rider through this event bus so this is
  449. 14:15a working solution but there's a ton of
  450. 14:17ways that we can dig deeper and find
  451. 14:19better ways to optimize and make this
  452. 14:21whole system more efficient so a couple
  453. 14:23of things that we didn't look into in
  454. 14:24this video but you're certainly welcome
  455. 14:26to dig into yourself if you're curious
  456. 14:27first one is math we didn't really do
  457. 14:30any math to see how much we need to
  458. 14:32scale all of our systems but there's
  459. 14:34there's certainly some numbers that can
  460. 14:36be crunched if you're curious about how
  461. 14:38this scales we also didn't discuss
  462. 14:40redundancy but that's a very important
  463. 14:41consideration we need to make sure that
  464. 14:43if any one of these pieces fails that
  465. 14:45our drivers and Riders can continue
  466. 14:47riding and if the rider can safely get
  467. 14:49to their destination in the event of any
  468. 14:51system failures some other interesting
  469. 14:53things to take a look at are algorithms
  470. 14:54for calculating an ETA we mentioned that
  471. 14:56it would be possible to build our own
  472. 14:58ETA service that take takes into account
  473. 14:59various other characteristics about a
  474. 15:01driver so looking into the algorithms
  475. 15:03that services like uber and Lyft use to
  476. 15:05actually do that would be very
  477. 15:07interesting another thing that's really
  478. 15:08important for companies like uber is
  479. 15:10data analytics so having some sort of
  480. 15:12pipeline setup that can persist data to
  481. 15:15some sort of data warehouse and allow
  482. 15:16employees to analyze the data and make
  483. 15:19optimizations to this system is super
  484. 15:21important we also talked about sharding
  485. 15:23our database of driver locations but
  486. 15:25there's a lot of algorithms that can be
  487. 15:26used to make sure that the data is
  488. 15:28geographically located close to where
  489. 15:30the user is going to be requesting it
  490. 15:32from and that cells that are close to
  491. 15:34each other are actually located in nodes
  492. 15:36that are close to each other there's a
  493. 15:37ton of other ways that you can dig in
  494. 15:38and find different ways to optimize and
  495. 15:40make the solution better and I certainly
  496. 15:42invite you to do so if you enjoyed that
  497. 15:43video you can get a lot more content
  498. 15:45just like this on interviewpen.com WE
  499. 15:48publish two to four videos a week really
  500. 15:49it's just an arbitrary number it's
  501. 15:51whenever I can sit down and do a video
  502. 15:53because these videos take a whole day to
  503. 15:55do and we're always online to answer any
  504. 15:57questions you may have join our Discord
  505. 15:59join our newsletter the blueprint where
  506. 16:01you can get more weekly data structure
  507. 16:03and algorithm and system design kind of
  508. 16:04topics and subscribe and like this video
  509. 16:07if you actually like this video and it
  510. 16:08helped you and also tell a friend that
  511. 16:10we exist that's all

About this transcript

This page contains the full transcript of Basic System Design for Uber or Lyft | System Design Interview Prep by Interview Pen, generated from the public captions YouTube serves with the video. The transcript has 3,727 words across 511 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.

What you can do with it

Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.

Free YouTube transcript tool

YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.