LLD CASE STUDIES / OBJECT DESIGN BRIEF

Design a parking lot

Designing a parking lot is the most common LLD interview question.

IntermediatePhase 09 / Topic 1 of 10ResponsibilitiesCollaborationsExtensibility
01

Overview

Designing a parking lot is the most common LLD interview question. It tests whether you can turn vague requirements into entities, responsibilities, relationships, and extensible behavior, then write clean code for the core flows.

The key flows are parking a vehicle (find a compatible free spot and issue a ticket) and exiting (calculate the fee, take payment, and free the spot). Good designs keep spot allocation and pricing replaceable.

A hotel front desk

Guests (vehicles) arrive, the desk finds a suitable room (spot), hands over a key card (ticket), and charges by nights stayed (duration) at checkout. The room assignment rule and pricing can change without redesigning the hotel.

02

Requirements to clarify first

  • Multiple floors, each with spots of types: motorcycle, compact, large, and electric.
  • Vehicles: motorcycle, car, truck. A vehicle can only use compatible spot types.
  • Entry issues a ticket; exit calculates a fee by duration and accepts payment.
  • Show available spots per floor and type. Support multiple entry and exit gates concurrently.
03

Where it shows up in interviews

Resource allocation

Recognize it when: assign limited slots to incoming requests.

  • Design a parking lot
  • Design a movie ticket system
  • Design an elevator system
Extensible pricing and allocation

Recognize it when: rules will change over time.

  • Add EV spots and weekend pricing
  • Design a multi-lot parking service
04

Where it is used in real software

Airport and mall garages

Systems like SKIDATA and ParkMobile issue tickets, track occupancy per level, and compute time-based fees.

Occupancy displays

Sensors publish spot availability to signs on each floor (Observer).

Dynamic pricing

Cities like San Francisco (SFpark) adjust parking prices by demand.

05

Key terms

ParkingLot
Top-level facade with floors, gates, and the park/exit operations.
ParkingSpot
Has an ID, type, and current vehicle or null.
Ticket
Links a vehicle, a spot, and an entry time.
SpotAllocationStrategy
Chooses which free spot to assign (nearest, lowest floor, etc.).
PricingStrategy
Calculates the fee from ticket and exit time.
06

Interview approach

  1. 1
    Clarify scope

    Confirm vehicle types, spot types, pricing model, payments, and concurrency. State non-goals such as reservations.

  2. 2
    Identify entities

    ParkingLot, Floor, ParkingSpot, Vehicle, Ticket, Payment, Gate.

  3. 3
    Assign responsibilities

    Spots know if they fit a vehicle. Floors track free spots. The lot coordinates allocation, tickets, and exit.

  4. 4
    Extract what varies

    Allocation and pricing are strategies so new rules do not change the lot class.

  5. 5
    Handle concurrency

    Two gates must never assign the same spot; lock or atomically claim spots.

  6. 6
    Walk through flows

    Trace park and exit end to end, including the lot-full and invalid-ticket cases.

07

Vehicle to spot compatibility

Smallest fitting spot first to preserve large spots

Step 1 / 4
VehicleAllowed spots (in preference order)
MotorcycleMotorcycle, Compact, Large
CarCompact, Large
Electric carElectric, Compact, Large
TruckLarge

NOWVehicle: Motorcycle | Allowed spots (in preference order): Motorcycle, Compact, Large

Encoding compatibility in one table means adding a new vehicle type is a data change, not a rewrite of allocation logic.

08

Implementation

enum VehicleType { Motorcycle = "MOTORCYCLE", Car = "CAR", Truck = "TRUCK" }enum SpotType { Motorcycle = "MOTORCYCLE", Compact = "COMPACT", Large = "LARGE" } const COMPATIBLE: Record<VehicleType, SpotType[]> = {  [VehicleType.Motorcycle]: [SpotType.Motorcycle, SpotType.Compact, SpotType.Large],  [VehicleType.Car]: [SpotType.Compact, SpotType.Large],  [VehicleType.Truck]: [SpotType.Large],}; class Vehicle {  constructor(readonly plate: string, readonly type: VehicleType) {}} class ParkingSpot {  private vehicle: Vehicle | null = null;  constructor(readonly id: string, readonly type: SpotType, readonly floor: number) {}   get isFree() { return this.vehicle === null; }  canFit(vehicle: Vehicle) { return this.isFree && COMPATIBLE[vehicle.type].includes(this.type); }  assign(vehicle: Vehicle) {    if (!this.canFit(vehicle)) throw new Error(`Spot ${this.id} unavailable`);    this.vehicle = vehicle;  }  release() { this.vehicle = null; }} class Ticket {  constructor(    readonly id: string,    readonly vehicle: Vehicle,    readonly spot: ParkingSpot,    readonly entryTime: Date,  ) {}}
09

Complexity and performance

Find spot (scan)O(spots)

Fine for a few thousand spots.

Find spot (indexed)O(1)

Keep a free-spot queue per floor and type.

ExitO(1)

Ticket lookup by ID in a map.

10

Trade-offs

Scan vs free lists

Scanning is simple and correct. For large lots, maintain a queue of free spots per type so allocation is O(1), at the cost of keeping it in sync.

Where pricing lives

As a strategy, pricing can change (weekend rates, subscriptions) without touching the lot. Putting it in Ticket couples data to business rules.

In-memory vs persistent

Interviews usually model in memory. In production, spots and tickets live in a database, and atomic updates prevent double assignment.

11

Variants and related techniques

Reservations

Add a Reservation entity with a time window; allocation skips reserved spots.

EV charging

Add an Electric spot type and a charging fee added to the pricing strategy.

Display boards

Use the Observer pattern: floors publish availability changes to display boards.

12

Common mistakes

  • Putting all logic in ParkingLot.

    Fix: Give spots, tickets, and strategies their own responsibilities.

  • Switch statements on vehicle type across the code.

    Fix: Use a compatibility table and polymorphic strategies.

  • Ignoring concurrent gates.

    Fix: Describe locking or atomic claiming of a spot.

  • Jumping into code before clarifying requirements.

    Fix: Spend the first minutes on scope, entities, and flows.

13

Interview questions

How do you prevent two gates from assigning the same spot?

Claim the spot atomically: a lock around allocation in memory, or a conditional database update that succeeds only if the spot is still free. Retry with the next spot if it fails.

How would you add monthly passes?

Add a PassPricing strategy (or a decorator around pricing) that returns 0 for valid pass holders. The ParkingLot class does not change.

Which design patterns did you use?

Strategy for allocation and pricing, Singleton or DI for the lot instance, Factory for creating vehicles or spots, and Observer for availability displays.

14

Practice problems

ProblemDifficultyWhat it trains
Add a handicapped spot typeEasyExtend compatibility.
Weekend and night pricingMediumNew pricing strategy.
Multi-lot city parking systemHardSearch across lots and reservations.