← All work
Simulation2025 / 11

Fulfillment Risk Simulation

A discrete-event fulfillment model that turns queues, station pressure, SLA risk, and staffing choices into an operating decision.

PythonSimPyOptimizationPower BI
8 hrmodeled shift
0-100system risk score
4capacity stations
Gridstaffing search
01 / Context

The question
behind the work.

A fulfillment dashboard can show that an SLA failed, but it cannot tell leaders which staffing change would have prevented the failure. The decision requires a model of queues, capacity, variability, and system pressure.

My role

I built the discrete-event engine, observer process, station metrics, live alert logic, pressure and risk scores, staffing optimizer, structured exports, and four-page Power BI decision layer.

02 / Implementation

What I built.

The SimPy engine observes every station minute by minute, raises alerts, scores system risk, tests scenarios, and exports the full decision layer to Power BI.

  • Modeled an eight-hour shift with Poisson arrivals, exponential service times, and constrained Pick, Pack, Sort, and Outbound resources.
  • Sampled WIP, completions, breaches, queues, and active workers every minute while tracking event-based station utilization and queue behavior.
  • Triggered queue blowup, WIP runaway, and SLA drift alerts during the simulation rather than inventing them afterward.
  • Combined SLA rate, maximum WIP, and top station pressure into a 0-100 system-risk score.
  • Ran bounded grid search across thousands of staffing combinations and selected the lowest-headcount feasible plan below the risk threshold.
03 / In detail

Start with the operating system, not the dashboard

I built this as a discrete-event simulation first. The SimPy engine models Poisson order arrivals, station capacity, exponential service times, routing, queues, work in process, SLA behavior, and outbound flow over a full shift.

Every dashboard output is downstream of that engine. That means a leader can ask what staffing change would alter a failure mode instead of only seeing that an SLA was missed after the fact.

Make pressure visible while it forms

The model observes the facility minute by minute and records queue depth, utilization, work in process, throughput, waits, SLA breaches, and station conditions. I added real-time alerts, a station-pressure score from zero to one, and a system-risk score from zero to 100.

Those measures turn the simulation into an operating view: where is the constraint forming, how quickly is it spreading, and which part of the facility needs attention first?

Search for a staffing decision

I ran baseline, surge, and optimized scenarios through the same engine, then used bounded grid search to compare staffing combinations against risk and service outcomes. The selected plan is traceable to the full scenario and optimization result set rather than a hand-picked dashboard view.

The model exports minute-, station-, event-, scenario-, and optimization-level CSV tables for a four-page Power BI decision layer. Fixed seeds keep comparisons reproducible when a scenario is rerun.

04 / Engineering judgment

The decisions
that shaped it.

  1. Built the engine before the dashboard so every visual is downstream of reproducible simulation output.
  2. Combined utilization with maximum queue length because sustained load and shock congestion describe different failure modes.
  3. Optimized against a transparent risk function and explicit headcount constraint instead of producing an opaque recommendation.

Evaluation & results

Baseline, surge, and optimized scenarios run through the same engine and produce minute-, station-, event-, scenario-, and optimization-level CSV outputs. Fixed seeds make comparisons reproducible, and the selected plan is traceable to the complete grid-search result set.

05 / Working outputs

See it for yourself.

Select an image to view it at full size.

Next projectInsurance Fraud Detection