Vaccine Distribution Simulation Optimization

Vaccine simulation template to build a representative model of communities at scale and test various configurations, policies and structures and explore their impact on distribution, vaccine reserve utilization, and population immunity.

The simulation models distributor agents - pharmacies, hospitals, clinics - administering vaccines to patients. Every timestep represents one day. A stochastic number of patients arrive each day to the distributors to receive a vaccine, and as the simulation runs these same patients return for a second dose.

*In v2.0.0, the model was refactored to allow for inclusion of the Johnson & Johnson (jj) vaccine. Set the appropriate global parameters to run the simulation with single-dose JJ vaccines.


  • Distributors: The distributor agent is the primary agent in the simulation. It receives patients and vaccines and attempts to maximize the number of patients treated.
  • Shipper: The shipper agent sends vaccines to each distributor agent. It sends vaccines weekly, on different days to different agents.
  • Population:The population agent generates patients who visit distributors. It also records appointments for second dose visits.


Reserve Policies

"second_dose_separate_storage": <Boolean> If true, model uses second dose storage. This should be set to true if second_dose_divert_to_storage > 0 or second_dose_matching is true.

"second_dose_divert_to_storage": <Integer> Number of vials per vaccine to set aside in reserve for second dose appointments.

"second_dose_matching": <Boolean> If true set aside a dose for every vaccine administered to a first dose patient in reserve

"shuffle_turn_away": <Boolean> If true will ignore the array order in prioritize_group_options and randomize who is turned away.

Prioritize Group Policies

"prioritize_group": <String> Key for prioritize_group_options. Selected array will determine which groups are turned away first (the last group type in the array). So [num_of_first_dose, second_dose_moderna] will, if a distributor is over subscribed, turn away people coming for their second_dose_moderna.

"prioritize_group_options": <Array[String]> order of patients to turn away. Preset options that cover current groups in simulation.

General Parameters

"pfizer_expiry": <Integer> timesteps for pfizer shelflife. If pfizer vaccine age is greater than pfizer_expiry will spoil. "moderna_expiry": <Integer> timesteps for moderna shelflife. If moderna vaccine age is greater than _expiry will spoil. "jj_expiry": <Integer> timesteps for jj shelflife. If jj vaccine age is greater than _expiry will spoil.

"initial_vaccinations_moderna": <Integer> The starting amount of moderna vaccinations to be represented in the Vaccinations plot. "initial_vaccinations_pfizer": <Integer> The starting amount of Pfizer vaccinations to be represented in the Vaccinations plot.

"appt_delay": <Integer> timesteps after which patient will return for second dose. "staff": <Integer> Staff per clinic. "doses_handled_per_staff_day": <Integer> Doses a staffer can administer a day. "initial_supply": <Integer> Initial supply of vials a distributor has on hand. "initial_provider_pfizer_perc": <Float> percentage of providers that will provide the Pfizer vaccine. Primary vaccine providing is randomly assigned, where if the number is less than the initial_provider_pfizer_perc it serves Pfizer, otherwise Moderna

"moderna_vials_per_week": <Integer> number of moderna vials each distributor receives. "pfizer_vials_per_week": <Integer> number of pfizer vials each distributor receives "jj_vials_per_week": <Integer> number of jj vials each distributor receives

"min_first_dose_patients": <Integer> minimum number of first dose patients (haven't received a shot yet, this will be their first). "mean_first_dose_patients": <Integer> average number of first dose patients "max_first_dose_patients": <Integer> max number to arrive on a single timestep.

"req_vaccines_perc_refill": <Float> optional. If a distributor requests extra vaccines (which it will if reserve_min_perc is greater than 0 and it's reserves fall below the percentage * the number of doses it tends to receive in a week) then the shipping agent will send extra in the next round, equal to req_vaccines_perc_refill multiplied by _doses_per_week. "reserve_min_perc": <Float> optional. percentage of doses delivered per week that, if an agent's reserves fall below, cause it to request more vaccines from shipping agent.

"population": 250000,

"num_distributors": <Integer> Number of distributor agents "steps": <Integer> Number of steps to run the simulation.


We envision this simulation as a jumping off point for more detailed and tailored distribution models. There are numerous directions that users can take this; some potentially high value features:

Additional heterogeneity: Different distributor agents could receive different amounts of vaccines, could have different throughputs, could receive drastically different numbers of patients, etc. Feedback loops for vaccine requests: Vaccine allocators are likely responsive to increased demand and shortages from specific distributors – expand the shipping agent behaviors and logic to deliver more vaccines to distributors that are short on vaccines. Appointment logic: Customize the sim so that patients pre-schedule appointments and vaccine reserve rates depend on upcoming appointments. Second dose appointments could be pushed, not entirely cancelled.


Every timestep is equivalent to one real world day. There are no weekends.