DATA 604 : Week 11 Assignment

Author: Rupendra Shrestha | April 25, 2026

Instructions

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

Introduction

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.

Objectives

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

Data Overview

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.

Data Preparations and Inputs

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")
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")
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

Arrival and Service Modeling

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")
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")
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")
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")
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.

Simulation Model Design - Resource Allocation

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")
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
unique(ds_work$Position)
[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)
cat("Food production:", num_food, "\n")
Food production: 6 
cat("Customer service:", num_cust, "\n")
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")
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 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")
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.

env_base %>% run(until = 840)  
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")
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")
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")
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)")
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.

Staffing Analysis

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 }
res_s1 <- get_mon_resources(sim_s1)
kable(head(res_s1), caption = "Resource Activity Sample")
Resource Activity Sample
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 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")
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 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 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.

Performance Analysis

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.

Food Production and Inventory Strategy

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.

Model Improvements

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.

Investment Evaluation

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.

Conclusion

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.