Simulation and analysis of university cafeteria performance:
Queuing model for throughput in the university cafeteria, identification of bottlenecks, and proposal of
solutions to optimize throughput times.
University canteens play a pivotal role in supporting students by providing reliable nutrition and a space
for social interaction. However, the bustling nature of these canteens often leads to challenges in
managing the flow of customers efficiently, resulting in long queues, extended service times, and an
overall suboptimal experience.
Recognizing the need to address these issues, I participated as a master's student in a team focused on
developing queuing models aimed at enhancing the efficiency of university canteens.
Under faculty supervision, we were tasked with simulating a queuing model to replicate the operational
dynamics of our university canteen. This endeavor aimed to help us better understand the entire queuing
process - from the moment a student arrives at the canteen counter to the completion of their payment.
The objectives of this simulation project were twofold: first, to gain deeper insight into the complex
interactions between customers, service providers, and available resources; and second, to identify
potential bottlenecks within the existing system.
This project explores the methodologies employed, the significance of queuing theory - an established
branch of operations research - and how it applies to the context of university canteens. We also discuss
the challenges encountered during the simulation process, the key findings that emerged from the analysis,
and the proposed solutions to address the identified bottlenecks.
By shedding light on this research, we aim to foster a broader conversation about the practical
applications of queuing models in real-world scenarios and present effective solutions to increase
capacity, reduce service times, and ultimately optimize the overall customer lead time.
STEP 1: Business Understanding
I. Queuing Theory:
The university canteen project shares several characteristics with queuing theory, a mathematical framework
used to model queue-based service environments such as convenience stores, restaurants or emergency
services, as well as in business operations like telecommunications, logistics and banking.
Queuing theory helps optimize resource allocation and improve customer service by identifying bottlenecks
through the calculation of the utilization factor for each station.
II. Data generation:
Another key component of this project is the generation of data for simulation models. Data generation is
instrumental in defining probability distributions for input variables such as arrival rates and service
times. Using Monte Carlo simulation, we generated large sets of random samples to simulate various
scenarios within the queuing system.
Key Performance Indicators (KPI) focused on operational value added to the canteen, particularly
emphasizing capacity, lead times, and the utilization factor of each service station.
STEP 2: Data Understanding
As with any queuing model, customers arrive at the system following a specific arrival process, typically
modeled using Poisson or exponential distributions. Upon arrival, if a server is available, the customer is
served immediately and then proceeds to the next station to complete payment.
To accurately represent the canteen’s queuing system, we considered the following customer states: arrival
at the canteen, interaction with cafeteria staff to order and receive food (first service station), and
payment at the cashier (second service station).
To simulate this system, we applied a Markov chain— a stochastic model consisting of defined states and
transition probabilities between them. Markov queuing processes enable simulation and analysis of system
behavior under varying conditions, operating without memory (future states are not influenced by past
events).
In queuing theory, Kendall’s notation is used to describe and classify queuing nodes. In our case, the
system is represented as M/M/1/1/∞/∞/FIFO, denoting a Markovian arrival process and service times,
one server per station, unlimited queue capacity, and a first-in, first-out service discipline.
STEP 3: Data Preparation
Based on the insights gained during the data understanding phase, we identified the most critical elements
of the queuing system. These were manually captured through direct visits to the university cafeteria,
during which we observed and recorded key details such as peak times when customer demand was highest.
Once sufficient data on arrival rates and service times had been collected, we applied chi-square tests to
evaluate how well the observed data fit a Poisson distribution. As the volume of collected data increased,
the p-value of the chi-square test also rose. After gathering approximately 150 data points, we proceeded
with the Data generation process.
NOTE: To ensure consistency and minimize observer bias, data was collected across multiple days and
time slots, excluding weekends.
# Python CODE: Data Generation def augment_poisson(data_augmented, sim_iteration, label):
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
data_augmented[1].plot(kind="hist", alpha=0.5, label="Order", color="green", bins=100)
plt.xlabel(f"{label} (People per minute)")
plt.ylabel("Frequency")
plt.title("Population Distribution Original")
Following the completion of data collection, we implemented Monte Carlo simulation to generate additional
data points based on the observed data sets. By analyzing the distribution of arrival rates and service
times, I developed two separate data generation functions—one for Poisson-distributed arrival rates and one
for exponentially-distributed service times. These functions generated up to 700 new data points,
replicating the characteristics of the original data distributions.
By defining probability distributions for input variables such as arrival rates and service times and
applying Monte Carlo simulation, we were able to simulate a wide range of scenarios. These scenarios
enabled the estimation of key performance indicators, including average waiting time, queue length,
system utilization, and the probability of delay.
Comparison between the original data and the generated data—based on mean values and distribution
patterns—confirmed that the generated data preserved the statistical properties of the original
dataset.
STEP 4: Data Exploration and Visualization
Exploring the datasets on arrival rates and service times provided early insights into the queuing system’s
behavior and performance. In queuing systems, critical performance metrics such as waiting times,
utilization factor, and lead times are derived through data exploration and are central to evaluating
system efficiency. These performance metrics are also useful for benchmarking different staffing scenarios
or service layouts that could be tested later on.
Using histograms and boxplots we were able to observe skewness, potential outliers and clustering patterns
within the datasets.
Waiting Time: This metric refers to the time a customer spends in the queue before being served. It
is calculated by measuring the difference between the time of arrival and the start of service.
Lead Time: Lead time captures the total time a customer spends in the system, from arrival to the
completion of service. It includes both waiting and service time and is calculated by tracking the full
customer journey.
Utilization Factor: The utilization factor represents the percentage of time that service stations
(servers) are actively serving customers relative to their total availability. It is a key indicator of
system capacity and efficiency.
STEP 5: Feature Engineering
To accurately calculate these performance metrics in a simulation model, it is necessary to capture precise
timestamps for customer arrivals, service start, service end, and departure. In our simulation model, we
defined the following key elements: --> 'Client Number' -->'Arrival Rate' --> 'Waiting time before
Canteen' --> 'Service Time Canteen' --> 'Waiting time before Cashier' --> 'Service Time Cashier'
--> 'Lead Time'
By tracking these values and applying suitable algorithms, we were able to compute the waiting times, lead
times, and utilization factors necessary to evaluate system performance and highlight opportunities for
operational improvement. The purpose of creating these features is not only to track customer movement
through the system but also to maintain traceability of the simulation output.
# Python CODE: Calculating Utilization factor through average of dataset avg_arrival_rate = np.mean(new_arrival) / 60
avg_service_time_uno = new_order.mean()
avg_service_time_dos = new_cashier.mean()
client_data = pd.DataFrame(columns=['Client Number', 'Arrival Rate', 'Waiting time before Canteen',
'Service Time Canteen', "Waiting time before Cashier", "Service Time Cashier", "Lead Time"])
client_data["Waiting time before Canteen"] = (client_data["Waiting time before Canteen"] -
client_data["Service Time Canteen"]).abs()
client_data["Waiting time before Cashier"] = (client_data["Waiting time before Cashier"] -
client_data["Service Time Cashier"]).abs()
client_data["Lead Time"] = client_data[['Waiting time before Canteen', 'Service Time Canteen',
"Waiting time before Cashier", "Service Time Cashier", "Lead Time"]].sum(axis=1)
STEP 6: Model Building and Training
For this queuing system simulation, we used Python and integrated the SimPy library, a discrete event
simulation (DES) package designed to model dynamic process behavior and resource management. SimPy allowed
us to recreate the canteen environment, simulating how resources (canteen and cashier stations) interact
with arriving customers.
The python code replicates queuing behavior by randomly selecting values from the three generated datasets,
representing the inherent variability in daily cafeteria operations. The random selection process ensures
that every simulation run presents a different variation, which allows for better stress-testing of the
system.
In the arrival process, the first station (Canteen) receives inter-arrival times from the
"arrival_process_stations" function and processes service durations through the "service_process_canteen"
function. Once a customer's request is completed, it is passed to the second station (CASHIER), which is
simulated using the service_process_cashier function.
# Python CODE: Building the Queueing Model env = simpy.Environment()
# What is simpy.Environment()? Within the SimPy library, the Environment class represent the environment where events occur and are
scheduled, following key features exclusive to the SimPy library like Simulation Time, Event Scheduling and
Handling, Process Execution, etc.
# What is simpy.Resource()? Within the SimPy library, the Resource class represents the contention capacity within a station, it
represents how many processes can run concurrently. Within the python code, customers generate
request() in order to get access to the resource and are then release() once the task is
completed.
# What is simpy.Store()? Within the SimPy library, the Store class represents the queues, buffers, or holding areas where
simulation processes put events if the Resource() is occupied. The Resource() class retrieves
events by using the get() function.
Arrival events are generated by sampling random arrival rate values (measured in arrivals per minute),
which are converted into inter-arrival times to determine how long the system waits before processing the
next customer.
Each new customer is assigned a client number and added to the canteen queue (station_order) using the
put() method. The canteen station processes customers via the get() method, tracking the
customer's arrival time, waiting time before service, and time spent in the service station.
# Python CODE: Arrivals def arrival_process_stations(env, client_number, client_data):
while True:
arrival_select = np.random.choice(new_arrival.values)
client_data.loc[client_number, 'Arrival Rate'] = arrival_select
if arrival_select != 0:
interarrival_time = 60 / arrival_select
else:
interarrival_time = 60
yield env.timeout(interarrival_time)
client_number += 1
station_order.put((env.now, client_number))
env.process(service_process_order(env, client_data))
# Python CODE: Service def service_process_cashier(env, client_data):
while True:
with server_number_dos.request() as request:
yield request
arrival_time, client_number = yield station_cashier.get()
service_time_dos = np.random.choice(new_cashier.values)
yield env.timeout(service_time_dos)
client_data.loc[client_number, "Service Time Cashier"] = service_time_dos
client_data.loc[client_number, 'Waiting time before Cashier'] = env.now - arrival_time
env.process(service_process_cashier(env, client_data))
The cashier station operates similarly: it retrieves the next customer from the intermediate queue
(station_cashier) using the get() method and records the waiting time before the cashier, the
service time, and the total time spent at the station.
Once the cashier process is completed, the simulation calculates the lead time for each customer. After the
simulation run, system-wide metrics are computed, including the utilization factors of both stations and
the total number of customers served.
STEP 7: Model Evaluation and Comparison
To assess the accuracy of the simulation, we calculated the utilization factor of each station using two
approaches: first, by applying the average arrival and service times from the dataset, and second, by
manually computing utilization using the timestamps recorded during the simulation.
Results from the dataset: + Utilization factor of the CANTEEN station: 1.4912927763838917
+ Utilization factor of the CASHIER station: 0.9009195651771269
Results from the simulation model: + Utilization factor of the CANTEEN station: 1.498312288696883
+ Utilization factor of the CASHIER station: 0.9030687642105081
NOTE: This comparison helps to validate that the expected values from the dataset align with the
behavior captured during the simulation.
Both visual inspection of the simulation and the utilization factor results confirm that the primary
bottleneck occurs at the canteen service station. This bottleneck was further evaluated by increasing the
number of servers at this station to observe the effect on utilization and waiting times.
Average measures from a (1 Server per Station): + Waiting time before Canteen 10020.542148
+ Service Time Canteen 38.377895
+ Waiting time before Cashier 15.112265
+ Service Time Cashier 23.131278
+ Lead Time 9042.589862
# PYTHON RESULTS (1 Server per Station): Client Number 1
Waiting time before Order 0.0
Service Time Order 22.832561
Waiting time before Cashier 0.0
Service Time Cashier 51.881967
Lead Time 74.714528
Name: 1, dtype: object
Client Number 48
Waiting time before Order 391.274495
Service Time Order 38.645774
Waiting time before Cashier 0.0
Service Time Cashier 21.77937
Lead Time 451.699639
Name: 48, dtype: object
The results demonstrated a clear reduction in waiting times and utilization at the canteen station when the
number of servers was increased. Once the utilization factor drops below 1, the queueing system stabilizes,
and the bottleneck is no longer persistent.
Average measures from a (2 Servers in Canteen, 1 in Cashier): + Waiting time before Canteen 6.566400
+ Service Time Canteen 40.652416
+ Waiting time before Cashier 25.384632
+ Service Time Cashier 23.698804
+ Lead Time 96.270926
The simulation outputs, including average waiting times and service metrics, show measurable performance
improvements and confirm that the adjustments made to the system architecture effectively address queue
delays. This positively demonstrates how even small changes to the queuing system can have noticeable
effects on service quality and flow.
STEP 8: Model Refinement
There are several ways to improve a queuing model to more accurately reflect the reality of a queuing
system, such as incorporating realistic variations in workload, which often manifest as fluctuations in
customer arrivals and service demands throughout the day (e.g., peak and off-peak hours).
If the simulation assumes a constant arrival rate, it may misrepresent actual demand patterns. To address
this, scaling the arrival rate based on different times of day helps simulate the increased strain during
peak hours and better captures real-world workload variability.
Incorporating peak and off-peak periods into the queuing simulation enhances the model's accuracy and
realism. It allows for a more precise representation of operational dynamics, supports better staffing and
scheduling decisions, improves overall performance evaluation, informs capacity planning, and
ultimately enables more effective decision-making.
CONCLUSION: By developing a queuing model that closely mirrors the operations of the university
canteen, we can accurately identify system bottlenecks and propose adjustments to capacity and service
times as viable solutions.
The simulation showed that implementing "2 Servers in Canteen, 1 in Cashier" effectively removes major
bottlenecks during normal operation. However, the system remains sensitive to peak times, when customer
arrival rates significantly increase compared to regular hours.
These findings support data-driven decisions that accommodate the dynamic nature of the system and its
customer demand. Continued testing with the simulation model will provide further insight into how the
queuing system performs under high-demand conditions and how it can be optimized to manage peak periods
more efficiently.
NOTE: These proposed adjustments are directly supported by the simulation results and show
measurable improvements in flow and throughput. Which proves the effectiveness of the simulation model as
it can also be scaled and reused to evaluate future changes such as layout redesigns or the integration of
self-service technology.