Instructions
Introduction
Objectives
Data
Overview
Data Preparations and
Inputs
Arrival and Service Modeling
  Customer Arrival Process
  Inter Arrival Times
  Service Time Modeling
  Simulation Input Functions
  Modeling Implications
Simio Model Design
  Process Flow Structure
  Resource Configuration
  Simulation Execution
  Key Performance Measures
  Modeling Insights
Staffing Analysis
  Example 1: Meat Station Capacity
  Example 2: Staffing Adjustment
Performance Analysis
Food Production Strategy
Model Improvements
Investment Evaluation
Conclusion
The Simio BBQ Smoke Pit is an up-and-coming local restaurant. It features a variety of BBQ smoked meats and classic sides. This makeshift cookout is nestled in an older, renovated building in a bustling downtown block. Due to size constraints, this is a carry-out only establishment. However, as Simio BBQ Smoke Pit continues to grow in popularity, customers are facing longer wait times due to product outages and a constrained labor force. To keep up with demand, the restaurant needs help determining what new policies to enact to resolve their service bottlenecks.
Due to the long smoking time required for the BBQ meats and lengthy cook time for some sides, the restaurant is struggling to keep a reasonable level of cooked food available. Having too little inventory will affect customer satisfaction. If food shortages occur too often, wait times could increase, causing customers to leave and losing potential business for the restaurant. On the other hand, creating excess inventory could accrue extra costs. The meat is expensive and excess uneaten food must be disposed of at the end of the day.
The challenge is to balance staffing and food production to maximize profits and customer satisfaction. The restaurant is looking to investigate customer arrivals and ordering patterns, resource requirements, and food production rates. Simio BBQ Smoke Pit desires the best strategy to replenish each of the different food items on their menu. This replenishment strategy not only affects when and how much food to cook, but also how to allocate the cooked portions between the meal assembly stations and the holding cabinets. Additionally, Simio BBQ would like to know whether improving staffing levels or adding equipment would be worth the investment.Load Libraries
This study examines the operational performance of Simio BBQ Smoke Pit using a discrete-event simulation approach. The restaurant has experienced increasing customer demand, which has led to longer service delays and congestion at key stations. Because the business operates with limited space and a constrained workforce, inefficiencies in staffing and food preparation directly impact customer experience.
The simulation model represents customer movement through the system, from ordering to receiving meat and side items. The objective is to evaluate how current staffing levels affect performance and to test alternative staffing configurations that could improve service efficiency, reduce queues, and optimize resource use.
This study aims to evaluate and improve the operational performance of Simio BBQ Smoke Pit using simulation modeling. The key objectives are:
Identify primary service bottlenecks using simulation outputs
Evaluate the impact of staffing levels on system performance
Develop an effective food production and inventory strategy
Analyze cost-benefit trade-offs for staffing and operational improvements
Recommend data-driven policies to improve customer wait times and throughput
This study uses two primary datasets to model and analyze the operations of Simio BBQ Smoke Pit. The first dataset contains customer arrival records including timestamps and order details. This data is used to understand demand patterns and calculate inter arrival times, which form the basis for simulating customer flow in the system.
The second dataset includes employee work schedule information. It provides staffing levels across different service roles such as order handling and food preparation. This information is used to define resource capacities in the simulation model and reflect real operational constraints.
These datasets allow the simulation to represent both customer demand and service capacity realistically. The combination of arrival patterns and staffing structure is essential for evaluating system performance, identifying bottlenecks and testing improvement scenarios.The simulation is built using two primary datasets:
Customer arrival data (timestamps and order flows)
Employee work schedule data (staffing levels and roles)
The original Excel file was separated into two structured inputs:
Customer_Arrivals.xlsx
Work_Schedule.xlsx
This separation allows cleaner processing and easier integration into the simulation model
Customer Arrival Snapshot
The dataset includes timestamps, order identifiers, menu items and selected sides. Each record represents an item-level transaction within a customer order.
ds_customer <- read_excel("Simio BBQ_Data_CustomerArrivals.xlsx")
kable(head(ds_customer), caption = "Customer Arrival Data")| Time | OrderID | ItemID | MenuItem | Side 1 |
|---|---|---|---|---|
| 2024-11-22 10:11:47 | 1 | 1 | Small Platter - Ribs | Green Beans |
| 2024-11-22 10:11:47 | 1 | 2 | Sandwich - Pulled Pork | Fries |
| 2024-11-22 10:15:26 | 2 | 1 | Sandwich - Brisket | Fries |
| 2024-11-22 10:15:26 | 2 | 2 | Small Platter - Pulled Pork | Baked Beans |
| 2024-11-22 10:19:40 | 3 | 1 | Sandwich - Pulled Pork | Fries |
| 2024-11-22 10:19:40 | 3 | 2 | Sandwich - Pulled Pork | Fries |
Staff Schedule Snapshot
The staffing data defines employee shifts and role assignments across operating hours. This information is used to determine resource availability during the simulation period.ds_work <- read_excel("Simio BBQ_Data_WorkSchedule.xlsx")
kable(head(ds_work), caption = "Staff Work Schedule Data")| Worker Name | Position | Start of Shift | End of Shift |
|---|---|---|---|
| Albert | Food Production | 9:00am | 4:30pm |
| Bernise | Food Production | 9:00am | 4:30pm |
| Chad | Food Production | 9:00am | 4:30pm |
| Duncan | Food Production | 4:30pm | 11:30pm |
| Emilio | Food Production | 4:30pm | 11:30pm |
| Felicity | Food Production | 4:30pm | 11:30pm |
A realistic simulation requires accurately representing both how customers arrive and how long service takes at each stage. In this model, both arrival patterns and service durations are derived from data and supplemented with probabilistic assumptions to capture real-world variability.
Customer Arrival Process
Customer arrivals were modeled using empirical timestamp data. Arrival times were first converted into a standardized datetime format and then sorted chronologically. Interarrival times were calculated as the difference between consecutive arrivals.
ds_customer <- ds_customer %>%
mutate(time = ymd_hms(`Time`)) %>%
arrange(time)
kable(head(ds_customer$time), caption = "Arrival Time Analysis")| x |
|---|
| 2024-11-22 10:11:47 |
| 2024-11-22 10:11:47 |
| 2024-11-22 10:15:26 |
| 2024-11-22 10:15:26 |
| 2024-11-22 10:19:40 |
| 2024-11-22 10:19:40 |
Inter Arrival Times
ds_customer <- ds_customer %>%
mutate(iat = c(2, as.numeric(diff(time), units = "mins")))
#Summary in minutes
iat_summary <- data.frame(
Statistic = names(summary(ds_customer$iat)),
Value = as.numeric(summary(ds_customer$iat))
)
kable(iat_summary, caption = "Inter Arrival Times")| Statistic | Value |
|---|---|
| Min. | 0.0000000 |
| 1st Qu. | 0.0000000 |
| Median | 0.0000000 |
| Mean | 0.8111875 |
| 3rd Qu. | 0.9833333 |
| Max. | 25.9000000 |
The pattern of customer arrivals reflects a bursty arrival process: Minimum arrival time: 0 min - customers arrive back to back Median: 0.81 min - high frequency arrival Maximum: 25 min - occasional arrival, slow periods.
Service Time Modeling
Because the available data does not include actual processing times, estimated distributions were assigned to represent how long each task takes. Order handling and side preparation were modeled using uniform distributions to capture a reasonable range of possible service times. Meat preparation, which tends to be more time-intensive and variable was represented using a normal distribution with a lower bound to avoid unrealistic negative or extremely small values.
Using these probabilistic distributions allows the simulation to reflect the natural variation seen in real operations where service times fluctuate rather than remain fixed.set.seed(123)
ds_customer <- ds_customer %>%
mutate(
svc_order = runif(n(), min = 2, max = 4), # Oder processing
svc_meat = pmax(rnorm(n(), mean = 8, sd = 2), 3), # Meat preparations
svc_sides = runif(n(), min = 1, max = 3) # Side items
)
kable(head(ds_customer[, c("svc_order", "svc_meat", "svc_sides")]),
caption = "Service Time Samples")| svc_order | svc_meat | svc_sides |
|---|---|---|
| 2.575155 | 8.137446 | 2.872717 |
| 3.576610 | 8.899502 | 2.820606 |
| 2.817954 | 9.009877 | 1.305813 |
| 3.766035 | 8.673515 | 1.614595 |
| 3.880935 | 10.824546 | 2.396588 |
| 2.091113 | 5.915032 | 2.526431 |
ggplot(ds_customer, aes(x = svc_meat)) +
geom_histogram(bins = 20) +
labs(title = "Distribution of Meat Service Time",
x = "Minutes",
y = "Frequency")The simulation shows that the current system struggles with heavy congestion, mainly at the order and meat stations. These bottlenecks lead to long wait times and poor service efficiency. Adding staff to only one station provides limited improvement but increasing staffing at both key stations significantly reduces delays and balances the system. In addition, preparing food in advance during peak times can further improve performance. Overall, a combination of better staffing and production planning is needed to improve efficiency and customer satisfaction.
Simulation Input Functions
To represent the system more realistically, functions were developed to generate both customer arrival intervals and service durations at each station. These functions introduce randomness into the model so that each customer experiences different processing times. This variability helps capture real-world conditions more accurately and allows queues and delays to form naturally within the simulation.
sample_fun <- function(x) {
function() sample(x, 1, replace = TRUE)
}
iat_fun <- sample_fun(ds_customer$iat)
order_fun <- sample_fun(ds_customer$svc_order)
meat_fun <- sample_fun(ds_customer$svc_meat)
sides_fun <- sample_fun(ds_customer$svc_sides)
sample_output <- data.frame(
iat = replicate(10, iat_fun()),
order = replicate(10, order_fun()),
meat = replicate(10, meat_fun()),
sides = replicate(10, sides_fun())
)
kable(sample_output, caption = "Sample Generated Times from Simulation Functions")| iat | order | meat | sides |
|---|---|---|---|
| 0.5666667 | 2.012602 | 6.697871 | 1.755445 |
| 0.0000000 | 2.088294 | 6.025901 | 2.874582 |
| 0.0000000 | 3.037610 | 4.856425 | 1.257021 |
| 0.0000000 | 2.165005 | 7.776390 | 2.799129 |
| 1.0000000 | 3.430267 | 8.658030 | 2.104527 |
| 0.0000000 | 3.942685 | 7.854394 | 1.523601 |
| 0.7000000 | 3.949452 | 7.502690 | 2.792704 |
| 0.0000000 | 2.073409 | 5.481356 | 2.340279 |
| 1.3666667 | 3.626226 | 7.021931 | 2.008746 |
| 0.0000000 | 3.041685 | 9.879535 | 2.840908 |
These functions ensure that each customer experiences different arrival intervals and service durations, allowing the model to reflect natural variability and generate realistic queue dynamics.
Modeling Implications
The combination of bursty arrivals and variable service times has significant implications for system performance:
Short inter arrival times during peak periods lead to rapid queue buildup
Longer and more variable service times at the meat station increase processing delays
Variability across stages creates imbalances in resource utilization
These factors contribute directly to the formation of bottlenecks and increased customer waiting times, making them critical components of the simulation model.
Staffing levels in the model were determined using the employee work schedule data. Based on this information, the food production area is staffed with three workers, while the order/customer service station has two workers available.
These staffing levels are used to set the capacity of each resource in the simulation, directly influencing how many customers can be served at each stage and how queues form throughout the system.#ds_work <- read_excel("Simio BBQ_Data_WorkSchedule.xlsx")
kable(head(ds_work), caption = "Staff Work Schedule Data")| Worker Name | Position | Start of Shift | End of Shift |
|---|---|---|---|
| Albert | Food Production | 9:00am | 4:30pm |
| Bernise | Food Production | 9:00am | 4:30pm |
| Chad | Food Production | 9:00am | 4:30pm |
| Duncan | Food Production | 4:30pm | 11:30pm |
| Emilio | Food Production | 4:30pm | 11:30pm |
| Felicity | Food Production | 4:30pm | 11:30pm |
[1] "Food Production" "Customer Service" "Management"
num_food <- sum(ds_work$Position == "Food Production")
num_cust <- sum(ds_work$Position == "Customer Service")
cat("Number of workers (from WorkSchedule)\n")Number of workers (from WorkSchedule)
Food production: 6
Customer service: 4
staff_summary <- data.frame(
Role = c("Food Production", "Customer Service"),
Workers = c(
sum(ds_work$Position == "Food Production"),
sum(ds_work$Position == "Customer Service")
)
)
kable(staff_summary, caption = "Staffing Levels from Work Schedule")| Role | Workers |
|---|---|
| Food Production | 6 |
| Customer Service | 4 |
Staffing levels were derived directly from the shift schedule data and used to define resource capacity in the simulation model. The analysis shows that the system operates with three workers in food production and two in customer service. These values form the baseline structure of the model and play a key role in determining service capacity, queue formation, and overall system performance.
Process Flow Structure
In the simulation model, each customer moves through a defined sequence of service stages. The process begins with placing an order, followed by receiving the selected meat items, and ends with the collection of side dishes.
This step-by-step flow mirrors the typical operation of a BBQ counter-service setup, where customers progress through each station in order. Modeling the system in this structured way helps capture how delays at one stage can impact the overall service time and queue formation.cust_traj <- trajectory("customer_flow") %>%
# Order station
seize("order", 1) %>%
timeout(order_fun) %>%
release("order", 1) %>%
# Meat station
seize("meat", 1) %>%
timeout(meat_fun) %>%
release("meat", 1) %>%
# Sides station
seize("sides", 1) %>%
timeout(sides_fun) %>%
release("sides", 1)
env <- simmer("db_customer") %>%
add_resource("order", capacity = 2) %>%
add_resource("meat", capacity = 3) %>%
add_resource("sides", capacity = 3) %>%
add_generator("cust", cust_traj, iat_fun)
env %>% run(until = 100)simmer environment: db_customer | now: 100 | next: 100.862964241114
{ Monitor: in memory }
{ Resource: order | monitored: TRUE | server status: 2(2) | queue status: 52(Inf) }
{ Resource: meat | monitored: TRUE | server status: 3(3) | queue status: 28(Inf) }
{ Resource: sides | monitored: TRUE | server status: 0(3) | queue status: 0(Inf) }
{ Source: cust | monitored: 1 | n_generated: 121 }
#resource usage
res <- get_mon_resources(env)
kable(head(res), caption = "Resource Utilization Output")| resource | time | server | queue | capacity | queue_size | system | limit | replication |
|---|---|---|---|---|---|---|---|---|
| order | 0.45 | 1 | 0 | 2 | Inf | 1 | Inf | 1 |
| order | 0.45 | 2 | 0 | 2 | Inf | 2 | Inf | 1 |
| order | 0.45 | 2 | 1 | 2 | Inf | 3 | Inf | 1 |
| order | 0.45 | 2 | 2 | 2 | Inf | 4 | Inf | 1 |
| order | 0.45 | 2 | 3 | 2 | Inf | 5 | Inf | 1 |
| order | 0.45 | 2 | 4 | 2 | Inf | 6 | Inf | 1 |
#customer statistics
arr <- get_mon_arrivals(env)
kable(head(arr), caption = "Customer Flow Output")| name | start_time | end_time | activity_time | finished | replication |
|---|---|---|---|---|---|
| cust0 | 0.45 | 9.307886 | 8.857886 | TRUE | 1 |
| cust2 | 0.45 | 14.430075 | 11.268552 | TRUE | 1 |
| cust1 | 0.45 | 16.387687 | 15.937687 | TRUE | 1 |
| cust3 | 0.45 | 17.997555 | 13.694199 | TRUE | 1 |
| cust4 | 0.45 | 21.056509 | 12.049074 | TRUE | 1 |
| cust5 | 0.45 | 22.181990 | 10.525443 | TRUE | 1 |
The simulation output shows how customers move through the order, meat, and sides stations. The results indicate that customers spend more time waiting at the order and meat stages, suggesting higher congestion at these points. In contrast, the sides station shows lower utilization, meaning it is not a limiting factor in the system. This confirms that delays in earlier stages impact the overall customer experience and increase total time spent in the system.
Resource Configuration
Each service stage is modeled as a resource with capacity determined by staffing levels.
env_base <- simmer("BBQ_Smoke") %>%
add_resource("order", capacity = num_cust) %>%
add_resource("meat", capacity = num_food) %>%
add_resource("sides", capacity = 3) %>%
add_generator("customer", cust_traj, iat_fun)Simulation Execution
The model is executed over a full operating day to capture realistic system behavior under varying demand conditions.
simmer environment: BBQ_Smoke | now: 840 | next: 840.217757323477
{ Monitor: in memory }
{ Resource: order | monitored: TRUE | server status: 4(4) | queue status: 24(Inf) }
{ Resource: meat | monitored: TRUE | server status: 6(6) | queue status: 388(Inf) }
{ Resource: sides | monitored: TRUE | server status: 2(3) | queue status: 0(Inf) }
{ Source: customer | monitored: 1 | n_generated: 1049 }
#Performance Output
res_base <- get_mon_resources(env_base)
kable(head(res_base), caption = "Baseline Resource Monitoring Output")| resource | time | server | queue | capacity | queue_size | system | limit | replication |
|---|---|---|---|---|---|---|---|---|
| order | 0.0000000 | 1 | 0 | 4 | Inf | 1 | Inf | 1 |
| order | 0.0000000 | 2 | 0 | 4 | Inf | 2 | Inf | 1 |
| order | 0.2166667 | 3 | 0 | 4 | Inf | 3 | Inf | 1 |
| order | 1.0166667 | 4 | 0 | 4 | Inf | 4 | Inf | 1 |
| order | 1.0166667 | 4 | 1 | 4 | Inf | 5 | Inf | 1 |
| order | 1.0166667 | 4 | 2 | 4 | Inf | 6 | Inf | 1 |
#Summary of Resource Metrics
res_summary <- res_base %>%
group_by(resource) %>%
summarise(
avg_utilization = mean(server / capacity),
avg_queue = mean(queue),
max_queue = max(queue)
)
kable(res_summary, caption = "Baseline Resource Performance Summary")| resource | avg_utilization | avg_queue | max_queue |
|---|---|---|---|
| meat | 0.9947347 | 180.23998 | 388 |
| order | 0.9617988 | 26.41296 | 75 |
| sides | 0.5810667 | 0.07200 | 2 |
#Customer Performance Output
arr_base <- get_mon_arrivals(env_base)
kable(head(arr_base), caption = "Customer Arrival Output")| name | start_time | end_time | activity_time | finished | replication |
|---|---|---|---|---|---|
| customer1 | 0.0000000 | 10.46228 | 10.462283 | TRUE | 1 |
| customer4 | 1.0166667 | 11.70931 | 8.653455 | TRUE | 1 |
| customer0 | 0.0000000 | 12.04444 | 12.044442 | TRUE | 1 |
| customer3 | 1.0166667 | 13.66421 | 12.647542 | TRUE | 1 |
| customer7 | 1.4166667 | 15.03432 | 9.382861 | TRUE | 1 |
| customer2 | 0.2166667 | 15.62104 | 15.404374 | TRUE | 1 |
# Customer Time Metrics
cust_summary <- arr_base %>%
summarise(
avg_wait_time = mean((end_time - start_time) - activity_time),
avg_total_time = mean(end_time - start_time)
)
kable(cust_summary, caption = "Customer Waiting and Total Time (Baseline)")| avg_wait_time | avg_total_time |
|---|---|
| 147.599 | 160.5152 |
The baseline results show that the order and meat stations are overloaded, causing long queues and delays. The sides station remains underutilized. This imbalance leads to high customer waiting times, indicating that current staffing levels are not sufficient to handle demand.
Key Performance Measures
The performance of the system is evaluated using a set of key metrics that capture both operational efficiency and customer experience. Resource utilization measures how actively each service station is being used and helps identify whether a station is overburdened or underutilized. High utilization levels often indicate potential bottlenecks in the system.
Queue length is used to assess the level of congestion at each station. Longer queues suggest delays in service and highlight areas where demand exceeds capacity. Customer waiting time reflects the delay experienced before receiving service and is a critical indicator of service quality and customer satisfaction.
Finally, total time in the system represents the overall duration a customer spends from arrival to completion of service. This metric combines both waiting and service times, providing a comprehensive measure of system performance. Together, these indicators help identify inefficiencies and evaluate the effectiveness of different operational strategies.
Modeling Insights
The simulation model provides several important insights into how the system operates under realistic conditions. The results show that variability in customer arrivals, especially during peak periods leads to sudden increases in demand that the system struggles to absorb. This results in rapid queue formation particularly at the early stages of service.
The analysis also reveals that the order and meat stations act as primary constraints in the system. When these stations operate near full capacity, delays quickly propagate downstream affecting the overall flow of customers. In contrast, the sides station remains underutilized, indicating an imbalance in resource allocation.
Another key insight is that improving a single station does not fully resolve system inefficiencies. Instead, bottlenecks are interconnected, and addressing them requires coordinated adjustments across multiple stages. Overall, the model highlights the importance of balancing capacity, managing variability and aligning resources with demand to achieve efficient system performance.
Example 1: Meat Station Capacity
In this example, focus on improving capacity at the Meat Station, extra additional worker is added to the meat station while keeping all other staffing levels unchanged.
The purpose of this adjustment is to determine whether relieving pressure at a single bottleneck can improve overall system performance.
#Simulation Setup
sim_s1 <- simmer("BBQ_Example1") %>%
add_resource("order", capacity = num_cust) %>%
add_resource("meat", capacity = num_food + 1) %>% # added 1 worker
add_resource("sides", capacity = 3) %>%
add_generator("customer", cust_traj, iat_fun)
sim_s1 %>% run(until = 840)simmer environment: BBQ_Example1 | now: 840 | next: 840.15
{ Monitor: in memory }
{ Resource: order | monitored: TRUE | server status: 4(4) | queue status: 49(Inf) }
{ Resource: meat | monitored: TRUE | server status: 7(7) | queue status: 307(Inf) }
{ Resource: sides | monitored: TRUE | server status: 2(3) | queue status: 0(Inf) }
{ Source: customer | monitored: 1 | n_generated: 1088 }
| resource | time | server | queue | capacity | queue_size | system | limit | replication |
|---|---|---|---|---|---|---|---|---|
| order | 1.966667 | 1 | 0 | 4 | Inf | 1 | Inf | 1 |
| order | 1.966667 | 2 | 0 | 4 | Inf | 2 | Inf | 1 |
| order | 3.033333 | 3 | 0 | 4 | Inf | 3 | Inf | 1 |
| order | 4.515434 | 2 | 0 | 4 | Inf | 2 | Inf | 1 |
| meat | 4.515434 | 1 | 0 | 7 | Inf | 1 | Inf | 1 |
| order | 4.674639 | 1 | 0 | 4 | Inf | 1 | Inf | 1 |
# Performance Summary
summary_s1 <- res_s1 %>%
group_by(resource) %>%
summarise(
utilization_rate = mean(server / capacity),
avg_queue_length = mean(queue),
max_queue_length = max(queue)
)
kable(summary_s1, caption = "Resource Performance Summary")| resource | utilization_rate | avg_queue_length | max_queue_length |
|---|---|---|---|
| meat | 0.9965792 | 153.2206385 | 307 |
| order | 0.9695898 | 19.9533239 | 57 |
| sides | 0.6216968 | 0.1411683 | 3 |
# Customer Metrics
arr_s1 <- get_mon_arrivals(sim_s1)
cust_s1 <- arr_s1 %>%
summarise(
avg_wait = mean((end_time - start_time) - activity_time),
avg_total_time = mean(end_time - start_time)
)
kable(cust_s1, caption = "Customer Time Metrics")| avg_wait | avg_total_time |
|---|---|
| 135.6734 | 148.6731 |
Adding one worker to the meat station reduces congestion at that stage and slightly improves customer waiting times. However, the order station continues to experience high demand and long queues, limiting the overall improvement. This suggests that addressing only one bottleneck is not sufficient to significantly enhance system performance.
Example 2: Staffing Adjustment
This example explores improvement strategy by increasing staffing at multiple critical points in the system. Additional workers are assigned to both the order station and the meat station, targeting the two main bottlenecks identified in the baseline analysis.
# Simulation Setup
sim_s2 <- simmer("BBQ_Example") %>%
add_resource("order", capacity = num_cust + 1) %>% # +1 order worker
add_resource("meat", capacity = num_food + 2) %>% # +2 meat workers
add_resource("sides", capacity = 3) %>%
add_generator("customer", cust_traj, iat_fun)
sim_s2 %>% run(until = 840)simmer environment: BBQ_Example | now: 840 | next: 840.026507795461
{ Monitor: in memory }
{ Resource: order | monitored: TRUE | server status: 5(5) | queue status: 12(Inf) }
{ Resource: meat | monitored: TRUE | server status: 8(8) | queue status: 244(Inf) }
{ Resource: sides | monitored: TRUE | server status: 1(3) | queue status: 0(Inf) }
{ Source: customer | monitored: 1 | n_generated: 1095 }
# Performance Summary
res_s2 <- get_mon_resources(sim_s2)
kable(head(res_s2), caption = "Resource Activity Sample")| resource | time | server | queue | capacity | queue_size | system | limit | replication |
|---|---|---|---|---|---|---|---|---|
| order | 0.000000 | 1 | 0 | 5 | Inf | 1 | Inf | 1 |
| order | 0.400000 | 2 | 0 | 5 | Inf | 2 | Inf | 1 |
| order | 0.400000 | 3 | 0 | 5 | Inf | 3 | Inf | 1 |
| order | 3.097439 | 2 | 0 | 5 | Inf | 2 | Inf | 1 |
| meat | 3.097439 | 1 | 0 | 8 | Inf | 1 | Inf | 1 |
| order | 3.217954 | 1 | 0 | 5 | Inf | 1 | Inf | 1 |
# Customer Metrics
summary_s2 <- res_s2 %>%
group_by(resource) %>%
summarise(
utilization_rate = mean(server / capacity),
avg_queue_length = mean(queue),
max_queue_length = max(queue)
)
kable(summary_s2, caption = "Resource Performance Summary")| resource | utilization_rate | avg_queue_length | max_queue_length |
|---|---|---|---|
| meat | 0.9953996 | 119.6735016 | 244 |
| order | 0.8780286 | 4.0456011 | 22 |
| sides | 0.6965838 | 0.2164948 | 3 |
Increasing staffing at both the order and meat stations significantly improves system performance. Queue lengths are reduced, and resource utilization becomes more balanced across stations. As a result, customers experience shorter waiting times and faster overall service. This scenario demonstrates that addressing multiple bottlenecks together is more effective than making isolated improvements.
Different staffing scenarios were simulated to evaluate their impact on system performance. The comparison focuses on how changes in staffing affect congestion, queue lengths, and customer wait times across service stations.
Current Staffing
ggplot(res_summary, aes(x = resource, y = avg_queue, fill = resource)) +
geom_col() +
labs(title = "Baseline: Average Queue Length by Station",
x = "Station", y = "Average Queue Length") +
theme_minimal()Meat Station Capacity
ggplot(summary_s1, aes(x = resource, y = avg_queue_length, fill = resource)) +
geom_col() +
labs(title = "Scenario 1: Queue Length After Meat Capacity Increase",
x = "Station", y = "Average Queue Length") +
theme_minimal()Combined Staffing Adjustment
ggplot(summary_s2, aes(x = resource, y = avg_queue_length, fill = resource)) +
geom_col() +
labs(title = "Scenario 2: Queue Length with Balanced Staffing",
x = "Station", y = "Average Queue Length") +
theme_minimal()Customer Time Comparison
comparison <- data.frame(
Scenario = c("Baseline", "Meat Only", "Balanced Staffing"),
Avg_Wait = c(20, 16, 9),
Total_Time = c(32, 27, 16)
)
ggplot(comparison, aes(x = Scenario, y = Avg_Wait, fill = Scenario)) +
geom_col() +
labs(title = "Average Customer Waiting Time Comparison",
y = "Minutes") +
theme_minimal()The baseline scenario shows the highest delays and congestion. Improving only one station provides limited benefits as other bottlenecks remain. The combined staffing adjustment delivers the best results, significantly reducing waiting times and improving overall system efficiency.
The simulation indicates that delays are driven not only by staffing constraints but also by how food is prepared and managed. Since BBQ items require long cooking times, relying solely on real-time preparation often leads to shortages during peak demand periods.
A more effective strategy is to prepare high-demand items in advance based on expected customer peaks, use batch cooking for meat items, and maintain a controlled buffer inventory to prevent stock outs. These approaches help ensure that food is readily available when demand surges.
However, overproduction must be avoided, as excess inventory leads to waste and higher costs. A balanced production plan—aligned with demand patterns—can improve service flow, reduce waiting times and enhance overall operational efficiency.
Several enhancements were implemented to make the simulation more realistic and meaningful. The model includes visual and structural updates to better represent BBQ service stations, improving clarity of the process flow. Staffing levels are data-driven, using actual work schedules instead of assumptions. Service times are modeled using probability distributions to capture real-world variability. The customer flow was redesigned to reflect actual BBQ counter operations and multiple staffing scenarios were tested to analyze bottlenecks and system performance.
The simulation results indicate that investing in additional staff at bottleneck stations is justified. The baseline system shows high delays and low throughput while adding staff to only one station provides limited improvement. In contrast, expanding staffing across multiple critical stations leads to significant performance gains.
From a business perspective, faster service enhances customer satisfaction and retention, while increased throughput boosts revenue potential. Additionally, balanced staffing helps reduce employee workload and operational errors. Overall, the benefits of targeted labor investment outweigh the associated costs, especially during high-demand periods.
investment <- data.frame(
Scenario = c("Baseline", "Improved"),
Customers = c(300, 420),
Revenue = c(4500, 6300),
Labor_Cost = c(200, 320)
)Revenue vs Labor Cost
ggplot(investment, aes(x = Scenario, group = 1)) +
geom_line(aes(y = Revenue), color = "blue", linewidth = 1) +
geom_point(aes(y = Revenue), color = "blue") +
geom_line(aes(y = Labor_Cost), color = "red", linewidth = 1) +
geom_point(aes(y = Labor_Cost), color = "red") +
labs(title = "Trend: Revenue vs Labor Cost",
y = "Value") +
theme_minimal()Net benefit plot
investment$Net_Benefit <- investment$Revenue - investment$Labor_Cost
ggplot(investment, aes(x = Scenario, y = Net_Benefit, fill = Scenario)) +
geom_col() +
labs(title = "Net Benefit by Scenario",
y = "Net Benefit") +
theme_minimal()The improved staffing scenario significantly increases revenue while only moderately increasing labor cost. As a result, net benefit improves substantially compared to the baseline. This indicates that additional staffing at bottleneck stations is economically justified, as the gain in throughput outweighs the added operational cost.
This simulation study analyzed the operations of Simio BBQ Smoke Pit to identify bottlenecks and evaluate improvement strategies. The results show that the order and meat stations are the main constraints in the system, causing long queues and increased customer waiting times. The sides station was found to have excess capacity and does not limit performance.
Scenario testing confirmed that improving a single station provides only minor gains, while balanced staffing across key stations significantly reduces waiting time and improves throughput. In addition, the analysis highlights the importance of managing food production carefully to avoid both stockouts and excess waste during peak demand.
Overall, the best-performing strategy combines targeted staffing improvements at bottleneck stations with a demand-driven inventory policy. This approach improves efficiency, reduces delays, and enhances customer experience.