Parking Lot Manager System Design

By Pradyumna Chippigiri

March 5, 2026

Problem Statement

Design a Parking lot Manager system and implement the data structures for a parking lot. It should support:

Clarifying Questions

Functional Requirements

Non-Functional Requirements

Entities

No need for vehicle entity as we are not storing any vehicle specific information. (in the db, we can just store in a hmap.)

APIs

POST /park
body: {
  vehicleSize: 'MOTORCYCLE' | 'CAR' | 'BUS',
  vehicleNumber: string,
}
 
Success (201) -> spotId: string
 
Failure (409) -> error: 'No spot available for requested vehicleSize'
 
POST /unpark
body: {
  vehicleSize: 'MOTORCYCLE' | 'CAR' | 'BUS',
  vehicleNumber: string,
}
Success (200) -> spotId: string
Failure (404) -> error: 'No vehicle found with the given payload'
GET /available-spots-for-vehicle-size
 
Success (200) -> map of availableSpots: vehicleSize -> availableSpots
Failure (404) -> error: 'No available spots for the given vehicle size'

Implementation Details

Well, so how to go about implementing the backend functions that the api calls are going to call?

Thinking of the data structure, the immediate idea that comes to my mind is to use a hashmap to store a mapping of vehicleNumbers to the ParkingSpot id.

Naive Approach

another naive approach for storing the parkingspots for me would be to use a queue.


Like say for example we have 100 spots, and we have 50 bikes, 40 cars, and 10 buses right. Then i would consider creating 3 queues, one for bikes, one for cars, and one for buses.


The time complexity for both of these approaches is O(1), and the space complexity is O(n) where n is the number of spots. (total 100 in our case.)

Better Approach

in the above approach, we are just popping the spots from the queue without any consideration of the distance from the entry.

So what if we could store the spots in a way that the closest spot is always at the front of the queue?


So how to do this?


We can use a min heap to store the spots.

Maintain priority queues for each vihicle size, and assign spot with minimum distance from entry everytime.


The time complexity for this approach is O(log n) but gives best nearest spot everytime, and the space complexity is O(n) where n is the number of spots. (total 100 in our case.)

Pseudo Code

Say we have a list of spots along with their distances from the entrance, and their sizes, so we can create the priority queues for each vehicle size.

We get this list_of_spots from the database we mentioned in Entities section. (ParkingSpot table)

Constructor(list_of_spots):
    vehicleToSpot = {}                     // license -> (size, spotId)
    spotDistance = {}                // spotId -> distanceToEntrance
 
    bikePQ = MinHeap()
    carPQ  = MinHeap()
    busPQ  = MinHeap()
 
    for each spot in list_of_spots:
        spotDistance[spot.id] = spot.distanceToEntrance
 
        if spot.size == BIKE:
            bikePQ.push( (spot.distanceToEntrance, spot.id) )
        else if spot.size == CAR:
            carPQ.push( (spot.distanceToEntrance, spot.id) )
        else:
            busPQ.push( (spot.distanceToEntrance, spot.id) )

Now for the park a vehicle api, we can do the following:

 
Enter(vehicle_size, license_plate):
    if vehicle_size == BIKE:
        pq = bikePQ
    else if vehicle_size == CAR:
        pq = carPQ
    else:
        pq = busPQ
 
    if pq.isEmpty():
        return NONE
 
    (dist, spotId) = pq.pop()                  // allocate best/closest spot
    vehicleToSpot[license_plate] = (vehicle_size, spotId)
    return spotId

Now for the unpark a vehicle api, we can do the following:

Exit(license_plate):
    if license_plate not in vehicleToSpot:
        return FALSE
 
    (vehicle_size, spotId) = vehicleToSpot[license_plate]
    delete vehicleToSpot[license_plate]
 
    dist = spotDistance[spotId]            // lookup the stored distance
 
    if vehicle_size == BIKE:
        bikePQ.push( (dist, spotId) )
    else if vehicle_size == CAR:
        carPQ.push( (dist, spotId) )
    else:
        busPQ.push( (dist, spotId) )
 
    return TRUE

Now for the get available spots for each vehicle size api, we can do the following:

 
GetAvailableSpots():
    return { MOTORCYCLE: bikePQ.size(), CAR: carPQ.size(), BUS: busPQ.size() }

Rememeber without vehicleToSpot, the exit would not be possible, as we need to know the spotId to free the spot.

HLD

Parking Lot Manager HLD


Thanks for reading! Do subscribe to my newsletter to get notified about new blogs and updates.