How to Design an Elevator System
A Senior+ Guide — Building elevator scheduling, dispatch algorithms, and building management for 100+ story skyscrapers
Table of Contents
- Introduction
- Functional & Non-Functional Requirements
- Capacity Estimation
- Data Model
- API Design
- High-Level Architecture
- Elevator Hardware & Sensors
- Single Elevator Scheduling
- Multi-Elevator Dispatch
- Peak Traffic Handling
- Destination Dispatch
- Elevator State Machine
- Safety Systems & Emergency Protocols
- Energy Optimization
- Building Management Integration
- Monitoring & Predictive Maintenance
- Digital Twin & Simulation
- Multi-Bank & Sky Lobby Design
- Accessibility Features
- Database Design
- Caching Strategy
- Multi-Building Campus Design
- Cost Estimation
- Interview Q&A
- Full C# Implementation
- Conclusion
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).
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.
| Requirement | Target | Measurement |
|---|---|---|
| Average Wait Time | < 30s peak, < 20s off-peak | Time from hall call to elevator arrival |
| Peak Handling Capacity | 12-15% of population in 5 minutes | Passengers transported per 5-min interval |
| Round Trip Time | < 180s express, < 300s local | Lobby departure to lobby return |
| System Availability | 99.99% (52 min downtime/year) | Uptime excluding scheduled maintenance |
| Safety Response Time | < 500ms for emergency stop | Detection to full brake engagement |
| Position Accuracy | ± 2mm at floor level | Encoder-based position verification |
| Door Cycle Time | Open 2.5s, Dwell 3-8s, Close 2.5s | Full open-to-close cycle |
| Energy per Trip | < 0.5 kWh average | Energy metering per trip |
| Noise Level | < 55 dB in car, < 45 dB adjacent | Sound level at 1m distance |
| MTBF | > 20,000 operating hours | Historical 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.
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 Type | Floors | Population | Elevators | Capacity | Speed | Zone Strategy |
|---|---|---|---|---|---|---|
| Small Office | 10-20 | 500-2,000 | 4-8 | 1,000-1,600 kg | 2-3 m/s | Single zone |
| Medium Office | 20-40 | 2,000-8,000 | 8-16 | 1,600-2,000 kg | 3-5 m/s | Low/Mid zones |
| Large Office | 40-70 | 8,000-20,000 | 16-30 | 1,600-2,500 kg | 5-8 m/s | 3-4 zones |
| Supertall Office | 70-100+ | 20,000-50,000 | 30-60 | 1,600-2,500 kg | 8-20 m/s | 4-6 zones + sky lobbies |
| Luxury Residential | 30-60 | 200-800 | 4-10 | 800-1,600 kg | 3-6 m/s | 1-2 zones |
| Hotel | 30-80 | 300-2,000 | 6-20 | 1,000-1,600 kg | 3-6 m/s | Guest + service |
| Mixed Use Supertall | 80-120+ | 15,000-40,000 | 40-80 | 1,600-2,500 kg | 8-20 m/s | Multi-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.
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.
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
| Entity | Write Frequency | Data Volume/Day | Retention |
|---|---|---|---|
| Elevator State | 10 Hz per elevator | ~50 MB (40 elevators) | Real-time only |
| Hall Calls | ~500/day per elevator | ~2 MB | 1 year |
| Car Calls | ~1,000/day per elevator | ~4 MB | 1 year |
| Trips | ~500/day per elevator | ~2 MB | 5 years |
| Events | ~50,000/day per elevator | ~200 MB | 90 days |
| Maintenance Logs | ~5/week per elevator | ~50 KB | 10 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 Category | Protocol | Latency Target | Throughput | Auth |
|---|---|---|---|---|
| Passenger Commands | HTTPS/REST | < 200ms | 100 QPS | JWT + Floor ACL |
| Status Queries | HTTPS or WebSocket | < 100ms | 500 QPS | JWT |
| Dispatch Commands | Message Bus (UDP/TCP) | < 50ms | 1,000 msg/s | HMAC signing |
| BMS Integration | BACnet IP / MQTT | < 500ms | 50 msg/s | Network segmentation |
| Mobile App | HTTPS + SSE | < 300ms | 200 QPS | OAuth 2.0 |
| Monitoring Dashboard | WebSocket | < 1s | 50 connections | Session 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.
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.
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.
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 Type | Accuracy | Update Rate | Use Case |
|---|---|---|---|
| Rotary Encoder (on motor) | ±0.5mm | 1 kHz | Primary position tracking |
| Floor Passage Sensors | ±5mm | Event-driven | Position verification |
| Laser Distance Meter | ±1mm | 100 Hz | High-rise applications |
| Magnetic Strips | ±10mm | Event-driven | Terminal floors, leveling |
| Wire Rope Encoders | ±2mm | 500 Hz | Hydraulic 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.
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.
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.
| Algorithm | Avg Wait | Max Wait | Total Travel | Fairness | Complexity |
|---|---|---|---|---|---|
| FCFS | High | Very High | Very High | Perfect | O(1) |
| SCAN | Medium | Medium | Low | Good | O(n log n) |
| LOOK | Low-Medium | Medium | Lowest | Good | O(n log n) |
| C-SCAN | Low | Low | Medium | Excellent | O(n log n) |
| SCAN-EDF | Lowest | Lowest | Low-Medium | Excellent | O(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;
}
}
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.
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.
| Algorithm | Avg Wait | Peak Wait | Throughput | Best For |
|---|---|---|---|---|
| Nearest Car | 25s | 60s | 18 pax/min | Low traffic, small buildings |
| Zone + Nearest | 22s | 50s | 22 pax/min | Medium buildings |
| Multi-Objective | 18s | 40s | 25 pax/min | Large buildings, peak traffic |
| Destination Dispatch | 15s | 35s | 30 pax/min | Supertall, high-density offices |
| AI-Optimized | 12s | 30s | 33 pax/min | Buildings 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.
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
| Mode | Trigger | Behavior |
|---|---|---|
| MORNING_UP_PEAK | Lobby calls > 200/min | All idle at lobby, express to high floors |
| EVENING_DOWN_PEAK | Upper calls > 300/min | Park at upper floors, optimize lobby express |
| LUNCH_RUSH | High bidirectional volume | Increase capacity, normal dispatch tuned |
| SPECIAL_EVENT | Scheduled by manager | Custom zone assignments, priority service |
| AFTER_HOURS | Occupancy < 20% | Reduced fleet, energy saving mode |
| FIRE_SERVICE | Fire alarm | Recall 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.
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.
| Feature | Traditional | Destination Dispatch | Improvement |
|---|---|---|---|
| Avg Wait Time | 28s | 15s | 46% reduction |
| Avg Travel Time | 75s | 45s | 40% reduction |
| Handling Capacity | 13% in 5 min | 18% in 5 min | 38% increase |
| Elevators Required | 40 | 28 | 30% fewer |
| Shaft Floor Space | 120 m² | 84 m² | 36 m² saved |
| Energy per Trip | 0.5 kWh | 0.35 kWh | 30% reduction |
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.
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
| Transition | Typical | Maximum | Fault Action |
|---|---|---|---|
| Idle → Doors Opening | 50ms | 200ms | Retry once |
| Doors Opening → Boarding | 2.0-2.5s | 3.5s | Fault, re-close/re-open |
| Boarding → Doors Closing | 3-8s | 8s | Force close |
| Doors Closing → Accelerating | 2.0-2.5s | 3.5s | Fault, stop |
| Leveling → Doors Opening | 0.5-1.0s | 2.0s | Leveling 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
- Mains power loss detected (0ms) — Safety circuit still powered by UPS
- Motor enters regenerative braking (10ms) — Using stored kinetic energy
- Elevator decelerates to nearest floor
- Doors open via UPS battery (15-30 seconds)
- Generator starts (30-45 seconds)
- Transfer switch engages (45-60 seconds)
- 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 System | Trigger | Response | Independence |
|---|---|---|---|
| Overspeed Governor | 115%/140% speed | < 500ms | Fully mechanical |
| Safety Gear | Governor activation | < 1 second | Mechanical |
| Buffer Springs | Terminal floor | Instantaneous | Purely mechanical |
| Door Safety Edge | Obstruction | < 50ms | Hardware circuit |
| Final Limits | Past terminal floor | < 100ms | Hardwired |
| Fire Recall | Fire alarm signal | < 60 seconds | Hardwired relay |
| Earthquake Sensor | P-wave detection | < 5 seconds | Dedicated 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.
| Technology | Energy Reduction | Cost Premium | Payback |
|---|---|---|---|
| Regenerative drives | 30-45% | $15-25K/unit | 3-5 years |
| LED + sleep mode | 60-70% lighting | $2-5K/unit | 1-2 years |
| VVVF drives | 25-35% | Standard | Immediate |
| Standby positioning | 5-10% | Software only | Immediate |
| Destination dispatch | 15-25% | $200-500K system | 5-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.
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.
| Integration | Protocol | Data | Frequency |
|---|---|---|---|
| HVAC ↔ Elevator | BACnet IP | Positions, load, predicted occupancy | Every 30s |
| Fire Alarm → Elevator | Hardwired + BACnet | Alarm signal, zone, recall floor | Real-time |
| Access → Elevator | TCP/IP API | Badge ID, authorized floors | Per request |
| Elevator → Lighting | MQTT | Arrival events, direction | Event-driven |
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
| Component | Key Indicators | Prediction Window | Accuracy |
|---|---|---|---|
| Door Operator | Motor current, cycle count | 14-30 days | 85% |
| Hoist Ropes | Load cycles, diameter | 30-90 days | 80% |
| Motor Bearings | Vibration, temperature | 14-45 days | 88% |
| Guide Rails | Vibration spectrum | 60-180 days | 75% |
| Controller Capacitors | ESR, temperature | 90-365 days | 70% |
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.
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.
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.
| Design | Shafts (100 floors) | Avg Wait | Cost vs Baseline |
|---|---|---|---|
| Conventional | 40-50 | 30-40s | Baseline |
| Zone-based (3 zones) | 30-36 | 22-28s | -20% |
| Sky lobby + express | 24-30 | 18-25s | -30% |
| Dual-car + sky lobby | 16-22 | 15-22s | -40% |
| Full optimization + DD | 14-18 | 12-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 Category | Database | Write Rate | Retention | Query Pattern |
|---|---|---|---|---|
| Metadata | PostgreSQL | Low | Permanent | CRUD, joins |
| Hall/Car Calls | PostgreSQL | ~10/s | 1 year | Time-range |
| Trips | PostgreSQL | ~5/s | 5 years | Analytics |
| Sensor Telemetry | InfluxDB/TimescaleDB | 2,000/s | 30 days | Time-range |
| Events | Elasticsearch | ~50/s | 90 days | Pattern 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 Pattern | TTL | Update Strategy | Size (40 elevators) |
|---|---|---|---|
| elevator:{id}:state | No expiry | Pub/Sub (10Hz) | ~20 KB |
| elevator:{id}:calls | No expiry | Pub/Sub (event) | ~10 KB |
| building:{id}:floor_status:{n} | 5s | Computed from elevator states | ~50 KB |
| building:{id}:analytics:daily | 5 min | Aggregated from trips table | ~10 KB |
| building:{id}:dispatch_config | No expiry | Written 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 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.
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
| Component | Cost Range | Notes |
|---|---|---|
| Standard traction elevator (1,600kg, 3 m/s) | $150,000 - $250,000 | Installed, complete with shaft prep |
| High-speed elevator (2,000kg, 10 m/s) | $400,000 - $700,000 | Requires specialized machine room |
| Supertall express (2,500kg, 20 m/s) | $800,000 - $1,500,000 | Custom engineering, TWIN compatible |
| Destination dispatch system | $200,000 - $500,000 | Per building, includes kiosks + software |
| Regenerative drive upgrade | $15,000 - $25,000 | Per elevator, 3-5 year payback |
| BMS integration module | $30,000 - $80,000 | Per building, includes commissioning |
| Maintenance monitoring system | $50,000 - $150,000 | Per building, cloud-based analytics |
Annual Operating Costs
| Cost Category | Per Elevator/Year | Notes |
|---|---|---|
| Preventive maintenance contract | $8,000 - $15,000 | Includes quarterly inspections |
| Corrective maintenance (average) | $3,000 - $8,000 | Varies with age and usage |
| Energy cost | $2,000 - $6,000 | Depends on usage and local rates |
| Modernization reserve | $5,000 - $10,000 | Annual set-aside for major upgrades |
| Insurance | $1,000 - $3,000 | Liability 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
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.
- Strategy Pattern:
IDispatchStrategyallows 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:
BuildingManagerprovides a simplified interface to the complex subsystem - Producer-Consumer:
ConcurrentQueuefor 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.
- 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."