My Solution for Design an Efficient Parking Lot System with Score: 9/10

by expanse_jubilee979

System requirements


Functional:

List functional requirements for the system (Ask the chat bot for hints if stuck.)...

  1. User pre-books a parking slot or drive-in to a facility
    1. if drive-in the automated kiosk issues a ticket based on the selection by user
    2. if pre-book user needs to self register and register the vehicle
  2. Facilities are multi-level with multiple entrances at the lower floor
  3. Each facilities have a disability parking slots at lower level - let captain park near an entrance

System Requirements

  1. A vehicle can be of types - Bike, Car, Bus, Truck
  2. Parking spaces are - small, medium, large, XLarge, the vehicles are fit based on their size
  3. Clients to the system are kiosk at entrances, mobile and web


Scope

  1. Manage booking, reservation, occupancy, cancellation and free-up slots on exit
  2. The kisok transmits availability to nearby display boards in each level by local networking
  3. Vehicle of a specific size can be parked in a slot of similar size - medium sized vehicle is parked in medium slots
  4. Booking at Entrance or via mobile/web doesnt collide and handle concurrent requests
  5. Fairness - if a slot is taken the next request in line is allowed to book, like a queue, slot is not allocated to random request



Out of scope

  1. Kiosk is a software and local networking, emitting availability to local display boards
  2. Payment and surge pricing
  3. Electric vehicle and electric vehicle parking slots are not considered
  4. Reservation history & Booking history is not maintained
  5. Vehicle is allocated for the right spot with size in consideration



Non-Functional:

List non-functional requirements for the system...

  1. Fairness - Vehicles are parked in the right sized spots, in case of multiple requests the slots are allocated as first come first serve. When handling concurrent request, the first request will be booked and system will suggest a new slot for the second request.
  2. Consistency - the spots are marked available/not available even though spots are allocated from multiple entrances, system maintains integrity. Two cars appearing from two different entrances should not be allocated to a same slot


Consistency

  1. The booking, reservation status are updated in the database, the database deployed in a master and standby with synchronous communication.

Availability

  1. The services - reservation, booking service, notification are deployed in a managed kubernetes environment to ensure the system is available for responding to booking, reservation and slot availability queries.
  2. Redis in clustered mode is deployed to maintain faster reads (slots, metadata of city, area, building) and writes (mark a slot as taken)



Assumptions

  1. Parking lot city/area/building/slots are pre-defined and slots are marked with sizes
  2. Each building has multi-level parking facility
  3. Each booking of a slot is min 1hr


Capacity estimation

Estimate the scale of the system you are going to design...

  1. City - 10 cities, each city has 10 areas
  2. Building - each area has 10 buildings
  3. Level - each building has 10 levels
  4. Slots - each level has 200 slots resulting
  5. Total slots in a building - 200 slots x 10 levels = 20K slots
  6. Total slots in an area - 20K slots x 10 buildings = 200K slots
  7. Total slots in a city - 200K slots x 10 cities = 2M slots
  8. When a building is onboarded for managing slots, the slots are classified as
    1. 10% disabled parking - 2000 slots
    2. 10% small vehicle slots in each floor (hatchback, cooper) - 2000 slots
    3. 20% medium vehicle slots (sedans) - 4000 slots
    4. 40% large slots (Caravans) - 8000 slots
    5. 20% extra large slots (Bus) - 4000 slots


API design

Define what APIs are expected from the system...


City API

GET /api/v1/cities Response Code: 200 OK Response Body : { "cities": [{ "cityCode": "reston", "lat": 71.6, "long": 71.6, "areas": 10, "slots": 200000, "openSlots": "100000" }, {...}] }



Areas API

GET /api/v1/cities/{city} Response Code: 200 OK Response Body : { "areas": [{ "areaCode": "reston-20191", "areaName": "reston town center", "lat": 74.6, "long": 74.6, "buildings": 10, "level": 10 "slots": 20000, "openSlots": "10000" }, {...}] }



Building API

GET /api/v1/cities/{city}/{area} Response Code: 200 OK Response Body : { "builldings": [{ "buildingCode": "reston-20191-BLD-01", "lat": 75.6, "long": 75.6, "levels": 10, "slots": 2000, "openSlots": 1500 }, {...}] }




Level API

GET /api/v1/cities/{city}/{building} Response Code: 200 OK Response Body : { "levels": [{ "levelCode": "reston-20191-BLD-01-LVL-01", "slots": 200, "openSlots": 100 }, {...}] }


Slot API

GET /api/v1/cities/{city}/{building}/{level} Response Code: 200 OK Response Body : { "slots": [{ "slotCode": "reston-20191-BLD-01-LVL-01-SLT-01", "disabledAccessiblity": false, "status": "open" }, {...}] }


Reservation API


Reserve a slot


POST /api/v1/reservations Request Body: { "levelCode": "reston-20191-BLD-01-LVL-01", "expectedTime": "1747723584", //Tuesday, 20 May 2025 12:00:00 GMT+05:30, "vehicle": { "licensePlate": "ABC", "size" : "medium", } } Response: 202 Accepted, Response Body : { "acknowledgementId": "12345" "entryTime": "1747723584", "parkingSlot": { "slotId": "reston-20191-BLD-01-LVL-01-SLT-01", "levelCode" : "BLD-01-LVL-01" } "status": "allocating" // enum - confirmed, waiting, cancelled }



Database design

Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...




High-level design

You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...


  1. Web Client - uses websocket to pull available cities, areas, buildings, levels and slots in each cities/areas/buildings/levels. This is
  2. Mobile Client -uses HTTP polling over REST APIs for reservation, looking up slots, available slots. The notification about reservation status, booking confirmation are pushed to mobile and the client does HTTP polling for receiving updates.
  3. Kiosk - uses websocket to pull information about levels, slots, availability of slots. A kiosk is always stationed in an entrance in a building and can maintain persistent connection
  4. Websocket API - A two way asynchronous communication channel through which the mobile/web client gets availability information as well as booking information
  5. Availability service - Gets available cities/areas/buildings/levels/slots, with overall count of slots available, and count of free/open slots
  6. Reservation Manager - accepts a reservation request and push it to a broker for asynchronous processing
  7. Broker - A kafka broker that has topics as below,
    1. reservation - topic has reservation requests
    2. booking - topic has booking results
  8. Booking Service - Service attempts to book a slot, it subscribes to broker and listens to reservation topic and attempts to book a slot. Also it takes direct booking request from API gateway and attempts to book a slot synchronously. Once booked or failed to book, a message is sent to topic "booking" as well as update the reservation/booking tables
  9. Notification - service listens to broker topic "booking" and send out notifications to mobile/kiosks (via FCM/APN), for web clients send out a websocket reply for the booking/reservation status
  10. Cache - A Redis cache enabled with RedisSearch + Geo maintains,
    1. Facility metadata - of all available parking facilities - by city, area, building, levels and slots. This is maintained for faster look up by city, area, building, no of levels, no of slots, this info doesnt contain live availability status
    2. Occupancy - per slot availability for the day in a key "occupancy:<city><area>:<building>:<level>:<slotId>:<day>: <interval> 1 or 0". 1 indicates. occupied and 0 indicates open




Request flows

Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...







Detailed component design

Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...


Booking a Slot

The concept here is to use a Bitmap for each slot for faster writes and low latency reads. The idea is to use a BitMap with 96 bits (12 bytes) for each slot, initially all bits of a slot are 0. How did we get into 96 bits, each day is divided into 15mins intervals i.e. 60 x 24 / 15 = 96 intervals. Each bit represents a 15 min interval, each bitmap represents a day for the slot.


When a vehicle crosses the entry barricade, a booking is made for a slot for an interval, say 1hr from 10:00 AM, four bits from 40 to 43 are set to 1 (booked for 1 hour).


When the vehicle reaches the exit barricade, the kiosk records the exit time, say 11:00 AM, the booking is termed as closed i.e slots from 44 till 96 continues to be 0s.


No Show: When there is booking made for a slot, for the expected time of entry, say 11:00 AM, the respective bit 44 is set to 1. If the vehicle fails to enter the facility (the entry kiosk) before 11:16 AM, the reservation is cancelled and following bits from 45 continues to be 0s, i.e. the slot is blocked only for 15 mins post the expected time of entry. The system may charge 25% percent of 1 hr charge as a fee.




For instance in java, (Redis needs a lua script for atomic updates)

BitSet slot = new BitSet(96); public Ticket book(int startInterval, int endInterval) { slot.set(startInterval, endInterval); return new Ticket(ticketId, slotDetails); } public boolean release(int startInterval, int endInterval) { slot.clear(startInterval, endInterval); return true; }


Handling Concurrency

Concurrent requests for a single parking slot may occur in below scenarios

  1. While a vehicle is at the entry and a reservation request is attempted by the system
  2. When a building has two entrances and two vehicles attempt to book a slot at the same time


Both of these scenarios are handled by locking mechanism in Redis slot record i.e. all the clients generate a reservation request using a /reservation API, this results in a reservation request message in Kafka topic which is time ordered. The kafka topic is partitioned by "slotId" maintaining the time ordering. The consumer service (booking service) reads the request sequentially (time ordered) and while fulfilling the request, lock the slot record in Redis, modify the slot to occupied and update the reservation table in the database. This has a additional network call to update two places (redis and database) however this is required to make system consistent.


For instance three clients (web, mobile and kiosk) makes the request as below,


Time 1 slot:007 RESERVE_REQ client_A Time 2 slot:007 RESERVE_REQ client_B Time 3 slot:007 RESERVE_ACK client_A


Kafka Topic, Partition and Consumer groups

For reservation, we have one topic called "reservation", and 2500 partitions to handle high traffic load and enable parallelism. Here we have 20 instances of BookingService forming under one consumer group "booking-consumer" making 125 partitions per consumer.


The booking service picks the message at Time 1 and honours the request. When it sees that request at Time 2 for same slot:007, which is already occupied then it makes an attempt to suggest a new slot by initiating a notification back to the client.



Trade offs/Tech choices

Explain any trade offs you have made and why you made certain tech choices...

  1. TradeOff - Wastage of a slot on No Show - when a user reserves a slot and booking is confirmed for the slot, the slot is blocked for 15 mins. If the vehicle does not turn up then the slot remains blocked and it causes a wastage of resource. However the user may be charged for a nominal fee for 15 mins. When a next reservation comes up or next booking request comes up the status of a slot is checked, if it was no show then this charge could be initiated. Running a scheduled Job to. detect and handle such scenarios requires additional components which incurs additional infra costs. Instead, it could be verified whenever a booking for a slot in the same building is attempted
  2. Trade Off - Using a sensor per parking lot is ideal way to handle no-show or occupied or free spots, however this will create high traffic onto the system, as well as additional components and ensuring its availability to handle those messages, increases I/O, network calls, MQTT channel cost, sensor cost and maintenance cost which is way too high than the cost of wasting a parking lots 15 mins.
  3. Database - mongodb with flat collection structure for holding metadata of city/area/building/slots and its geo location.
  4. Cache: Redis with Redis Geo and Redisearch - Redis is used for tracking occupancy, geo location and geo queries. This is loaded onto redis from mongodb on system startup. Since redis is faster in lookup and metadata setup is not often updated, this serves the purpose of finding nearest parking lots much faster.
  5. Broker - Kafka for ensuring message delivery and order of processing
  6. Database - Mongodb for reservation, booking, parking metadata. These are loaded onto Redis, the slot availability are set at Redis first and followed by mongodb




Failure scenarios/bottlenecks

Try to discuss as many failure scenarios/bottlenecks as possible.


  1. Notification on mobile/kiosk/web about booking/reservation status is asynchronous, if the client is out of network or unreachable, the client might miss the notification.
  2. Duplicate booking requests - if the client requests for the slot again the system will end up processing the request to finally decide that its a duplicate request. Avoid duplicate request before posting a message in kafka
  3. Rare case of booking loop while attempting to be fair - when handling concurrent requests, the system honours the first request (book the slot) and suggests another slot on the same building or nearby building for the second request. The client might accept to book the suggested slot, however in heavy traffic scenarios there may be another request already in the pipeline for the suggested slot, which was never seen by the booking service. This might create a loop and finally the user might get frustrated. There can also be a scenario where multiple suggestions for the same slot is send to multiple users which will also create a race condition and loop





Future improvements

What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?


  1. Verify whether the vehicle with the expected license plate is parked in the parking slot. Take additional steps of impounding vehicle/charge additional amount if violated
  2. Sensor approach - install sensor that can emit whether the parking lot is available or not, the sensor is installed in each parking slot for live updates of parking slot availability status
  3. Security - JWT token authentication via Load balancer,
  4. Monitoring & logging - at load balancer and other components in the system
  5. Rate limit - handle DoS/DDoS, spam requests on all APIs
  6. User Experience
    1. User can search for a parking slot nearby, the system responds with buildings with parking facilities in the near vicinity (5 miles) sorted by nearest to 5 miles
  7. Handle system fairness on concurrent requests - honour next request in line
  8. Predictive recommendations by looking at the booking logs - helps users book in advance or hints about booking traffic spikes