Queue Simulation with M/M/c Algorithm

This post presents QueueForge, an interactive educational tool for queue simulation based on the M/M/c model from queueing theory. The application, built with React, TypeScript, and Vite, allows users to visually explore in real time the behavior of a multi-server queueing system, typically used to model real-world scenarios such as call centers, bank counters, and help desks.

QueueForge combines three fundamental aspects:

  • M/M/c theoretical model - implementation of the mathematical formulas from queueing theory, including the Erlang C formula
  • Discrete event simulation - simulation engine that generates empirical data comparable with theoretical predictions
  • Real-time visualization - charts and metrics updated instantly as parameters change

The application is freely accessible at: https://computationalmindset.com/apps/QueueForge

Foundations of Queueing Theory

Queueing theory is a branch of applied mathematics that studies waiting phenomena. Born in 1909 from the work of Danish engineer Agner Krarup Erlang in the field of telephony, this theory provides mathematical tools for analyzing and optimizing systems in which entities (customers, packets, requests) arrive, wait, and are served.

A queueing system is characterized by three fundamental components:

  • Arrival process: describes how customers arrive in the system (e.g., according to a Poisson process)
  • Service process: describes the duration of service (e.g., with exponential distribution)
  • Service infrastructure: number of servers, queue capacity, service discipline (FIFO, LIFO, priority)

Kendall's notation classifies queueing systems in the form A/B/c/K/N/D, where:

  • A: distribution of inter-arrival times (M = Markovian/exponential, D = deterministic, G = general)
  • B: distribution of service times
  • c: number of servers
  • K: maximum system capacity (omitted if infinite)
  • N: population size (omitted if infinite)
  • D: service discipline (omitted if FIFO)

In the abbreviated form, an M/M/c system means:

  • M (first): arrivals according to a Poisson process (exponential inter-arrival times)
  • M (second): service times with exponential distribution
  • c: number of identical parallel servers
with infinite queue capacity, infinite population, and FIFO discipline.

The M/M/c Model

The M/M/c model is the fundamental queueing theory model for multi-server systems. The main parameters are:

  • Arrival rate $\lambda$ (lambda): average number of customers arriving per unit of time
  • Service rate $\mu$ (mu): average number of customers a single server can handle per unit of time
  • Number of servers $c$: identical parallel servers available

System utilization

The utilization $\rho$ represents the fraction of time servers are busy: $$\rho = \frac{\lambda}{c \cdot \mu}$$ The system is stable (i.e., the queue does not grow indefinitely) if and only if $\rho < 1$, meaning the total service capacity $c \cdot \mu$ exceeds the arrival rate $\lambda$. If $\rho \geq 1$, the queue grows without bound over time.

Erlang C formula

The Erlang C formula calculates the probability that a customer must wait in queue (delay probability). Defining the offered load $a = \lambda / \mu$, the formula is: $$C(c, a) = \frac{\displaystyle \frac{a^c}{c!} \cdot \frac{c}{c - a}}{\displaystyle \sum_{k=0}^{c-1} \frac{a^k}{k!} + \frac{a^c}{c!} \cdot \frac{c}{c - a}}$$ This formula is the foundation for computing all performance metrics of the M/M/c system.

Performance metrics

From the Erlang C formula the fundamental metrics of the system are derived:

Average queue length $L_q$ (average number of customers waiting, excluding those being served): $$L_q = C(c, a) \cdot \frac{\rho}{1 - \rho}$$

Average number of customers in the system $L$ (waiting + being served): $$L = L_q + \frac{\lambda}{\mu}$$

Average waiting time in queue $W_q$ (derived from Little's Law): $$W_q = \frac{L_q}{\lambda}$$

Average time in the system $W$ (waiting + service): $$W = \frac{L}{\lambda}$$

Little's Law

Little's Law is a fundamental theorem that holds for any stable queueing system, regardless of the arrival or service distribution: $$L = \lambda \cdot W$$ and analogously for the queue: $$L_q = \lambda \cdot W_q$$ This relationship is used both in theoretical calculations and in simulation validation.

Numerical example: M/M/1 queue

As a special case of the M/M/c model with $c = 1$, consider a system with $\lambda = 6$ customers/min and $\mu = 10$ customers/min:

  • Utilization: $\rho = 6 / (1 \times 10) = 0.6$ (60%)
  • Average queue length: $L_q = 0.9$ customers
  • Average waiting time: $W_q = 0.15$ min = 9 seconds

Numerical example: M/M/2 queue

For a call center with 2 agents ($c = 2$), $\lambda = 10$ customers/min and $\mu = 8$ customers/min per server:

  • Utilization: $\rho = 10 / (2 \times 8) = 0.625$ (62.5%)
  • Probability of waiting (Erlang C): $C(2, 1.25) \approx 0.481$
  • Average queue length: $L_q \approx 0.8$ customers

Discrete Event Simulation

Beyond the theoretical calculation, QueueForge implements a discrete event simulation engine that generates empirical data comparable with the predictions of the mathematical model.

The simulation operates in discrete time steps, and at each step it performs the following operations:

  1. Arrival generation: checks whether a new customer arrives in the current step, using a Bernoulli trial with probability $p_{\text{arrival}} = \lambda \cdot \Delta t$ (Poisson process approximation for small $\Delta t$)
  2. Service completion: for each busy server, checks whether service is completed with probability $p_{\text{service}} = \mu \cdot \Delta t$ (exponential process approximation)
  3. Queue management: waiting customers are assigned to available servers according to FIFO discipline
  4. Statistics collection: cumulative metrics are updated (average queue length, average waiting time, etc.)

This approach allows users to observe how empirical values converge toward theoretical predictions as simulation time increases. For sufficiently long simulations (over 5000 seconds), empirical results tend to converge within 5-10% of theoretical values.

User Interface and Interaction

QueueForge provides an intuitive and professional interface with several key features:

  • Interactive sliders: real-time adjustment of arrival rate ($\lambda$), service rate ($\mu$), number of servers ($c$), and simulation speed
  • Real-time chart: canvas visualization of queue length evolution over time
  • System metrics: current queue length, utilization, and theoretical vs. empirical averages side by side
  • Educational tooltips: hovering over parameters displays an explanation of their meaning
  • Simulation controls: Play, Pause, and Reset buttons to control the simulation flow

The main interaction consists of modifying system parameters and immediately observing the effect on both the theoretical metrics (computed analytically) and the running simulation, thereby building a deep intuition for the behavior of queueing systems.

Technical Implementation

QueueForge is built using modern web technologies and follows an architecture with clean separation of concerns:

  • React 18: component-based UI framework for building the application structure
  • TypeScript: with strict mode enabled for type safety and code maintainability
  • Vite: modern build tool for fast development and optimized production builds
  • SCSS: CSS with variables and modules for structured styling
  • Canvas API: custom chart rendering for optimal performance

The project architecture is organized into four distinct layers:

  1. Models layer (models/): pure mathematical functions implementing M/M/c queueing theory formulas (Erlang C, Little's Law, etc.)
  2. Simulation layer (simulation/): discrete event simulation engine that generates empirical data
  3. Visualization layer (visualization/): Canvas-based rendering optimized for real-time updates
  4. UI layer (components/, App.tsx): React components orchestrating user interaction

The test suite ensures code coverage above 70%, verifying the accuracy of M/M/c formulas, compliance with Little's Law, simulation convergence, and correct detection of system instability.

Try QueueForge

Experience QueueForge directly in your browser:

Launch QueueForge

The application requires no installation and works on any modern web browser. For the best experience, use a recent version of Chrome, Firefox, Safari, or Edge.

Development and Contribution

QueueForge was developed with Claude Code following the BMAD (Breakthrough Method of Agile AI-driven Development) approach, as part of an exploration in AI-assisted software development for educational tools.

The project follows standard modern TypeScript and JavaScript development practices:

Clone the repository:

git clone https://github.com/ettoremessina/QueueForge.git
cd QueueForge

Install dependencies:

npm install

Run development server:

npm run dev
This starts a local development server with hot module replacement for rapid iteration.

Build for production:

npm run build
The optimized output is generated in the dist/ folder and can be deployed to any static hosting service.

Run tests:

npm test

Source Code and License

The complete source code is available on GitHub at this address: QueueForge.

These materials are distributed under MIT license; feel free to use, share, fork and adapt these materials as you see fit.
Also please feel free to submit pull-requests and bug-reports to this GitHub repository or contact me on my social media channels available on the top right corner of this page.