Requirements


Functional Requirements:


  • Allow reservation of a parking spot.
  • Process payment for the reservation.
  • Enable parking of a car in the reserved spot.
  • Support early departure before reservation time expires.
  • Gate check-in/out.
  • Handle no show.



Non-Functional Requirements:


  • Needs to be consistent (need to handle multiple attempts of reserving the same parking spot at the same time)
  • Needs to be reliable (needs servers to always be up)


Capacity:


  • Assume we need to handle about 500 million parking lots around the world
  • Assume every parking lot can hold about 100 cars
  • Assume users park and depart around 5 times a second
  • Assume users reserve around 10 times a second


(5 cars parking and departing/second) * 60 seconds * 60 minutes * 24 hours * 365 days * 5 years = 788 million

Assume every database entry is about 500 bytes = 394 GB


(10 users reserving/second) * 60 seconds * 60 minutes * 24 hours * 365 days * 5 years = 1.6 billion

Assume every database entry is about 500 bytes = 788 GB


API Design


  1. reserveParking API
    1. Request: { userId: string, parkingLotId: string, parkingSpaceId: string, reservationTimeStart: DateTime, reservationTimeEnd: DateTime }
    2. Response: None
  2. getReservations API
    1. Request: { userId: string }
    2. Response: { parkingLotId: string, parkingSpaceId: string, reservationTimeStart: DateTime, reservationTimeEnd: DateTime }
  3. parkCar API
    1. Request: { userId: string, parkingLotId: string, parkingSpaceId: string }
    2. Response: None
  4. departCar API
    1. Request: { userId: string, parkingLotId: string, parkingSpaceId: string }
    2. Response: None
  5. checkInGate API
    1. Request: { userId: string, parkingLotId: string, time: DateTime }
    2. Response: None
  6. checkOutGate API
    1. Request: { userId: string, parkingLotId: string, time: DateTime }
    2. Response: None


High-Level Design


The client will connect to a load balancer to balance the requests made to the server. Client will also connect to CDN to access static content for better performance.


The load balancer can direct to the server which points to different services. We will have the reservation service which will handle all reservations and payment related actions. We handle both in the same service so that if payment fails, reservations should also fail. We will store in the database that the user made a reservation.


If user arrives at the lot, the lot will access the CheckIn Service to check the user into the lot. If the user leaves the lot, the lot will access the CheckIn Service to check the user out of the lot.


Once user parks, the lot will access the Parking Service to mark in the database that the user has parked.


Detailed Component Design

Deep dive into 2-3 key components. Explain how they work, how they scale, discuss tradeoffs, capacity, and any relevant algorithms or data structures.


Reservation Service

  • Functionality
    • Handles both reserveParking and getReservations APIs to reserve a parking spot for a user and can also fetch the reservation information so the user can view it at any time. Payment is handled in reserveParking so that payment fails, reservation will also fail. Information will be written to the database.
    • Tech Choice: Amazon RDS

Parking Service

  • Functionality
    • Handles parkCar and departCar APIs to track when a user has parked their car during their reserved time and when they choose to leave. Information will be written to the database.
  • Tech Choice: Amazon RDS

CheckIn Service

  • Functionality
    • Handles when a user has arrived at a parking lot and when they have left the parking lot. Information will be written to the database.
  • Tech Choice: Amazon RDS


TradeOffs/Tech Choice:

  • I have decided not to go with a cache and sacrifice performance, because we want the most up to date data for a specific parking lot and spot. If multiple users are attempting to park at the same spot at too similar of a time, we may be giving them stale data.
  • I have went with a relational database over a nonrelational one because I have chosen to prioritize consistency over speed and scalability. We want our parking lot to always have the correct information, otherwise users may park in the same spot as another user.