System Design Space
Knowledge graphSettings

Updated: April 11, 2026 at 11:51 PM

Smart parking system

medium

Public interview at C++ Russia 2023: concurrent parking-spot reservation, strict consistency, and automatic timeout release.

A smart parking system does not break on the map or the search box. It breaks when several drivers try to claim the same physical spot at once.

The chapter connects temporary holds, the free-spot counter, license-plate-based gate access, and timeout-driven release into one coherent architecture.

For interviews and engineering discussions, this case is useful because it quickly shows whether you can protect scarce-resource invariants under high contention.

Temporary Hold

The critical product step is not selling a spot forever, but creating a short hold quickly and releasing it automatically if the driver never arrives.

Spot Counter

The key invariant lives in one number: free spots must never go below zero, even when many clients hit the same parking lot at once.

Timeout Loop

Expired reservations are easier to clean up in a separate background loop so the synchronous API stays simple and the spot does not remain blocked for too long.

Gate Access

Plate validation and barrier control live in a different operational path, so they should be separated from reservation logic early in the architecture.

This public C++ Russia 2023 interview asks the candidate to design a smart parking system: drivers reserve a spot in advance, enter by license plate, and the backend has to survive concurrency without ever assigning the same physical spot twice.

Source

Original analysis

This write-up is based on the Book Cube Telegram post and the public interview recording.

Перейти на сайт

Interview recording

The full public interview runs for about 30 minutes and is available on YouTube.

Watch on YouTube

Problem Statement

Smart Parking System

The product manages a network of paid parking lots with barriers and a mobile app. A driver reserves a spot in advance, receives a time-limited confirmation, and then enters without manual validation by using the car plate as the access key.

Functional Requirements

Parking discovery

Search by location and show nearby parking lots with current availability.

Reservation creation

Atomically reserve a single free spot without overselling the same slot.

Timeout cancellation

Automatically release the spot if the driver does not show up in time.

Entry and exit

Recognize the plate automatically and open the barrier for a valid reservation.

Non-functional Requirements

High contention

Peak traffic arrives around office hours and popular destinations, so several drivers may compete for the same spot at the same time.

No double assignment

The most visible failure is giving one physical spot to two different drivers. The critical path has to prevent that categorically.

Conceptually this is not an instant sale. It is a temporary hold on a scarce resource, so the critical path has to keep the free-spot counter and the reservation record in sync.

Related case

Geosearch and hot zones

Useful when discussing local traffic spikes and geographic partitioning for parking lots.

Читать обзор

High-Level Architecture

Smart Parking System: Architecture Map

temporary holds, gate access, and timeout automation

Reservation Plane

Driver App
search + reserve
API Gateway
auth + routing
Reservation Service
create + cancel
Inventory Lock
Redis semaphore
Reservation DB
state + history

Access + Async Plane

ANPR/LPR -> Entry Service -> Gate Controller
plate check + barrier command
Event Bus -> Delay Queue -> Timeout Worker
reservation expiry pipeline
Notification
push + email

End-to-end smart parking flow: reserve a spot, validate gate access, and release no-shows automatically.

The architecture deliberately separates three loops: reservation handling, physical gate access, and background timeout cleanup. That makes it easier to scale the API, the ANPR/LPR path, and the background workers independently.

Core Entities

Parking

{
  id: UUID,
  gps_coordinates: {lat, lon},
  total_capacity: int,
  free_spots_counter: int, // semaphore!
  address: string
}

Booking

{
  id: UUID,
  user_id: UUID,
  parking_id: UUID,
  car_plate: string,
  created_at: timestamp,
  expires_at: timestamp,
  status: enum (pending, confirmed, cancelled, expired)
}

Interviewer feedback

The candidate first focused on counters and operational tables without explicitly introducing a Booking entity. For this system, that history is essential for auditing, support, and utilization analysis.

Free-spot Counter

The core technical problem is simple to state and easy to get wrong: decrement the free counter atomically and never let it go below zero. That is exactly where parallel reservation attempts race with one another.

Redis: Lua script

Recommended
-- parking_book.lua
local counter = redis.call('GET', KEYS[1])
if tonumber(counter) > 0 then
  return redis.call('DECR', KEYS[1])
else
  return -1 -- No free spots
end

Pros

Atomic on a single key, simple to reason about, and very fast.

Cons

You still need a separate plan for durability and for syncing with the source-of-truth database.

PostgreSQL: conditional UPDATE

UPDATE parkings 
SET free_spots = free_spots - 1
WHERE id = $1 AND free_spots > 0;

-- affected_rows = 0 → no spots left

Pros

Strong transactional guarantees and a single durable source of truth.

Cons

Under high contention it quickly turns into row locking and database pressure.

Recommended approach

Redis works well as a fast front-line semaphore, while PostgreSQL stores the final reservation state and history. In practice that gives you a two-step design: fast contention control up front and a durable record behind it.

Automatic Release on Timeout

If the driver does not arrive within 15 minutes, the spot should not stay blocked forever. The reservation needs an explicit lifetime and a background loop that can release the resource without blocking the synchronous API.

AWS SQS: delayed delivery

# On reservation
sqs.send_message(
    QueueUrl=timeout_queue,
    MessageBody={"booking_id": "...", "parking_id": "..."},
    DelaySeconds=900 # 15 minutes
)

# After 15 minutes the worker checks:
# - If the car did not arrive → INCR counter, cancel reservation
# - If the car already arrived → do nothing

An alternative is RabbitMQ Delayed Message Plugin if the queue needs to stay inside a self-managed stack.

Timeout workers and entry handlers must tolerate retries cleanly. A duplicate timeout event must not return the same spot twice.

Geographic Partitioning

Parking demand is naturally local, which makes geographic partitioning a strong default choice. Most users search nearby, so the common request path does not need to touch the whole country.

Strategy

  • Use a region or geohash-derived key to place parking lots close together.
  • Serve “find nearby parking” requests from the local region whenever possible.
  • Keep cross-region traffic as an exception instead of the default query mode.

Dense city centers, airports, and malls will still become hotspots. Those areas usually need finer partitions, stronger caching, or dedicated read replicas.

Key Findings

The semaphore lives on the counter

The critical invariant is binary: a spot is either still free or already claimed. Every race on the counter threatens the whole user journey.

Reservation history is mandatory

A separate reservation entity is required not just for product logic, but also for support, auditing, analytics, and recovery.

Timeout deserves its own loop

It is safer to move no-show cleanup out of the synchronous API into a queue-driven background flow.

Geography helps scaling

Parking supply is physically local, so locality can become part of the architecture very early.

What matters most in the interview

The interviewer wants more than a working diagram. You should explicitly explain the trade-off between fast reservation confirmation, strict correctness, and the operational cost of a more complex design.

Interviewer Feedback

✓ Strengths

  • Quickly identified the main invariant: one spot cannot belong to two drivers.
  • Covered timeout handling, failures, and the full reservation lifecycle.
  • Recognized that geography affects both scaling and traffic distribution.
  • Kept a solid overall answer structure for a short public interview.

⚠ Areas for Improvement

  • The reservation entity should have been introduced much earlier.
  • The answer still needs concrete load estimates and sizing assumptions.
  • The final database choice should be argued more explicitly.
  • The operational path around ANPR/LPR failures and gate handling remains shallow.

Related chapters

Enable tracking in Settings