system-design50 min read

How to Design an Elevator System — A Senior+ Guide | Ayodhyya

How to Design an Elevator System

A Senior+ Guide — Building elevator scheduling, dispatch algorithms, and building management for 100+ story skyscrapers

Published on July 14, 2026 · by Ayodhyya · 25 min read · System Design

1. Introduction

Modern skyscrapers are marvels of engineering, but none of them would be functional without one critical system that most occupants take for granted: the elevator. A building like the Burj Khalifa (828 meters, 163 floors), Shanghai Tower (632 meters, 128 floors), or the recently completed Jeddah Tower (1,000+ meters, 167+ floors) would be nothing more than an expensive monument if people couldn't efficiently travel between floors. The elevator system is the circulatory system of a vertical city, and designing it well is one of the most fascinating challenges in systems engineering.

The complexity of elevator systems scales nonlinearly with building height. A 10-story office building might need only 2-3 elevators operating independently. But a 100+ story skyscraper requires a sophisticated fleet of 40-80 elevators operating as a coordinated unit, handling thousands of passengers per hour during peak periods, while maintaining average wait times under 30 seconds. The morning rush in a 100-story building can see 5,000-10,000 people arriving within a 30-minute window, all needing to reach floors scattered across 400+ vertical meters.

From a system design perspective, the elevator problem is remarkably rich. It encompasses real-time scheduling algorithms, distributed systems coordination, hardware-software interfaces, safety-critical design, energy optimization, and human-computer interaction. It's a problem that combines elements of operating system scheduling (SCAN algorithms are directly analogous to disk head scheduling), load balancers (dispatching requests to available resources), and queueing theory (modeling wait times under varying traffic patterns).

Why This Matters for System Design Interviews: Elevator system design is a classic interview question at major tech companies. It tests your ability to handle real-time constraints, design state machines, reason about concurrency, and optimize for multiple competing objectives (throughput vs. latency vs. energy vs. comfort). Companies like Otis, Schindler, KONE, and ThyssenKrupp employ hundreds of software engineers working on these exact problems.

Traffic patterns in skyscrapers are highly predictable yet extreme. During morning up-peak hours (typically 8:00-9:30 AM), the vast majority of traffic flows from the lobby upward. During evening down-peak (5:00-6:30 PM), traffic reverses. Lunch hours create a secondary wave. The system must handle these peaks gracefully while still serving individual requests throughout the day. A poorly designed system can create cascading delays where wait times compound exponentially during peak periods.

The physics of elevator travel also impose hard constraints. Modern traction elevators travel at 10-20 meters per second. At these speeds, passengers experience noticeable acceleration forces that must be limited to around 1.0-1.5 m/s² for comfort. Door operations take 2-4 seconds each way. These physical constants mean that a round trip in a 100-story building takes a minimum of 90-120 seconds even with no intermediate stops. Understanding these constraints is essential for realistic capacity planning.

In this comprehensive guide, we will design a complete elevator management system from the ground up. We'll start with requirements and capacity estimation, design the data model and APIs, build the high-level architecture, dive deep into scheduling algorithms, handle safety and emergency protocols, optimize for energy efficiency, integrate with building management systems, and finish with a complete C# implementation of over 300 lines. By the end, you'll have the knowledge to design elevator systems for the world's tallest buildings.

"The elevator industry moves 18 billion passengers per day globally — more than all airlines combined. The system design challenge is ensuring every single one of those trips is safe, efficient, and comfortable."

2. Functional & Non-Functional Requirements

Functional Requirements

The core functional requirements of an elevator system span passenger interaction, fleet management, and operational control. At the most basic level, passengers must be able to call an elevator from any floor, select a destination, and be transported safely. But the full scope extends far beyond this fundamental interaction.

Passengers interact with the system through hall call buttons (up/down on each floor), car operating panels (destination buttons inside each elevator), and increasingly through smartphone apps and touchless interfaces. The system must register these calls, assign an appropriate elevator, manage door operations, monitor load conditions, and provide real-time status updates including current position, direction, and estimated arrival time.

Core Functional Requirements

  • Hall call registration and elevator assignment for all floors
  • Car destination selection with floor prioritization
  • Door open/close control with obstruction detection
  • Load monitoring and overload prevention
  • Position tracking with floor-level accuracy
  • Direction indication and ETA display
  • Emergency stop and alarm systems
  • Fire service and evacuation protocols (ASME A17.1)
  • Maintenance scheduling and diagnostics
  • Access control integration (floor authorization via badge/RFID)
  • Multi-language audio announcements and visual displays
  • Real-time monitoring dashboard for building management

Non-Functional Requirements

Non-functional requirements define the quality attributes that make the system acceptable. In elevator systems, these requirements are often safety-critical and regulated by international standards such as ASME A17.1 (Safety Code for Elevators and Escalators) and EN 81 series in Europe.

RequirementTargetMeasurement
Average Wait Time< 30s peak, < 20s off-peakTime from hall call to elevator arrival
Peak Handling Capacity12-15% of population in 5 minutesPassengers transported per 5-min interval
Round Trip Time< 180s express, < 300s localLobby departure to lobby return
System Availability99.99% (52 min downtime/year)Uptime excluding scheduled maintenance
Safety Response Time< 500ms for emergency stopDetection to full brake engagement
Position Accuracy± 2mm at floor levelEncoder-based position verification
Door Cycle TimeOpen 2.5s, Dwell 3-8s, Close 2.5sFull open-to-close cycle
Energy per Trip< 0.5 kWh averageEnergy metering per trip
Noise Level< 55 dB in car, < 45 dB adjacentSound level at 1m distance
MTBF> 20,000 operating hoursHistorical failure data analysis

Safety is the paramount non-functional requirement. Elevator systems are classified as safety-critical systems, meaning a failure can directly endanger human lives. This classification drives every design decision, from redundant sensors and watchdog timers to fail-safe brake mechanisms that engage on power loss. The ASME A17.1 code specifies over 500 individual requirements covering everything from fire resistance of wiring to the maximum force exerted by closing doors.

Safety-Critical Design Note: Unlike many software systems, elevator controllers cannot simply restart on failure. A software crash during operation could leave passengers trapped, create a free-fall scenario if brakes are not engaged, or disable fire service during an emergency. Elevator controllers typically use real-time operating systems (RTOS) with hardware watchdog timers, and the software must be certified to SIL 2 (Safety Integrity Level 2) or higher per IEC 61508.

Fault tolerance goes beyond simple redundancy. The system must gracefully degrade — if the dispatch computer fails, individual elevators must continue operating in independent service mode. If communication between elevators is lost, each car must make locally optimal decisions. If a sensor fails, the system must detect the failure and switch to a conservative operating mode with reduced performance but maintained safety.

3. Capacity Estimation

Accurate capacity estimation is the foundation of elevator system design. Under-provisioning leads to unacceptable wait times, while over-provisioning wastes expensive floor space (each shaft consumes roughly 3-5 square meters) and capital.

Building Population Estimation

The starting point is estimating the building's population. For office buildings, a common rule of thumb is one person per 10-15 square meters of net usable area. A typical floor has 1,500-2,500 square meters, translating to 100-250 people per floor. For a 100-story building, this gives 10,000-25,000 total occupants. Not all occupants are present simultaneously — office buildings typically have 80-90% occupancy during business hours.

Five-Minute Handling Capacity

The five-minute handling capacity (HC) is the most critical metric. Industry standards recommend that elevators should transport 12-15% of the population within 5 minutes during peak conditions. For a building with 15,000 occupants, this means moving 1,800-2,250 people in a 5-minute window.

Quick Formula

Required 5-min HC = Building Population × 0.13

Elevators Needed = Required HC / (Car Capacity × Trips per Elevator per 5 min)

For a 100-story, 20,000-person building: 2,600 / (20 × 7) ≈ 19 elevators minimum

Round Trip Time Calculation

The round trip time (RTT) depends on travel distance, stops, door operation, and passenger exchange. The fundamental RTT formula is:

RTT = 2×H×t_v + (S+2)×t_s + (2S+H+1)×t_p

Where H is the highest reversal floor, S is the number of stops, t_v is time per floor at rated speed, t_s is door operating time, and t_p is passenger transfer time.

Elevator Sizing Table

Building TypeFloorsPopulationElevatorsCapacitySpeedZone Strategy
Small Office10-20500-2,0004-81,000-1,600 kg2-3 m/sSingle zone
Medium Office20-402,000-8,0008-161,600-2,000 kg3-5 m/sLow/Mid zones
Large Office40-708,000-20,00016-301,600-2,500 kg5-8 m/s3-4 zones
Supertall Office70-100+20,000-50,00030-601,600-2,500 kg8-20 m/s4-6 zones + sky lobbies
Luxury Residential30-60200-8004-10800-1,600 kg3-6 m/s1-2 zones
Hotel30-80300-2,0006-201,000-1,600 kg3-6 m/sGuest + service
Mixed Use Supertall80-120+15,000-40,00040-801,600-2,500 kg8-20 m/sMulti-bank + sky lobbies

Peak QPS Estimation

Each passenger generates 4-6 system requests per trip: one hall call, one car call, door events (2-4), and access control checks. During peak 5-minute periods with 2,000 passengers, this gives roughly 10,000-12,000 requests per 5 minutes, or about 35-40 QPS. Including monitoring and dashboard traffic (5-10x command traffic), total system QPS reaches 500-1,000 for a large building.

Capacity Planning Tip: Always plan for 20% more than worst-case estimates. Buildings grow, tenant density changes, and events create unusual traffic. The cost of one additional shaft during construction is trivial compared to retrofitting.

4. Data Model

The data model must capture the physical state of every elevator, the logical state of every request, and the historical record of every trip. This data drives real-time dispatch, maintenance planning, energy optimization, and building management reporting.

erDiagram ELEVATOR { string id PK string shaft_id int current_floor string direction string state int capacity_kg int speed_ms boolean in_service datetime last_maintenance } FLOOR { int floor_number PK string building_id FK int height_meters string floor_type boolean accessible } HALL_CALL { string id PK int floor_number string direction datetime created_at string assigned_elevator_id FK string status } CAR_CALL { string id PK string elevator_id FK int floor_number datetime registered_at boolean completed } PASSENGER { string id PK string badge_id string user_type } TRIP { string id PK string passenger_id FK string elevator_id FK int origin_floor int destination_floor datetime start_time datetime end_time int wait_time_ms float energy_wh } MAINTENANCE_LOG { string id PK string elevator_id FK string maintenance_type string fault_code datetime scheduled_date datetime completed_date string technician_id float parts_cost_usd float labor_hours string status } ELEVATOR |--o{ HALL_CALL : "assigned" ELEVATOR |--o{ CAR_CALL : "serves" ELEVATOR |--o{ TRIP : "completes" PASSENGER |--o{ TRIP : "makes" FLOOR ||--o{ HALL_CALL : "originates"

The Elevator entity maintains real-time state including current position, direction, operational state, and capacity constraints. The Floor entity represents a physical floor with height, type (standard, lobby, sky lobby, mechanical, parking), and accessibility features. The Hall_CALL captures a passenger's request with floor, direction, timestamp, assignment, and status. The CAR_CALL represents a destination selected inside an elevator.

Entity Write Frequency & Retention

EntityWrite FrequencyData Volume/DayRetention
Elevator State10 Hz per elevator~50 MB (40 elevators)Real-time only
Hall Calls~500/day per elevator~2 MB1 year
Car Calls~1,000/day per elevator~4 MB1 year
Trips~500/day per elevator~2 MB5 years
Events~50,000/day per elevator~200 MB90 days
Maintenance Logs~5/week per elevator~50 KB10 years

The Maintenance_Log records events with type (preventive, corrective, emergency), fault codes, work performed, parts replaced, and cost tracking. The diagnostics snapshot captures sensor readings and system state at fault time. The Event_Stream captures high-frequency operational events (floor passages, door operations, load changes) written to a time-series database with millisecond timestamps, retained 30-90 days for analysis.

The data model supports multi-tenancy for buildings managed by the same operator. A Building entity serves as the top-level container, with each building having its own elevators, floors, and tenants, allowing centralized dashboards while maintaining data isolation.

5. API Design

The elevator system exposes passenger-facing APIs, management APIs, and internal communication APIs. All must handle real-time constraints, with command APIs requiring sub-second responses and status APIs providing up-to-the-second accuracy.

Passenger-Facing APIs

// Register a hall call (up/down button on floor)
POST /api/v1/halls/calls
{
    "building_id": "bld_001",
    "floor": 47,
    "direction": "UP",
    "passenger_id": "usr_abc123"
}
// Response: { "call_id": "hc_9876", "assigned_elevator": "e_12", "eta_seconds": 8 }

// Get real-time elevator status for a floor
GET /api/v1/floors/{floor_number}/status
// Response: { nearest_up_elevator: { id: "e_12", eta: 8 }, queue_depth: { up: 3, down: 1 } }

// Register a destination (inside car or destination dispatch)
POST /api/v1/elevators/{elevator_id}/calls
{ "floor": 82, "passenger_id": "usr_abc123" }

// Get elevator real-time position and status
GET /api/v1/elevators/{elevator_id}/status
// Response: { current_floor: 34, direction: "UP", state: "MOVING", load: 65%, next_stop: 47 }

// Emergency stop
POST /api/v1/elevators/{elevator_id}/emergency/stop
{ "reason": "PASSENGER_EMERGENCY", "reported_by": "usr_abc123" }

Management APIs

// Configure dispatch parameters
PUT /api/v1/buildings/{building_id}/dispatch/config
{
    "peak_mode": "MORNING_UP",
    "parking_floor": 1,
    "zone_configuration": [
        { "zone_id": "low", "floors": [1,25], "elevators": ["e_01","e_02","e_03"] },
        { "zone_id": "mid", "floors": [26,50], "elevators": ["e_04","e_05","e_06"] },
        { "zone_id": "high", "floors": [51,100], "elevators": ["e_07","e_08","e_09"] }
    ]
}

// Take elevator out of service
POST /api/v1/elevators/{elevator_id}/maintenance/enter

// Get building analytics
GET /api/v1/buildings/{building_id}/analytics/daily?date=2026-07-14
API CategoryProtocolLatency TargetThroughputAuth
Passenger CommandsHTTPS/REST< 200ms100 QPSJWT + Floor ACL
Status QueriesHTTPS or WebSocket< 100ms500 QPSJWT
Dispatch CommandsMessage Bus (UDP/TCP)< 50ms1,000 msg/sHMAC signing
BMS IntegrationBACnet IP / MQTT< 500ms50 msg/sNetwork segmentation
Mobile AppHTTPS + SSE< 300ms200 QPSOAuth 2.0
Monitoring DashboardWebSocket< 1s50 connectionsSession token

Error handling follows strict conventions. Safety-critical commands (emergency stop, fire service activation) require a two-step confirmation protocol with a 5-second TTL confirmation token. Rate limiting is applied per-building and per-elevator. The dispatch system has hard limits on assignment requests (one per elevator per 100ms).

6. High-Level Architecture

The system follows a layered architecture with clear separation between hardware control, real-time dispatch, building management integration, and user interfaces.

graph TB subgraph UI[User Interface Layer] A[Hall Call Panels] B[Car Operating Panels] C[Mobile App] D[Building Dashboard] end subgraph GW[API Gateway] F[REST API Server] G[WebSocket Hub] end subgraph CORE[Core Dispatch System] I[Dispatch Engine] J[Pattern Analyzer] K[Zone Manager] end subgraph CTRL[Elevator Control Layer] M[Controller - Low Zone] N[Controller - Mid Zone] O[Controller - High Zone] end subgraph HW[Hardware Interface] Q[Motor Drives] R[Door Operators] S[Sensors] T[Safety Circuits] end subgraph DATA[Data & Monitoring] U[Time-Series DB] V[Event Store] W[Analytics Engine] end A & B --> F C --> F D --> G F & G --> I I --> J & K I --> M & N & O M & N & O --> Q --> R --> S --> T M & N & O --> U I --> V --> W

Communication Patterns

The architecture employs three patterns: command-response for passenger interactions requiring immediate feedback, event-streaming for status updates where latest state matters more than individual events, and request-reply with timeout for dispatch-to-controller communication where every command must be acknowledged within a deadline.

sequenceDiagram participant P as Passenger participant API as API Gateway participant D as Dispatch Engine participant C as Elevator Controller participant H as Hardware P->>API: Press UP on Floor 47 API->>D: HallCall(floor=47, UP) D->>D: Evaluate available elevators D->>C: Assign E12 to floor 47 C->>H: Travel to floor 47 H-->>C: Floor 35 passed H-->>C: Floor 45 passed C-->>API: E12 at floor 45, ETA 4s API-->>P: Elevator arriving in 4s H-->>C: Floor 47 arrived C->>H: Open doors C-->>API: E12 arrived API-->>P: Elevator arrived

Fault isolation is a critical principle. Each elevator controller runs on dedicated hardware with its own power supply, network connection, and watchdog timer. If one controller fails, only its managed elevators are affected. The dispatch system is replicated with leader election, ensuring a single source of truth for assignments while providing failover capability.

Architectural Constraint: Elevator controllers are physically located in the building (machine room or penthouse). Communication must work over building network infrastructure which may include fiber, Ethernet over power line, or dedicated serial connections. Network reliability can be challenging due to electromagnetic interference from motor drives.

The architecture implements CQRS for the dispatch system. Commands (hall calls, car calls, emergency stops) use a write-optimized path with exactly-once delivery. Queries (position status, wait time estimates, analytics) are served by a read-optimized path backed by materialized views from the event stream.

7. Elevator Hardware & Sensor Systems

Understanding the physical hardware is essential for designing realistic elevator systems. The hardware layer defines constraints and capabilities that software must work within.

Motor and Drive Systems

Modern elevators use gearless traction motors with permanent magnet synchronous motors (PMSM). PMSMs offer 95%+ efficiency, smoother operation, and better regenerative braking. The variable-frequency drive (VFD) controls motor speed by adjusting frequency and voltage. The VFD communicates via CAN bus, Modbus, or proprietary protocols, reporting motor current, voltage, temperature, and faults. A 1,600 kg elevator at 4 m/s requires a 30-40 kW motor; supertall 2,500 kg at 20 m/s may require 100+ kW.

Position Sensing

Sensor TypeAccuracyUpdate RateUse Case
Rotary Encoder (on motor)±0.5mm1 kHzPrimary position tracking
Floor Passage Sensors±5mmEvent-drivenPosition verification
Laser Distance Meter±1mm100 HzHigh-rise applications
Magnetic Strips±10mmEvent-drivenTerminal floors, leveling
Wire Rope Encoders±2mm500 HzHydraulic elevators

Load Measurement

Load cells mounted under the car floor measure total weight. Modern systems use 4-8 strain gauge load cells connected to a summing junction, providing total weight and distribution data. Load data serves: overload protection (elevator won't move if load exceeds 110% of rated), passenger counting, and door hold extension (keeping doors open longer when heavy boarding is detected).

Load Cell Specs for 1,600 kg Elevator

  • Type: Shear beam, stainless steel, IP67 rated
  • Capacity: 500 kg each × 4 sensors = 2,000 kg total
  • Accuracy: ±0.05% of full scale
  • Operating Temperature: -30°C to +70°C
  • Overload Protection: 150% without permanent deformation

Safety Circuit

The safety circuit is a series-connected chain of safety switches that must all be closed for the elevator to operate. This hardwired circuit operates independently of software. Key switches include: car gate switch, hoistway door contacts, emergency stop switches, overspeed governor, final limit switches, and slack rope switches. Software can monitor but never bypass this circuit.

Safety-Critical: The safety circuit is the ultimate fail-safe. It operates so that any single switch or wire failure results in the elevator stopping (fail-safe principle). Operating at 48V DC through the hoistway, this hardware-level safety makes modern elevators extraordinarily safe — the fatality rate is approximately 0.00000027 per trip, about 1,000 times safer than automobiles.

8. Single Elevator Scheduling

Before understanding multi-elevator dispatch, we must master single elevator scheduling. The algorithm determines the order of serving floor requests, directly impacting wait times, travel times, and energy consumption. This problem is analogous to disk scheduling in operating systems.

First-Come, First-Served (FCFS)

The simplest algorithm serves requests in arrival order. While fair, FCFS is wildly inefficient — imagine the elevator at floor 1 going to floor 50, halfway up at floor 25 a call arrives at floor 2. FCFS sends the elevator back to floor 2 before continuing to floor 50, wasting significant time and energy.

SCAN Algorithm (Elevator Algorithm)

SCAN is the industry standard. The elevator moves in one direction, servicing all requests in its path, until reaching the last request in that direction or the zone boundary. It then reverses and services requests on the way back. This produces a smooth sweep pattern minimizing total travel distance.

stateDiagram-v2 [*] --> Idle Idle --> MovingUp : Request above Idle --> MovingDown : Request below Idle --> DoorsOpening : Request at current floor MovingUp --> MovingUp : More requests above MovingUp --> DoorsOpening : At next stop MovingUp --> ReversingDown : No requests above MovingDown --> MovingDown : More requests below MovingDown --> DoorsOpening : At next stop MovingDown --> ReversingUp : No requests below ReversingUp --> MovingUp : Direction reversed ReversingDown --> MovingDown : Direction reversed DoorsOpening --> Boarding : Doors fully open Boarding --> DoorsClosing : Dwell timer expires DoorsClosing --> Idle : Closed, no requests DoorsClosing --> MovingUp : Closed, going up DoorsClosing --> MovingDown : Closed, going down

LOOK Algorithm

LOOK reverses direction as soon as there are no more requests in the current direction, eliminating unnecessary travel to zone boundaries. If the highest pending request is at floor 35 in a zone covering floors 1-50, the elevator reverses at floor 35 instead of continuing to 50.

C-SCAN (Circular SCAN)

C-SCAN always sweeps in the same direction. When reaching the top, it quickly returns to the bottom (without servicing) and begins a new sweep. This provides more uniform wait times, preventing starvation where passengers at one end experience much longer waits. The trade-off is slightly higher average travel time.

AlgorithmAvg WaitMax WaitTotal TravelFairnessComplexity
FCFSHighVery HighVery HighPerfectO(1)
SCANMediumMediumLowGoodO(n log n)
LOOKLow-MediumMediumLowestGoodO(n log n)
C-SCANLowLowMediumExcellentO(n log n)
SCAN-EDFLowestLowestLow-MediumExcellentO(n²)

Here is a practical C# implementation of the SCAN algorithm for a single elevator, demonstrating how pending floor requests are serviced in order of travel direction:

// SCAN (Elevator Algorithm) implementation for a single elevator
public class ScanScheduler
{
    public static List<int> GetServiceOrder(List<int> pendingFloors,
        int currentFloor, ElevatorDirection direction)
    {
        var result = new List<int>();
        if (pendingFloors.Count == 0) return result;

        var sorted = pendingFloors.OrderBy(f => f).ToList();

        if (direction == ElevatorDirection.Up)
        {
            // Service all floors at or above current floor, ascending
            result.AddRange(sorted.Where(f => f >= currentFloor));
            // Then reverse and service all floors below, descending
            result.AddRange(sorted.Where(f => f < currentFloor).Reverse());
        }
        else
        {
            // Service all floors at or below current floor, descending
            result.AddRange(sorted.Where(f => f <= currentFloor).Reverse());
            // Then reverse and service all floors above, ascending
            result.AddRange(sorted.Where(f => f > currentFloor));
        }

        return result;
    }

    // Example: elevator at floor 35, going UP, pending: [12, 28, 35, 47, 52, 60, 8]
    // SCAN order: [35, 47, 52, 60, 28, 12, 8]
    // LOOK order: [47, 52, 60, 28, 12, 8] (skips current floor if already there)
}

// C-SCAN variant: always sweeps upward, wraps around
public class CScanScheduler
{
    public static List<int> GetServiceOrder(List<int> pendingFloors,
        int currentFloor, int maxFloor)
    {
        var sorted = pendingFloors.OrderBy(f => f).ToList();
        var result = new List<int>();

        // Service floors above current (ascending)
        result.AddRange(sorted.Where(f => f >= currentFloor));
        // Wrap: go to bottom without servicing, then sweep up from bottom
        result.AddRange(sorted.Where(f => f < currentFloor));

        return result;
    }
}
Key Insight: In practice, algorithm choice matters less than dwell time optimization. The difference between SCAN and LOOK is typically 5-10% in average wait time. Optimizing door timing based on passenger flow (keeping doors open 1 second longer when people are boarding) often has a larger impact than switching scheduling algorithms.

9. Multi-Elevator Dispatch

Multi-elevator dispatch is where the real complexity and value lie. When a building has 20-80 elevators, the assignment of each hall call to a specific elevator directly impacts thousands of passenger-hours per day.

Nearest Car Algorithm

The simplest dispatch assigns each hall call to the nearest available elevator. If no idle elevators exist, the call goes to the elevator arriving first based on current position and direction. This performs reasonably under uniform traffic but fails during peak periods when all elevators move the same direction.

Zone-Based Dispatch

Zone-based dispatch divides floors into logical zones with dedicated elevator groups. A 100-story building might have three zones: low (1-30), mid (31-60), high (61-100). Each zone has its own group with some express cars serving only the lobby and zone boundaries.

graph LR subgraph LowZone[Low Zone 1-30] L1[Elevator 1-6] end subgraph MidZone[Mid Zone 31-60] M1[Elevator 7-12] end subgraph HighZone[High Zone 61-100] H1[Elevator 13-18] end subgraph Express[Express Cars] E1[E19-E22] end Express --> LowZone & MidZone & HighZone

Traffic Flow Optimization

Advanced systems model the building's traffic as a network and optimize assignments to balance fleet load. During morning up-peak, the system positions idle elevators at the lobby. It implements peak positioning where elevators finishing a trip park where most likely needed next, rather than returning to the lobby.

flowchart TB A[Hall Call Received] --> B{Elevator at Same Floor?} B -->|Yes| C[Assign Immediately] B -->|No| D[Score Each Candidate Elevator] D --> E[Score = w1×WaitTime + w2×TravelTime + w3×Energy + w4×Balance] E --> F{Best Score < Threshold?} F -->|Yes| G[Assign Best Elevator] F -->|No| H{Predicted Wait < 30s?} H -->|Yes| G H -->|No| I[Queue + Alert Manager] G --> J[Send to Controller]
AlgorithmAvg WaitPeak WaitThroughputBest For
Nearest Car25s60s18 pax/minLow traffic, small buildings
Zone + Nearest22s50s22 pax/minMedium buildings
Multi-Objective18s40s25 pax/minLarge buildings, peak traffic
Destination Dispatch15s35s30 pax/minSupertall, high-density offices
AI-Optimized12s30s33 pax/minBuildings with rich data history

Modern dispatch systems increasingly use reinforcement learning agents trained on historical traffic data to learn optimal policies considering time of day, day of week, weather, nearby events, and real-time occupancy sensors.

10. Peak Traffic Handling

Peak traffic handling is the make-or-break capability. A system performing well off-peak but creating 5-minute waits during morning rush defines tenants' entire perception of the building.

Morning Up-Peak (8:00 - 9:30 AM)

Virtually all traffic flows from lobby upward with passengers distributed across all floors. During 30 minutes in a 100-story building with 15,000 occupants, the system must transport 5,000-7,000 people upward. This one-directional flow overwhelms normal bidirectional dispatch logic.

xychart-beta title "Typical Daily Traffic Pattern - Office Building" x-axis ["7AM","8AM","9AM","10AM","11AM","12PM","1PM","2PM","3PM","4PM","5PM","6PM","7PM"] y-axis "Passengers per 5 min" 0 --> 800 line [50,600,750,300,200,350,250,200,250,300,650,500,100]

During up-peak, the system switches to specialized mode: parking all idle elevators at the lobby, implementing express service to high-traffic floors, reducing door dwell at intermediate floors (since most are boarding not exiting), and direct-return strategy where elevators serving high floors return to lobby without accepting intermediate calls.

Evening Down-Peak & Lunch Rush

The evening down-peak reverses the morning pattern. Passengers originate from distributed locations, requiring many simultaneous hall calls from different floors. The lunch rush creates bidirectional flow — some go down to restaurants, others up to sky lobbies. Bidirectional flow is actually easier for elevators but volume can reach 30-40% of morning peak.

Peak Traffic Operating Modes

ModeTriggerBehavior
MORNING_UP_PEAKLobby calls > 200/minAll idle at lobby, express to high floors
EVENING_DOWN_PEAKUpper calls > 300/minPark at upper floors, optimize lobby express
LUNCH_RUSHHigh bidirectional volumeIncrease capacity, normal dispatch tuned
SPECIAL_EVENTScheduled by managerCustom zone assignments, priority service
AFTER_HOURSOccupancy < 20%Reduced fleet, energy saving mode
FIRE_SERVICEFire alarmRecall to lobby, phase I/II per code

Traffic prediction enables proactive peak handling. By analyzing historical patterns, the system can reposition elevators before peaks arrive, reducing wait times by 15-20% compared to purely reactive systems. Interfloor traffic during mid-day is often overlooked but significant — employees visiting colleagues across zones create cross-zone disruptions requiring temporary express car re-routing.

11. Destination Dispatch Systems

Destination dispatch (DD) is a paradigm shift. Passengers declare their destination before entering an elevator, and the system assigns them to a specific car. This simple change enables dramatically better performance.

flowchart LR A[Passenger at Lobby Kiosk] --> B[Enters Destination Floor] B --> C[System Groups with Others] C --> D[Assigned to Elevator C] D --> E[Passenger Walks to Elevator C] E --> F[Express to Zone] F --> G[Stops at Assigned Floors Only]

Benefits are substantial: average wait times decrease 30-50%, energy drops 15-25% from fewer stops, buildings accommodate the same traffic with 20-30% fewer elevators, and ride comfort improves with fewer intermediate stops.

Group Control Algorithm

When a new destination arrives, the algorithm evaluates all possible assignments minimizing a cost function considering current and predicted future system state. This combinatorial optimization considers: additional travel time for existing passengers, impact on future availability, effect on other pending requests, and system balance. For 40+ elevators, this must complete within 100-200ms.

Multi-Destination Grouping

Several passengers needing floors in the same zone can be grouped into a single express elevator that travels to the zone and makes only necessary stops. This "group riding" reduces trips by 40-60% compared to individual service.

FeatureTraditionalDestination DispatchImprovement
Avg Wait Time28s15s46% reduction
Avg Travel Time75s45s40% reduction
Handling Capacity13% in 5 min18% in 5 min38% increase
Elevators Required402830% fewer
Shaft Floor Space120 m²84 m²36 m² saved
Energy per Trip0.5 kWh0.35 kWh30% reduction
Real-World: ThyssenKrupp's Heron Tower installation reduced shafts from 33 planned to 22, saving ~$15M in construction while improving service. The system handles 10,000 daily occupants across 46 floors with sub-20-second peak waits.

12. Elevator State Machine

The state machine is the core of the control system, governing every aspect of operation through well-defined states and transitions. A robust state machine ensures predictable behavior, graceful fault handling, and maintained safety at all times.

stateDiagram-v2 state "Off Service" as Off state "Idle at Floor" as Idle state "Doors Opening" as DoorOpen state "Boarding" as Boarding state "Doors Closing" as DoorClose state "Accelerating" as Accel state "Running" as Running state "Decelerating" as Decel state "Leveling" as Level [*] --> Off Off --> Idle : Enable Idle --> DoorOpen : Hall or Car Call Idle --> Running : Dispatched elsewhere DoorOpen --> Boarding : Doors fully open Boarding --> DoorClose : Dwell expires DoorClose --> Idle : Closed, no destination DoorClose --> Accel : Closed, destination set Accel --> Running : Rated speed reached Running --> Decel : Approach floor Decel --> Level : Near floor speed Level --> DoorOpen : Floor confirmed

State Descriptions

Off Service: Powered down or disabled. Transition to Idle requires maintenance enable and safety verification.

Idle: At floor, doors closed, brakes engaged, monitoring for calls. Includes parking sub-state for specific floor parking during off-hours.

Doors Opening/Boarding: Door operator running, light curtains monitored for obstructions. Boarding monitors load cells, extending dwell if activity detected. Maximum dwell 8 seconds.

Doors Closing → Accelerating → Running → Decelerating → Leveling: The motion sequence from departure to arrival. Speed is ramped according to motion profiles limited to 1.0-1.5 m/s² acceleration and 1.0-1.5 m/s³ jerk for comfort.

State Transition Timing

TransitionTypicalMaximumFault Action
Idle → Doors Opening50ms200msRetry once
Doors Opening → Boarding2.0-2.5s3.5sFault, re-close/re-open
Boarding → Doors Closing3-8s8sForce close
Doors Closing → Accelerating2.0-2.5s3.5sFault, stop
Leveling → Doors Opening0.5-1.0s2.0sLeveling fault, retry

Fault handling follows strict protocol. Non-safety-critical faults (door timing, leveling) attempt a retry before logging. Safety-critical faults (overspeed, safety circuit open) immediately transition to the appropriate safe state. Mode transitions between normal and special modes (fire, emergency power) must be atomic across all elevators.

13. Safety Systems & Emergency Protocols

Safety systems are governed by strict international codes and represent the most critical design aspect. Modern elevators incorporate multiple independent layers of safety protection.

Fire Service Operations

Phase I (automatic recall): Upon fire alarm activation, all elevators recall to the lobby and open doors via hardwired connection that software cannot override. Phase II (firefighter operation): Firefighters use a key switch to take control. The elevator travels at reduced speed (0.3 m/s) with doors under manual control, dead-man operation. Only one car operates in Phase II at a time.

Power Failure & Overspeed Protection

Emergency Power Sequence

  1. Mains power loss detected (0ms) — Safety circuit still powered by UPS
  2. Motor enters regenerative braking (10ms) — Using stored kinetic energy
  3. Elevator decelerates to nearest floor
  4. Doors open via UPS battery (15-30 seconds)
  5. Generator starts (30-45 seconds)
  6. Transfer switch engages (45-60 seconds)
  7. Elevators resume at reduced speed (60+ seconds)

The overspeed governor is purely mechanical — a centrifugal mechanism activates at 115% rated speed (normal switch) and 140% (final safety switch activating the safety gear). The safety gear is a mechanical brake clamping guide rails with enough force to stop a fully loaded car within code-specified stopping distance.

Safety SystemTriggerResponseIndependence
Overspeed Governor115%/140% speed< 500msFully mechanical
Safety GearGovernor activation< 1 secondMechanical
Buffer SpringsTerminal floorInstantaneousPurely mechanical
Door Safety EdgeObstruction< 50msHardware circuit
Final LimitsPast terminal floor< 100msHardwired
Fire RecallFire alarm signal< 60 secondsHardwired relay
Earthquake SensorP-wave detection< 5 secondsDedicated sensors

Earthquake operation uses P-wave detection to stop elevators before destructive S-waves arrive. Software can monitor, log, and respond to safety events but must never override hardware safety mechanisms. The safety circuit operates on fail-safe design: any broken wire or failed sensor stops the elevator.

14. Energy Optimization

Elevators consume 2-8% of typical office building energy, rising to 10-15% in tall buildings. Modern technology offers significant optimization opportunities.

Regenerative Drives

Regenerative drives capture kinetic energy during braking, converting it back to electrical energy. When a loaded car descends or unloaded car ascends, the counterweight creates excess force causing the motor to generate. Recovery of 30-45% total consumed energy is typical, with 3-5 year payback periods.

TechnologyEnergy ReductionCost PremiumPayback
Regenerative drives30-45%$15-25K/unit3-5 years
LED + sleep mode60-70% lighting$2-5K/unit1-2 years
VVVF drives25-35%StandardImmediate
Standby positioning5-10%Software onlyImmediate
Destination dispatch15-25%$200-500K system5-8 years

Eco-Drive & Shuttle Strategy

Eco-drive profiles use longer acceleration/deceleration phases reducing peak motor power, cutting energy 20-25% with only 5-8% travel time increase. For very tall buildings, shuttle elevators carrying passengers to sky lobby transfer floors reduce total energy per trip by optimizing express runs and limiting local elevator travel ranges.

Intelligent parking minimizes empty car travel by positioning elevators where most likely called next based on traffic analysis. During morning up-peak, all idle cars park at the lobby; during evening, at highest occupied floors. LEED certification benefits directly from these optimizations, with 3-5 points achievable specifically from elevator energy performance.

15. Building Management Integration

Modern buildings coordinate everything through Building Management Systems (BMS). Elevator integration creates synergies improving building-wide efficiency.

graph TB BMS[BMS Controller] <--> HVAC[HVAC Control] BMS <--> FIRE[Fire Alarm] BMS <--> ACCESS[Access Control] BMS <--> LIGHT[Lighting] BMS <--> ELEV[Elevator System] BMS <--> CCTV[CCTV] FIRE -->|Fire Signal| ELEV ACCESS -->|Floor Auth| ELEV ELEV -->|Position| HVAC ELEV -->|Occupancy| LIGHT

HVAC Integration: Elevator data predicts where passengers will be. When elevators report 200 passengers heading to floor 82, HVAC preemptively increases cooling. When a floor empties for lunch, HVAC reduces conditioning. This reduces HVAC energy 10-15%.

Fire Alarm Integration: The most critical connection. Hardwired relay triggers Phase I recall. Real-time elevator position data helps firefighters. Dedicated fire-rated circuits remain operational during power failures.

Access Control Integration: Floor buttons are enabled/disabled based on badge authorization. Response time under 100ms prevents noticeable delays. Visitors must be pre-registered with specific floor access.

IntegrationProtocolDataFrequency
HVAC ↔ ElevatorBACnet IPPositions, load, predicted occupancyEvery 30s
Fire Alarm → ElevatorHardwired + BACnetAlarm signal, zone, recall floorReal-time
Access → ElevatorTCP/IP APIBadge ID, authorized floorsPer request
Elevator → LightingMQTTArrival events, directionEvent-driven
Smart Building Synergy: Sharing elevator destination data with HVAC enables "predictive comfort" — adjusting conditions in a zone before passengers arrive. If 200 people reach floors 50-60 in 5 minutes, HVAC pre-increases cooling, maintaining comfort without over-conditioning empty spaces.

16. Real-Time Monitoring & Predictive Maintenance

Modern elevators generate vast operational data that, properly analyzed, predicts failures before occurrence, optimizes performance, and reduces maintenance costs. The shift from reactive to predictive maintenance is one of the most impactful data analytics applications in the industry.

Key Monitoring Metrics

  • Average Wait Time (AWT): Rolling 5-minute average of hall call to arrival
  • Handling Capacity (HC): Population percentage transported in 5 minutes
  • System Availability: Percentage of time all elevators operational (target: 99.99%)
  • Energy per Trip: Average kWh consumed per passenger trip
  • Door Cycle Count: Total operations (predicts door maintenance needs)
  • Motor Temperature: Continuous monitoring with trend analysis
  • Vibration Analysis: Guide rail and rope condition monitoring
flowchart TB A[Elevator Sensors] --> B[Edge Computing] B --> C[Telemetry Stream] C --> D[Time-Series DB] D --> E[Real-Time Analytics] D --> F[ML Model Training] E --> G{Anomaly?} G -->|Yes| H[Alert] G -->|No| I[Continue] F --> J[Updated Model] H --> K[Work Order] K --> L[Technician] L --> M[Resolution] M --> F
ComponentKey IndicatorsPrediction WindowAccuracy
Door OperatorMotor current, cycle count14-30 days85%
Hoist RopesLoad cycles, diameter30-90 days80%
Motor BearingsVibration, temperature14-45 days88%
Guide RailsVibration spectrum60-180 days75%
Controller CapacitorsESR, temperature90-365 days70%

Predictive maintenance reduces downtime 35-45%, costs 20-30%, and extends component life 15-25%. For 40 elevators, annual savings reach $200,000-$500,000 while improving service quality with fewer unexpected breakdowns.

17. Digital Twin & Simulation

A digital twin is a real-time virtual replica mirroring physical state, behavior, and environment. It enables "what-if" simulation, algorithm testing without affecting operations, operator training, and continuous optimization.

graph TB subgraph Physical[Physical Building] PH[Elevator Hardware] PS[Sensors] end subgraph Twin[Digital Twin Platform] sync[Data Sync] sim[Physics Simulation] ai[ML Engine] viz[3D Visualization] end subgraph Apps[Applications] test[Algorithm Testing] plan[Capacity Planning] opt[Optimization] end PH --> sync PS --> sync sync --> sim & ai sim --> viz ai --> viz viz --> test & plan & opt

The simulation engine models passenger generation based on historical data, custom scenarios, or theoretical distributions. Engineers simulate extreme events (fire evacuation, power failure, 1,000 simultaneous arrivals), test dispatch changes under controlled conditions, and predict how modifications affect performance. A full day's operation simulates in under 60 seconds.

For new buildings, the digital twin is indispensable. Dozens of configurations can be compared across traffic scenarios, typically yielding 10-20% better performance than rule-of-thumb methods while often reducing required elevators. Otis's platform demonstrates 15% wait time improvement through continuous simulation-based optimization.

18. Multi-Bank & Sky Lobby Design

For buildings exceeding 50-60 stories, conventional single-bank design becomes impractical. Multi-bank designs with sky lobbies create a hierarchy — high-speed express cars for long distances and local cars serving zone floors.

graph TB subgraph Ground[Ground Floor] G1[Express Bank 1] G2[Express Bank 2] G3[Express Bank 3] end subgraph SL1[Sky Lobby Floor 25] L1[Local Bank A] L2[Local Bank B] end subgraph SL2[Sky Lobby Floor 50] L3[Local Bank C] L4[Local Bank D] end subgraph SL3[Sky Lobby Floor 75] L5[Local Bank E] end G1 --> SL1 G2 --> SL2 G3 --> SL3 L1 -.-> |Serves 1-25| Z1 L2 -.-> |Serves 26-50| Z2 L3 -.-> |Serves 51-75| Z3 L4 -.-> |Serves 76-100| Z4

Express elevators travel at 10-20 m/s non-stop between ground and sky lobbies, covering 30+ floors in under 30 seconds. Modern designs minimize transfer times through destination dispatch at sky lobbies — passengers entering the express have already registered their final destination, receiving a specific local elevator assignment at the sky lobby.

DesignShafts (100 floors)Avg WaitCost vs Baseline
Conventional40-5030-40sBaseline
Zone-based (3 zones)30-3622-28s-20%
Sky lobby + express24-3018-25s-30%
Dual-car + sky lobby16-2215-22s-40%
Full optimization + DD14-1812-18s-45%

ThyssenKrupp's TWIN system (two independent cabs per shaft) effectively doubles capacity with only 40% more shaft space, reducing total shafts by 25-30%. The Burj Khalifa uses 57 elevators with sky lobbies at floors 43 and 76, ensuring no occupant waits more than 30 seconds during peak.

19. Accessibility Features

Accessibility is both a legal requirement (ADA, EN 81-70) and a fundamental aspect of inclusive building design.

Physical Accessibility

Wheelchair accessibility requires minimum car dimensions (1,500mm × 1,500mm), control panels at 900-1,200mm height, door openings ≥800mm, level thresholds (max 13mm lip), and minimum 5-second door dwell for wheelchair entry/exit.

Accessibility Checklist

  • Braille on all buttons and signage
  • Audio floor announcements (adjustable volume)
  • High-contrast LED floor indicators
  • Tactile directional indicators on floor
  • Emergency communication with text display
  • Wheelchair-accessible control panel height
  • Minimum 800mm door opening
  • Handrails on three sides
  • Mirror on rear wall for wheelchair users
  • Emergency intercom with hearing loop
  • Visual and audible door movement indicators

Cognitive Accessibility

Clear, consistent signage with universal symbols helps passengers with cognitive disabilities. Simple button layouts reduce confusion. Audio announcements use plain language. Color coding and consistent spatial layouts aid wayfinding.

Emergency systems must serve all users: hearing loops for hearing aid users, text displays for deaf users, and lowered call buttons accessible from seated positions, connecting to 24/7 multilingual monitoring centers.

20. Database Design

The database layer must handle diverse patterns: high-frequency time-series sensor data, transactional trip/maintenance data, and analytical data for reporting and ML. A polyglot persistence approach provides the best balance.

-- Core relational schema (PostgreSQL)

CREATE TABLE buildings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    address TEXT,
    total_floors INT NOT NULL,
    building_type VARCHAR(50) NOT NULL,
    population_estimate INT,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE elevators (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    building_id UUID REFERENCES buildings(id),
    shaft_id VARCHAR(50) NOT NULL,
    bank_id VARCHAR(50) NOT NULL,
    zone_id VARCHAR(50),
    car_capacity_kg INT NOT NULL,
    rated_speed_ms DECIMAL(4,2) NOT NULL,
    status VARCHAR(20) DEFAULT 'IN_SERVICE',
    last_maintenance TIMESTAMPTZ,
    next_maintenance TIMESTAMPTZ,
    manufacturer VARCHAR(100),
    model VARCHAR(100)
);

CREATE TABLE hall_calls (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    building_id UUID REFERENCES buildings(id),
    floor_number INT NOT NULL,
    direction VARCHAR(4) NOT NULL CHECK (direction IN ('UP','DOWN')),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    assigned_elevator_id UUID REFERENCES elevators(id),
    status VARCHAR(20) DEFAULT 'PENDING',
    served_at TIMESTAMPTZ,
    wait_time_ms INT GENERATED ALWAYS AS (
        EXTRACT(EPOCH FROM (served_at - created_at)) * 1000
    ) STORED
);

CREATE TABLE trips (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    elevator_id UUID REFERENCES elevators(id),
    passenger_id UUID,
    origin_floor INT NOT NULL,
    destination_floor INT NOT NULL,
    direction VARCHAR(4) NOT NULL,
    start_time TIMESTAMPTZ NOT NULL,
    end_time TIMESTAMPTZ,
    wait_time_ms INT,
    travel_time_ms INT,
    energy_wh DECIMAL(8,2),
    status VARCHAR(20) DEFAULT 'IN_PROGRESS'
);

CREATE TABLE maintenance_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    elevator_id UUID REFERENCES elevators(id),
    maintenance_type VARCHAR(20) NOT NULL,
    priority VARCHAR(10) NOT NULL,
    fault_code VARCHAR(50),
    description TEXT,
    scheduled_date TIMESTAMPTZ,
    completed_date TIMESTAMPTZ,
    technician_id VARCHAR(50),
    parts_cost_usd DECIMAL(10,2),
    labor_hours DECIMAL(5,2),
    status VARCHAR(20) DEFAULT 'SCHEDULED',
    diagnostics JSONB,
    parts_replaced JSONB
);

CREATE INDEX idx_hall_calls_building_time
    ON hall_calls(building_id, created_at DESC);
CREATE INDEX idx_trips_elevator_time
    ON trips(elevator_id, start_time DESC);
Data CategoryDatabaseWrite RateRetentionQuery Pattern
MetadataPostgreSQLLowPermanentCRUD, joins
Hall/Car CallsPostgreSQL~10/s1 yearTime-range
TripsPostgreSQL~5/s5 yearsAnalytics
Sensor TelemetryInfluxDB/TimescaleDB2,000/s30 daysTime-range
EventsElasticsearch~50/s90 daysPattern search

21. Caching Strategy

A multi-tier caching strategy reduces database load and response times for the most frequently accessed data.

Tier 1: In-Memory Controller Cache

Each elevator controller maintains a local cache of its current state, pending calls, and door status. This cache is the authoritative source for real-time operations, updated at 10Hz from sensors. All dispatch decisions reference this cache rather than querying the database, ensuring sub-millisecond access for critical operations.

Tier 2: Dispatch System Cache (Redis)

The dispatch system maintains a Redis cluster with complete fleet state for all elevators. Each elevator's state is stored as a Redis hash with fields for position, direction, load, and pending stops. The cache is updated via pub/sub from each controller's state changes. TTL is set to 0 (no expiry) for current state, with 5-minute TTL for derived analytics.

Cache Key PatternTTLUpdate StrategySize (40 elevators)
elevator:{id}:stateNo expiryPub/Sub (10Hz)~20 KB
elevator:{id}:callsNo expiryPub/Sub (event)~10 KB
building:{id}:floor_status:{n}5sComputed from elevator states~50 KB
building:{id}:analytics:daily5 minAggregated from trips table~10 KB
building:{id}:dispatch_configNo expiryWritten on config change~5 KB

Tier 3: CDN / API Gateway Cache

Read-heavy endpoints like floor status and elevator position are cached at the API gateway with short TTLs (2-5 seconds). This reduces backend load during monitoring dashboard refresh cycles where multiple clients poll the same floor status. WebSocket connections bypass the cache and receive real-time push updates directly from the dispatch system.

Cache Consistency: Elevator state changes are time-critical — a stale cache showing an elevator at floor 30 when it's actually at floor 45 could lead to incorrect wait time estimates. All state-changing operations (door events, floor passages, direction changes) immediately invalidate and update the cache via pub/sub, achieving sub-100ms propagation across all cache tiers.

Cache Invalidation Strategy

Write-through caching is used for configuration data (zone definitions, dispatch parameters), ensuring cache and database are always consistent. Event-driven invalidation is used for operational state (position, load, calls), where the event source directly updates the cache without touching the database first. The database is updated asynchronously via event sourcing for historical record-keeping.

22. Multi-Building Campus Design

Large corporate campuses, mixed-use developments, and airport complexes require coordinated elevator management across multiple buildings. The multi-building architecture introduces challenges around centralized monitoring, cross-building transfers, and unified analytics.

Architecture

Each building runs its own autonomous elevator system with local dispatch, controllers, and failover capabilities. A campus-level management platform connects to each building's system via secure APIs, aggregating data for portfolio-wide analytics, centralized maintenance scheduling, and cross-building visitor management.

graph TB subgraph Campus[Campus Management Platform] CM[Central Monitor] CA[Analytics Engine] CMaint[Maintenance Scheduler] end subgraph B1[Building A - 50 floors] EA1[Dispatch A] EL1[Elevators 1-20] end subgraph B2[Building B - 80 floors] EA2[Dispatch B] EL2[Elevators 1-35] end subgraph B3[Building C - 30 floors] EA3[Dispatch C] EL3[Elevators 1-12] end CM <--> EA1 & EA2 & EA3 CA <--> EA1 & EA2 & EA3 CMaint <--> EA1 & EA2 & EA3

The campus platform provides: unified visitor management (one badge grants access across all buildings), centralized analytics comparing building performance, coordinated maintenance scheduling (dispatching technicians efficiently across buildings), and campus-wide emergency management (coordinating evacuations across multiple buildings simultaneously).

Cross-Building Integration

When buildings are connected via sky bridges or underground passages, the elevator system must handle cross-building transfers. A visitor arriving at Building A's lobby who needs to reach Building C's 25th floor should receive a seamless experience: Building A's elevator takes them to the connecting bridge floor, wayfinding guides them to Building C, and Building C's elevator is pre-assigned to take them to their destination.

Data federation across buildings enables powerful analytics. The campus platform can identify that Building A's elevators are overloaded during peak hours while Building B has spare capacity, informing decisions about tenant placement, shuttle services, or cross-building elevator sharing through connected passages. Aggregate energy reporting across the campus supports sustainability reporting and LEED campus certification.

23. Cost Estimation

Understanding elevator costs is essential for system designers, as cost constraints directly influence design decisions about fleet size, technology level, and feature set.

Capital Costs

ComponentCost RangeNotes
Standard traction elevator (1,600kg, 3 m/s)$150,000 - $250,000Installed, complete with shaft prep
High-speed elevator (2,000kg, 10 m/s)$400,000 - $700,000Requires specialized machine room
Supertall express (2,500kg, 20 m/s)$800,000 - $1,500,000Custom engineering, TWIN compatible
Destination dispatch system$200,000 - $500,000Per building, includes kiosks + software
Regenerative drive upgrade$15,000 - $25,000Per elevator, 3-5 year payback
BMS integration module$30,000 - $80,000Per building, includes commissioning
Maintenance monitoring system$50,000 - $150,000Per building, cloud-based analytics

Annual Operating Costs

Cost CategoryPer Elevator/YearNotes
Preventive maintenance contract$8,000 - $15,000Includes quarterly inspections
Corrective maintenance (average)$3,000 - $8,000Varies with age and usage
Energy cost$2,000 - $6,000Depends on usage and local rates
Modernization reserve$5,000 - $10,000Annual set-aside for major upgrades
Insurance$1,000 - $3,000Liability and equipment coverage

Lifecycle Cost Example — 100-Story Building, 40 Elevators

  • Initial capital: $20M - $35M (elevators + dispatch system)
  • Annual operating: $600K - $1.2M
  • 30-year lifecycle: $38M - $71M
  • Modernization (at year 15): $5M - $10M
  • Total 30-year cost: $43M - $81M

The cost per passenger trip over the building's lifetime averages $0.05 - $0.10, making elevator transportation remarkably cost-effective compared to the building rent it enables.

Cost optimization strategies include: standardizing on a single manufacturer (reducing spare parts inventory), negotiating fleet-wide maintenance contracts, investing in predictive maintenance to reduce emergency repairs, and implementing energy optimization to reduce operating costs. The decision between conventional and destination dispatch systems often comes down to lifecycle cost analysis — while DD has higher upfront costs, the 20-30% reduction in required elevators can save millions in construction costs and recoverable floor space.

24. Interview Q&A

Q1: Explain the SCAN elevator algorithm. How does it differ from the LOOK algorithm?
A: SCAN moves the elevator in one direction, servicing all requests in its path until reaching the zone boundary or last request in that direction, then reverses. LOOK is similar but reverses as soon as no more requests exist in the current direction — it doesn't travel to the boundary unnecessarily. SCAN provides more predictable timing; LOOK minimizes total travel distance. In a 100-floor zone with the highest request at floor 72, SCAN would continue to floor 100 before reversing; LOOK would reverse at floor 72.
Q2: How does destination dispatch improve system performance over traditional elevator systems?
A: Destination dispatch groups passengers going to nearby floors into the same elevator before boarding. This reduces stops per trip (improving travel time), enables better load distribution (reducing congestion), allows the system to plan optimal routes in advance (reducing wait times), and eliminates the uncertainty of not knowing passenger destinations until they enter the car. The net result is 30-50% wait time reduction, 40% fewer elevators needed, and 25-30% energy savings. The trade-off is more complex passenger flow and the need for kiosk-based lobbies.
Q3: How do you handle a situation where the dispatch system goes down?
A: The system must gracefully degrade. Each elevator controller operates autonomously with its own state machine and local call queue. Without dispatch coordination, controllers revert to independent service mode — serving the nearest calls in their immediate vicinity using local SCAN/LOOK algorithms. Passengers can still use the elevators, but efficiency drops significantly (expect 2-3x longer wait times). The dispatch system uses leader election with hot standby, so failover typically completes in under 5 seconds. All dispatch state is persisted in the event store for recovery.
Q4: Design the state machine for an elevator controller. What are the critical states and transitions?
A: The key states are: Off Service, Idle, Doors Opening, Boarding, Doors Closing, Accelerating, Running, Decelerating, Leveling, Fire Service, Emergency Stop, and Inspection. Critical transitions include: idle→doors opening (triggered by call), doors closing→accelerating (requires safety circuit closure and door lock confirmation), and any state→emergency stop (triggered by overspeed, safety circuit open, or manual emergency button). Every transition has a timeout — if exceeded, a fault is logged and the system moves to a safe state. The state machine must be deterministic: every input in every state produces exactly one defined output.
Q5: How would you calculate the number of elevators needed for a 60-story office building with 8,000 occupants?
A: Step 1: 5-minute handling capacity = 8,000 × 0.13 = 1,040 passengers. Step 2: For a 60-story building with 1,600 kg cars (≈20 passengers each), estimate RTT using the formula. With H=60, S≈12 stops, t_v≈3s/floor, t_s≈5s, t_p≈2s: RTT ≈ 2(60)(3) + (14)(5) + (133)(2) ≈ 360+70+266 ≈ 696 seconds (≈12 min). Step 3: Each elevator makes ≈ 5 trips in 5 minutes. Step 4: Each trip carries ≈ 15 passengers (accounting for partial loads). Step 5: Elevators needed = 1,040 / (15 × 5) ≈ 14 elevators minimum. Add 20% for redundancy = 17 elevators. With zone splitting (low zone 1-30, high zone 31-60), use 8 low + 7 high + 2 express = 17 total.
Q6: How do you ensure safety-critical design in elevator software?
A: Safety is ensured through defense in depth: (1) Hardware safety circuits operate independently of software — the overspeed governor, safety gear, and buffers are purely mechanical. (2) Software uses RTOS with watchdog timers — if the software hangs, the hardware watchdog triggers a safe stop. (3) The software is certified to SIL 2 per IEC 61508 with formal verification of critical paths. (4) Dual-channel processing compares results from two independent processors. (5) Fail-safe design means any failure results in stopping, not moving. (6) The safety circuit cannot be bypassed by software — this is a hardwired guarantee.
Q7: How would you handle peak morning traffic where 5,000 people need to reach upper floors within 30 minutes?
A: The system switches to MORNING_UP_PEAK mode: (1) Park all idle elevators at the lobby before the peak. (2) Reduce door dwell times at intermediate floors since most traffic is lobby→upper. (3) Implement express runs for high-floor zones using dedicated cars. (4) Disable return-to-lobby optimization — elevators go directly to the next highest call. (5) Use predictive positioning based on historical floor-by-floor demand. (6) For sky lobby buildings, increase express frequency and pre-assign local cars at sky lobbies. (7) Monitor real-time handling capacity and dynamically adjust zone boundaries if one zone is overloaded. The goal is 13% handling capacity = 650 passengers per 5 minutes.
Q8: What database architecture would you use for a system managing 1,000 elevators across 50 buildings?
A: Polyglot persistence: (1) PostgreSQL for relational data (buildings, elevators, trips, maintenance) with read replicas for analytics queries. (2) TimescaleDB or InfluxDB for high-frequency sensor telemetry (position, speed, vibration at 10Hz = 10,000 writes/second). (3) Redis cluster for real-time state caching with pub/sub for state change propagation. (4) Elasticsearch for event logs and maintenance search. (5) S3/object storage for long-term data archival after downsampling. Data volume: ~500 MB/day telemetry (90-day retention), ~10 MB/day relational, ~50 MB/day events. Total storage approximately 50 TB over 3 years.
Q9: How does a multi-objective dispatch algorithm balance wait time, energy, and system balance?
A: The algorithm computes a weighted score for each candidate elevator: Score = w₁×EstimatedWaitTime + w₂×EstimatedTravelTime + w₃×EnergyCost + w₄×SystemImbalance. Weights are dynamic — during peak hours, w₁ (wait time) dominates at 0.6; during off-peak, w₃ (energy) increases to 0.3. System imbalance measures how evenly distributed elevators are across floors. The energy cost estimates kWh based on distance, load, and direction (counterweight-aided travel costs less). The algorithm runs as a sorted evaluation of all candidates, completing in O(n) where n is the fleet size. For conflicts (simultaneous calls), the resolver reassigns calls to minimize global cost rather than local optimum.
Q10: Explain the two-step confirmation protocol for safety-critical commands.
A: Safety-critical commands (emergency stop, fire service activation, door override) cannot be executed immediately because accidental activation could trap passengers or create dangerous situations. The two-step protocol works as: (1) Client sends the command, server validates it and returns a confirmation token with a 5-second TTL. (2) Client must send the command again within 5 seconds, including the confirmation token. Only then does the server execute the command. This prevents accidental button presses, single-message replay attacks, and ensures the operator truly intends to execute the dangerous action. The token is cryptographically signed and single-use.
Q11: How would you design the real-time monitoring dashboard for building managers?
A: The dashboard uses WebSockets for real-time push updates. Layout: (1) Top panel: building-level KPIs (average wait time, handling capacity, energy, availability) with trend sparklines. (2) Main area: animated elevator position display showing all cars in their shafts with real-time position, direction arrows, and load indicators. (3) Side panel: alert list with color-coded severity. (4) Bottom panel: hourly traffic chart. Data flow: elevator controllers publish state at 10Hz → dispatch system aggregates → WebSocket hub pushes to connected dashboards. Each dashboard connection subscribes to its building's data feed. For 50 buildings × 5 dashboard connections each = 250 concurrent WebSocket connections, well within capacity.
Q12: What are the key trade-offs between centralized dispatch and distributed dispatch architectures?
A: Centralized dispatch has a single brain making optimal global decisions, but creates a single point of failure and requires high-bandwidth low-latency communication to all controllers. Distributed dispatch gives each controller autonomy, making locally optimal decisions with degraded global optimality, but provides inherent fault tolerance — if one controller fails, others continue. Hybrid approach (used in practice): controllers maintain local autonomy for immediate safety operations (door control, motion), while the central dispatch handles strategic decisions (which elevator serves which call). The central system can fail without affecting basic operation; it just reduces coordination efficiency by 30-40%.

25. Full C# Implementation

The following implementation provides a complete, production-quality foundation for an elevator management system. It includes the elevator state machine, dispatch strategies, and building management coordination.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ElevatorSystem
{
    public enum ElevatorDirection { Idle, Up, Down }
    public enum ElevatorState
    {
        OffService, Idle, DoorsOpening, Boarding,
        DoorsClosing, Accelerating, Running, Decelerating, Leveling
    }
    public enum TrafficMode { Normal, MorningUpPeak, EveningDownPeak, FireService, AfterHours }

    public class Elevator
    {
        public string Id { get; }
        public int CurrentFloor { get; private set; }
        public ElevatorDirection Direction { get; private set; }
        public ElevatorState State { get; private set; }
        public int CapacityKg { get; }
        public int CurrentLoadKg { get; private set; }
        public double SpeedMs { get; }
        public bool InService { get; private set; }
        public List<int> PendingFloors { get; } = new List<int>();
        private readonly object _lock = new object();

        public Elevator(string id, int capacityKg, double speedMs, int startFloor = 1)
        {
            Id = id;
            CapacityKg = capacityKg;
            SpeedMs = speedMs;
            CurrentFloor = startFloor;
            State = ElevatorState.OffService;
            Direction = ElevatorDirection.Idle;
            InService = false;
        }

        public void Enable()
        {
            lock (_lock)
            {
                State = ElevatorState.Idle;
                InService = true;
                Direction = ElevatorDirection.Idle;
            }
        }

        public void Disable()
        {
            lock (_lock)
            {
                State = ElevatorState.OffService;
                InService = false;
                Direction = ElevatorDirection.Idle;
                PendingFloors.Clear();
            }
        }

        public void AddDestination(int floor)
        {
            lock (_lock)
            {
                if (!PendingFloors.Contains(floor) && InService)
                {
                    PendingFloors.Add(floor);
                    PendingFloors.Sort();
                    UpdateDirection();
                }
            }
        }

        private void UpdateDirection()
        {
            if (PendingFloors.Count == 0)
            {
                Direction = ElevatorDirection.Idle;
                return;
            }
            bool hasAbove = PendingFloors.Any(f => f > CurrentFloor);
            bool hasBelow = PendingFloors.Any(f => f < CurrentFloor);
            if (hasAbove) Direction = ElevatorDirection.Up;
            else if (hasBelow) Direction = ElevatorDirection.Down;
            else Direction = ElevatorDirection.Idle;
        }

        public int GetNextStop()
        {
            lock (_lock)
            {
                if (PendingFloors.Count == 0) return -1;
                if (Direction == ElevatorDirection.Up)
                {
                    var above = PendingFloors.Where(f => f >= CurrentFloor).ToList();
                    if (above.Count > 0) return above.First();
                    return PendingFloors.Last();
                }
                else
                {
                    var below = PendingFloors.Where(f => f <= CurrentFloor).ToList();
                    if (below.Count > 0) return below.Last();
                    return PendingFloors.First();
                }
            }
        }

        public void MoveOneFloor(int targetFloor)
        {
            lock (_lock)
            {
                if (State == ElevatorState.Idle) State = ElevatorState.Accelerating;
                Thread.Sleep(100);
                State = ElevatorState.Running;
                Thread.Sleep(200);
                State = ElevatorState.Decelerating;
                Thread.Sleep(100);
                CurrentFloor = targetFloor;
                State = ElevatorState.Leveling;
                Thread.Sleep(50);
                State = ElevatorState.DoorsOpening;
                Thread.Sleep(200);
                PendingFloors.Remove(CurrentFloor);
                State = ElevatorState.Boarding;
                Thread.Sleep(150);
                State = ElevatorState.DoorsClosing;
                Thread.Sleep(200);
                UpdateDirection();
                State = Direction == ElevatorDirection.Idle
                    ? ElevatorState.Idle : ElevatorState.Accelerating;
            }
        }

        public int DistanceToFloor(int floor) => Math.Abs(CurrentFloor - floor);
        public bool IsAvailable => InService && State == ElevatorState.Idle;
        public bool CanAcceptLoad(int weight) => CurrentLoadKg + weight <= CapacityKg;
    }

    public interface IDispatchStrategy
    {
        Elevator SelectElevator(List<Elevator> elevators, int floor,
            ElevatorDirection direction, TrafficMode mode);
    }

    public class NearestCarStrategy : IDispatchStrategy
    {
        public Elevator SelectElevator(List<Elevator> elevators, int floor,
            ElevatorDirection direction, TrafficMode mode)
        {
            return elevators
                .Where(e => e.InService)
                .OrderBy(e =>
                {
                    int dist = e.DistanceToFloor(floor);
                    if (e.State == ElevatorState.Idle) return dist;
                    if (e.Direction == direction) return dist * 0.7;
                    return dist * 1.5;
                })
                .FirstOrDefault();
        }
    }

    public class ZoneStrategy : IDispatchStrategy
    {
        private readonly Dictionary<string, (int min, int max)> _zones;

        public ZoneStrategy(Dictionary<string, (int min, int max)> zones)
        {
            _zones = zones;
        }

        public Elevator SelectElevator(List<Elevator> elevators, int floor,
            ElevatorDirection direction, TrafficMode mode)
        {
            var zone = _zones.Values.FirstOrDefault(z => floor >= z.min && floor <= z.max);
            var zoneElevators = elevators.Where(e =>
                e.InService &&
                e.CurrentFloor >= zone.min && e.CurrentFloor <= zone.max).ToList();

            if (zoneElevators.Count == 0)
                zoneElevators = elevators.Where(e => e.InService).ToList();

            return zoneElevators
                .OrderBy(e => e.DistanceToFloor(floor))
                .FirstOrDefault();
        }
    }

    public class MultiObjectiveStrategy : IDispatchStrategy
    {
        private const double W_WAIT = 0.45;
        private const double W_TRAVEL = 0.25;
        private const double W_ENERGY = 0.15;
        private const double W_BALANCE = 0.15;

        public Elevator SelectElevator(List<Elevator> elevators, int floor,
            ElevatorDirection direction, TrafficMode mode)
        {
            double wWait = mode == TrafficMode.MorningUpPeak ? 0.6 : W_WAIT;
            double wEnergy = mode == TrafficMode.AfterHours ? 0.3 : W_ENERGY;

            var available = elevators.Where(e => e.InService).ToList();
            if (available.Count == 0) return null;

            double avgFloor = available.Average(e => e.CurrentFloor);

            return available
                .Select(e => new
                {
                    Elevator = e,
                    Score = ComputeScore(e, floor, direction, avgFloor, wWait, wEnergy)
                })
                .OrderBy(x => x.Score)
                .FirstOrDefault()?.Elevator;
        }

        private double ComputeScore(Elevator e, int floor, ElevatorDirection dir,
            double avgFloor, double wWait, double wEnergy)
        {
            double waitScore = e.DistanceToFloor(floor) * 2.0;
            if (e.Direction == dir) waitScore *= 0.6;
            else if (e.State == ElevatorState.Idle) waitScore *= 0.8;

            double travelScore = e.PendingFloors.Count * 3.0;
            double energyScore = e.DistanceToFloor(floor) * (e.CurrentLoadKg / 1600.0);
            double balanceScore = Math.Abs(e.CurrentFloor - avgFloor);

            return (wWait * waitScore) +
                   (0.25 * travelScore) +
                   (wEnergy * energyScore) +
                   (0.15 * balanceScore);
        }
    }

    public class DispatchEngine
    {
        private readonly List<Elevator> _elevators;
        private readonly IDispatchStrategy _strategy;
        private TrafficMode _currentMode = TrafficMode.Normal;
        private readonly ConcurrentQueue<(int floor, ElevatorDirection dir,
            DateTime time)> _pendingCalls = new();

        public event Action<string, int, string> OnElevatorAssigned;
        public event Action<string, ElevatorState, int> OnStateChanged;

        public DispatchEngine(List<Elevator> elevators, IDispatchStrategy strategy)
        {
            _elevators = elevators;
            _strategy = strategy;
        }

        public void SetTrafficMode(TrafficMode mode)
        {
            _currentMode = mode;
            if (mode == TrafficMode.MorningUpPeak)
            {
                foreach (var e in _elevators)
                    if (e.IsAvailable) e.AddDestination(1);
            }
        }

        public Elevator ProcessHallCall(int floor, ElevatorDirection direction)
        {
            var assigned = _strategy.SelectElevator(
                _elevators, floor, direction, _currentMode);

            if (assigned != null)
            {
                assigned.AddDestination(floor);
                OnElevatorAssigned?.Invoke(
                    assigned.Id, floor, $"Assigned to floor {floor}");
            }
            return assigned;
        }

        public void Tick()
        {
            foreach (var elevator in _elevators.Where(e => e.InService))
            {
                if (elevator.State == ElevatorState.Idle && elevator.PendingFloors.Count > 0)
                {
                    int next = elevator.GetNextStop();
                    if (next >= 0)
                    {
                        Task.Run(() =>
                        {
                            elevator.MoveOneFloor(next);
                            OnStateChanged?.Invoke(
                                elevator.Id, elevator.State, elevator.CurrentFloor);
                        });
                    }
                }
            }
        }

        public Dictionary<string, object> GetSystemStatus()
        {
            return new Dictionary<string, object>
            {
                ["mode"] = _currentMode.ToString(),
                ["total_elevators"] = _elevators.Count,
                ["in_service"] = _elevators.Count(e => e.InService),
                ["idle"] = _elevators.Count(e => e.State == ElevatorState.Idle),
                ["avg_wait_estimate"] = CalculateAvgWait(),
                ["pending_calls"] = _pendingCalls.Count
            };
        }

        private double CalculateAvgWait()
        {
            return _elevators.Where(e => e.InService)
                .Average(e => e.PendingFloors.Count * 5.0 + 3.0);
        }
    }

    public class BuildingManager
    {
        private readonly string _buildingId;
        private readonly List<Elevator> _elevators;
        private readonly DispatchEngine _dispatch;
        private readonly Timer _tickTimer;
        private TrafficMode _scheduledMode = TrafficMode.Normal;

        public BuildingManager(string buildingId, int elevatorCount,
            int floors, IDispatchStrategy strategy = null)
        {
            _buildingId = buildingId;
            strategy ??= new MultiObjectiveStrategy();
            _elevators = new List<Elevator>();

            for (int i = 0; i < elevatorCount; i++)
            {
                int startFloor = (i % 3 == 0) ? 1 : (i % 3 == 1) ? floors / 3 : 2 * floors / 3;
                _elevators.Add(new Elevator(
                    $"E{i + 1:D3}", 1600, 4.0, startFloor));
            }

            _dispatch = new DispatchEngine(_elevators, strategy);
            _dispatch.OnElevatorAssigned += (id, floor, msg) =>
                Console.WriteLine($"[{_buildingId}] {msg}");
            _dispatch.OnStateChanged += (id, state, floor) =>
                Console.WriteLine($"[{_buildingId}] {id} -> {state} at floor {floor}");

            _tickTimer = new Timer(_ => _dispatch.Tick(), null,
                TimeSpan.Zero, TimeSpan.FromMilliseconds(500));
        }

        public void Start()
        {
            foreach (var e in _elevators) e.Enable();
            Console.WriteLine($"Building {_buildingId} started with {_elevators.Count} elevators");
        }

        public void Stop()
        {
            _tickTimer.Dispose();
            foreach (var e in _elevators) e.Disable();
            Console.WriteLine($"Building {_buildingId} stopped");
        }

        public Elevator CallElevator(int floor, ElevatorDirection direction)
        {
            return _dispatch.ProcessHallCall(floor, direction);
        }

        public void SetTrafficMode(TrafficMode mode)
        {
            _scheduledMode = mode;
            _dispatch.SetTrafficMode(mode);
            Console.WriteLine($"[{_buildingId}] Mode changed to {mode}");
        }

        public Dictionary<string, object> GetStatus() => _dispatch.GetSystemStatus();

        public void RunPeakSimulation()
        {
            SetTrafficMode(TrafficMode.MorningUpPeak);
            var random = new Random(42);
            Console.WriteLine("--- Simulating morning up-peak ---");
            for (int i = 0; i < 50; i++)
            {
                int floor = random.Next(1, 6);
                CallElevator(floor, ElevatorDirection.Up);
            }
            Thread.Sleep(5000);
            Console.WriteLine("--- Peak simulation complete ---");
            Console.WriteLine($"Status: {string.Join(", ",
                GetStatus().Select(kv => $"{kv.Key}={kv.Value}"))}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("=== Elevator System Design Demo ===\n");

            var strategy = new MultiObjectiveStrategy();
            var building = new BuildingManager("BLD-001", 8, 60, strategy);

            building.Start();
            Thread.Sleep(1000);

            Console.WriteLine("\n--- Normal operation: random calls ---");
            building.CallElevator(15, ElevatorDirection.Up);
            building.CallElevator(30, ElevatorDirection.Down);
            building.CallElevator(45, ElevatorDirection.Up);
            building.CallElevator(52, ElevatorDirection.Down);
            Thread.Sleep(3000);

            building.RunPeakSimulation();

            Console.WriteLine("\n--- Final Status ---");
            var status = building.GetStatus();
            foreach (var kv in status)
                Console.WriteLine($"  {kv.Key}: {kv.Value}");

            building.Stop();
            Console.WriteLine("\n=== Demo Complete ===");
        }
    }
}

This implementation totals approximately 350 lines of C# and demonstrates all core concepts: the elevator state machine with 9 states, three pluggable dispatch strategies (nearest car, zone-based, multi-objective), traffic mode management, building-level coordination, and a simulation driver. In production, you would replace the Thread.Sleep calls with async operations, add proper event sourcing, integrate with the database and caching layers described earlier, and implement the full safety circuit interface.

Key Design Patterns Used:
  • Strategy Pattern: IDispatchStrategy allows swapping dispatch algorithms at runtime
  • Observer Pattern: Events (OnElevatorAssigned, OnStateChanged) decouple the dispatch engine from UI and logging
  • State Machine: Elevator states with defined transitions and timeout-driven fault handling
  • Facade Pattern: BuildingManager provides a simplified interface to the complex subsystem
  • Producer-Consumer: ConcurrentQueue for thread-safe call management

26. Conclusion

Designing an elevator system for a 100+ story skyscraper is one of the most multidisciplinary challenges in engineering. It requires deep knowledge of real-time systems, scheduling algorithms, safety-critical design, distributed systems, energy optimization, and human factors. Unlike many system design problems that exist purely in software, elevator systems bridge the physical and digital worlds with hard constraints imposed by physics, safety codes, and human comfort.

The key takeaways from this design are: First, safety must be the foundation of every design decision, with hardware-level safety systems that cannot be compromised by software failures. Second, the dispatch algorithm is the core differentiator between a good and great elevator system, with multi-objective optimization balancing wait time, energy, and system balance. Third, the system must be designed for graceful degradation — every component failure should result in reduced performance, not total system failure. Fourth, data-driven optimization through digital twins, predictive maintenance, and machine learning can improve performance by 15-30% over static configurations.

The C# implementation provided demonstrates the fundamental building blocks, but production systems require additional layers: proper async/await patterns for non-blocking operations, comprehensive error handling and logging, integration with building protocols (BACnet, Modbus), hardware driver interfaces, and robust testing including fault injection testing to verify graceful degradation behavior.

As buildings grow taller and denser, the challenges of vertical transportation will only intensify. Concepts like multi-car shafts (TWIN), rope-less elevators (using linear motor technology), and AI-driven predictive dispatch are pushing the boundaries of what's possible. The fundamental principles covered in this article — state machines, scheduling algorithms, safety-critical design, and systems thinking — will remain relevant regardless of how the technology evolves.

Further Learning:
  • Elevator Traffic Handbook by G.C. Barney — the definitive reference on elevator traffic analysis
  • ASME A17.1-2022/CSA B44-22 — the current safety code for elevators and escalators
  • IEC 61508 — functional safety of electrical/electronic/programmable systems
  • KONE, Otis, and Schindler technical whitepapers on destination dispatch and TWIN systems
  • MIT and Georgia Tech research papers on reinforcement learning for elevator dispatch

The elevator industry moves 18 billion passengers daily. Every one of those trips represents an engineering decision that was made to be safe, efficient, and comfortable. As system designers, we have the privilege and responsibility of building systems that people trust with their lives every day. Design well.

"Good building design creates great elevator systems. Great elevator systems create the illusion of effortless vertical movement in buildings that would otherwise be uninhabitable."

© 2026 Ayodhyya. All rights reserved.

System Design Articles | Software Engineering | Architecture