Functional Features:

  1. User can reserve a parking spot.
  2. User pays for the reservation.
  3. User can park a car on the parking spot.
  4. User can leave before the reservation time expires.
  5. One common error case to handle is when a user makes a reservation, but fails to show up. In this case, we would charge for the first 24 hours.


Non-Functional Features:


  1. Scalability - our system should able to handle 1000 request over the world.
  2. Availability - system should has up time 99%.
  3. Consistency - should not be double booking of the same park spot.


Capacity estimation

I assume:

  • The company has operations in 10 countries.
  • The company has 100 parking lots, on average, in one country.
  • On average, each parking lot has a capacity of 200 cars.
  • 80% of users use it for short term parking, averaging 4 hours.
  • 20% of users use it for long term parking, averaging 5 days.
  • Each parking lot has 200 parking spots on average.
  • Each parking lot receives 200 reservation requests per day.


Estimation:

  • 10 * 100 = 1000 parking lots.
  • The system receives 200 * 1000 = 200K reservation requests per day.
  • Each reservation would mainly consists of:
    • Reservation ID (8 bytes)
    • User ID (8 bytes)
    • Car type (1 byte)
    • Reservation start time (8 byte)
    • Reservation end time (8 byte)
    • Roughly speaking, let's assume this would total 128 byte in total.


  • Each day, we will add 200K * 128 = 25.6MB of data.
  • In 2 years, it would add up to 25.6 * 365 * 2 * 1.5 = 280 GB (assuming future growth




API design

API used by user:

checkCapacity(lot_id, vechile_type, start_time, end_tine) [is_free, price] - checks if parking lot has a free spot and returns price


reserveSpot(user_id, lot_id, vechile_type, start_time, end_time) -

returns reservation_id and price. Also forwarded on 3d party payment system.


completeReservation(reservation_id, payment_token) - after payment we need to complete payment procedure


API used by parking lot:

vechile_arrived(reservation_id, time)

vechile_left(reservation_id, time)






Database design

Reservation table:

  • reservation_id(key)
  • spot_id(foreign key)
  • user_id(foreign key)
  • payment_status
  • start_time
  • end_time
  • status

User table:

  • user_id(key)
  • info

Vechile table:

  • vechile_id(key)
  • user_id(foreign key)
  • type

Spot table:

  • spot_id(key)
  • lot_id(foreign key)

Lot table:

  • lot_id(key)
  • capacity





High-level design

Parking lot - notifies when car arrive or left

Client - user , that wants to get parking spot

Api gateway - mediator fro http requests

Reservation service - checks for empty place and update reservation in database

Payment service - 3d party for payments

healthcheck monitor - checks if all components of our system are available

cache - caching most use data to reduce latency reading from database




Request flows

checkCapacity request handles by reservation service. It checks if we have an empty spot.

reserveSpot request - handles by reservation service. Adds. a new reservation in the system and redirect user for payment service.

completeReservation - after payment, user confirms that spot was paid by token.


vechile_arrived - notifies, when car arrived on parking lot.

vechile_left- notifies, when car left from parking lot.





Detailed component design

For reservation we can use first fit slot allocation or time-slot reservation with time intervals or bitmap approach to achieve time complexity O(1)



Trade offs/Tech choices

Nosql db provides good horizontal scaling, but for us most important to have consistency, I mean we should prevent double booking of the same spot. SQL BD it is good choise , for instance PostgresSql





Failure scenarios/bottlenecks

Backend service are stateless. DB will be a bottleneck , it will difficult to scale. We can partitioned DB by parking id. Also we should use some heathcheck system.


In case of db crashes , would be better to use master-slave db approach with replication of db instances.





Future improvements

I believe that we use need to use CDN