List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Consistency
Availability
Estimate the scale of the system you are going to design...
Define what APIs are expected from the system...
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"
}, {...}]
}
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"
}, {...}]
}
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
}, {...}]
}
GET /api/v1/cities/{city}/{building}
Response Code: 200 OK
Response Body : {
"levels": [{
"levelCode": "reston-20191-BLD-01-LVL-01",
"slots": 200,
"openSlots": 100
}, {...}]
}
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"
}, {...}]
}
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
}
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...
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...
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...
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...
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,
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;
}
Concurrent requests for a single parking slot may occur in below scenarios
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
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.
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?