Abstract

This project develops a discrete-event simulation model of an e-commerce warehouse fulfillment system using R and the simmer package. The model simulates the process of customer orders form online purchase through inventory checking, picking, packing, and shipping. The simulation evaluates warehouse performance using metrics such as fulfillment time, queue length and resource utilization. The results would help identify operational bottlenecks and demonstrate how warehouse efficiency can be improved through better resource allocation. This project shows the application of simulation techniques in modern e-commerce and supply chain management.

Keywords:discrete event simulation, process flow, warehouse process, fulfillment system

Introduction

The rapid growth of e-commerce has increased the demand for efficent warehouse and delivery operations. Companies such as Amazon use advanced fulfillment centers, automation, and logistics systems to process customer orders quickly and accurately. Warehouse operations sucha s inventory checking, picking, packing, and shipping play a major role in customer satisfaction and operational efficency. ### This objectives of this project are: -To simulate the e-commerce order fulfillment process -To model warehouse activities including picking, packing, and shipping -To analyze warehouse efficiency using performance metrics -To identify operational bottlenecks -To demonstrate the application of simulation techniques in supply chain management

The simulated system represents a simplifilied e-commerce fulfillment center. Customer place orders through an online platform and the warehouse processes the order through several stages before dispatching products for delivery. The simulation assumes that orders arrive randomly and that processing times vary depending on warehouse activity. This model was inspired by the Amazon fulfillment center simulations.

The fulfillment process and parameters:

1.Customer order arrival: at random (exponential distribution) 2.Inventory vertificatio: 1-3 minutes 3.Item picking: 5-10 mins 4.Product packing: 3-6 minutes 5.Shipping and dispatch: 2-5 minutes Number of pickers: 2 Number of packers: 2 Warehouse operation hours: 8 hours

These assumptions simplify the real world fulfillment process while maintaining realistic warehouse behavior.

library(simmer)
library(simmer.plot)
## Warning: package 'simmer.plot' was built under R version 4.5.1
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 4.5.1
## 
## Attaching package: 'simmer.plot'
## The following objects are masked from 'package:simmer':
## 
##     get_mon_arrivals, get_mon_attributes, get_mon_resources
library(ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:simmer':
## 
##     select
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(DiagrammeR)
## Warning: package 'DiagrammeR' was built under R version 4.5.2

Used DiagrammeR package to display the process flow

grViz("
digraph warehouse_process {

  graph [layout = dot, rankdir = LR]

  node [shape = circle,
        style = filled,
        fontname = Helvetica,
        fontsize = 14]

  order     [label='🛒 Customer Order', fillcolor=beige]
  inventory [label='📦 Inventory Check', fillcolor=lightyellow]
  picking   [label='🤖 Item Picking', fillcolor=lightblue]
  packing   [label='📋 Packing', fillcolor=orange]
  shipping  [label='🚚 Shipping', fillcolor=pink]
  delivery  [label='🏠 Delivery', fillcolor=lightgrey]

  order -> inventory
  inventory -> picking
  picking -> packing
  packing -> shipping
  shipping -> delivery
}
")
#simulation environment created
warehouse_sim<-simmer("E-commerce Fulfillment")

#resources
warehouse_sim|>
  add_resource("inventory_checker", capacity = 1)|>
  add_resource("picker", capacity = 2)|>
  add_resource("packer", capacity=2)|>
  add_resource("shipping_station", capacity = 1)
## simmer environment: E-commerce Fulfillment | now: 0 | next: 
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Resource: picker | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
order_process<-trajectory("Order Fulfillmet")|>
  
  #Inventory check
  seize("inventory_checker")|>
  timeout(function() runif(1,1,3))|>
  release("inventory_checker")|>
  
  #picking
  seize("picker")|>
  timeout(function() runif(1,5,10))|>
  release("picker")|>
  
  #Packing
  seize("packer")|>
  timeout(function() runif(1,3,6))|>
  release("packer")|>
  
  #Shipping
  seize("shipping_station")|>
  timeout(function() runif(1,2,5))|>
  release("shipping_station")
#Generated customer orders
warehouse_sim|>
  add_generator("customer_order", order_process, function() rexp(1, rate=1/4), mon=2)
## simmer environment: E-commerce Fulfillment | now: 0 | next: 0
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Resource: picker | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Source: customer_order | monitored: 2 | n_generated: 0 }

Results

#run simulation
warehouse_sim|>
  run(until=480)
## simmer environment: E-commerce Fulfillment | now: 480 | next: 480.586127066782
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 1(1) | queue status: 1(Inf) }
## { Resource: picker | monitored: TRUE | server status: 2(2) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 2(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 1(1) | queue status: 2(Inf) }
## { Source: customer_order | monitored: 2 | n_generated: 112 }
#Results
arrivals<-get_mon_arrivals(warehouse_sim)
resource<- get_mon_resources(warehouse_sim)

avg_time<-mean(arrivals$end_time-arrivals$start_time)

cat("Average Fulfillment Time:",avg_time)
## Average Fulfillment Time: 31.63799

Visual

plot(resource)

ggplot(arrivals, aes (x=end_time-start_time))+
  geom_histogram(binwidth=2, fill="blue")+
  labs(title ="Order fulfillment Time Distributions", x="Fulfillment Time (Minutes)", y="Frequency")

The simulation results indicate that the picking operation is the primary bottleneck in the warehouse fulfillment process. The picker resource experienced the highest queue length and system utilization, suggesting that customer orders accumulated faster than they could be processed. In contrast, the packing and inventory checking stations maintained low queue levels and table utilization rates. These findings demonstrate the importance of resource allocation in warehouse management and suggest that increasing picker capacity could significantly improve fulfillment performance.

Second simulation for possible improvement.

For best results I tried to run the simulation with an increase of picker.

#simulation environment created
warehouse_sim2<-simmer("E-commerce Fulfillment 2")

#resources
warehouse_sim2|>
  add_resource("inventory_checker", capacity = 1)|>
  add_resource("picker", capacity = 4)|>
  add_resource("packer", capacity=2)|>
  add_resource("shipping_station", capacity = 1)
## simmer environment: E-commerce Fulfillment 2 | now: 0 | next: 
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Resource: picker | monitored: TRUE | server status: 0(4) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
order_process2<-trajectory("Order Fulfillmet2")|>
  
  #Inventory check
  seize("inventory_checker")|>
  timeout(function() runif(1,1,3))|>
  release("inventory_checker")|>
  
  #picking
  seize("picker")|>
  timeout(function() runif(1,5,10))|>
  release("picker")|>
  
  #Packing
  seize("packer")|>
  timeout(function() runif(1,3,6))|>
  release("packer")|>
  
  #Shipping
  seize("shipping_station")|>
  timeout(function() runif(1,2,5))|>
  release("shipping_station")
#Generated customer orders
warehouse_sim2|>
  add_generator("customer_order", order_process, function() rexp(1, rate=1/4), mon=2)
## simmer environment: E-commerce Fulfillment 2 | now: 0 | next: 0
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Resource: picker | monitored: TRUE | server status: 0(4) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 0(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Source: customer_order | monitored: 2 | n_generated: 0 }
#run simulation
warehouse_sim2|>
  run(until=480)
## simmer environment: E-commerce Fulfillment 2 | now: 480 | next: 482.76485702271
## { Monitor: in memory }
## { Resource: inventory_checker | monitored: TRUE | server status: 0(1) | queue status: 0(Inf) }
## { Resource: picker | monitored: TRUE | server status: 0(4) | queue status: 0(Inf) }
## { Resource: packer | monitored: TRUE | server status: 2(2) | queue status: 0(Inf) }
## { Resource: shipping_station | monitored: TRUE | server status: 1(1) | queue status: 2(Inf) }
## { Source: customer_order | monitored: 2 | n_generated: 100 }
#Results
arrivals2<-get_mon_arrivals(warehouse_sim2)
resource2<- get_mon_resources(warehouse_sim2)

avg_time2<-mean(arrivals2$end_time-arrivals2$start_time)

cat("Average Fulfillment Time:",avg_time2)
## Average Fulfillment Time: 23.23447

Visual

plot(resource2)

ggplot(arrivals2, aes (x=end_time-start_time))+
  geom_histogram(binwidth=2, fill="blue")+
  labs(title ="Order fulfillment Time Distributions", x="Fulfillment Time (Minutes)", y="Frequency")

The second simulation with the increased picker resource capacity from 2 to 4 workers, showed improvement.The second simulation showed a significant reduction in queue length and improve order flow throughout the warehouse system. Resource utilization become more balanced and the fulfillment delays were decreased. This demonstrates how simulation can be used to evaluate operational improvements and support warehouse optimizatio decisions.

Conclusion

This project developed a discrete-event simulation model of an e-commerce warehouse fulfillment system using R. The model sucessfully simulated customer orders moving throught inventory checking, picking, packing, and shipping stages. Ths simulation identified picking operations as the primary bottleneck affecting fulfillment time.

The optimized model achieved better operational efficiency by increasing picker capacity. The simulation demonstrated that resource allocation has a direct impact on warehouse throughput and customer fulfillment time. This project demonstrated how simulations can be used to analyze warehouse operations, improve efficiency, and support decision making supply chain and logistics management. The findings highlight the value of resource planning and porcess optimization in modern e-commerce fulfilment centers.

References:

-https://www.aboutamazon.com/news/innovation-at-amazon/amazon-fulfillment-center-simulations

-https://supplychain.amazon.com/blog/ecommerce-fulfillment-pick-pack-ship?utm_source=google&utm_medium=organic-search

-https://builtin.com/data-science/diagrammer

-https://r-simmer.org