Skip to content
FlowScript templates

Operations — time study with confidence intervals

A direct time study that reports how precise it is, which is the part normally missing. Typed FlowScript for supply chains. Keywords: supply chain, logistics, network, supplier.

Template previewFlowScript
Walk-to-bin element — 30 timed cyclesFigure: Walk-to-bin element — 30 timed cycles. Violin plot. Horizontal axis: Value (min), linear scale, from 0.15 to 0.65. 2 series. Picker A (0.41 min, interval 0.35 to 0.455, n = 15); Picker B (0.44 min, interval 0.4 to 0.475, n = 15). Observations: n = 30 observations. Uncertainty: the interquartile range. Not stated in the figure data: axes, effect. Picker A: n = 15, median 0.4 (IQR 0.3 to 0.5), mean 0.4 (SD 0.1), range 0.3 to 0.5, density bandwidth 0.0342 by the silverman rule. Picker B: n = 15, median 0.4 (IQR 0.4 to 0.5), mean 0.4 (SD 0.1), range 0.3 to 0.5, density bandwidth 0.0281 by the silverman rule. Picker A: Bandwidth h = 0.03425 by the silverman rule. Both rules of thumb are derived for normal data and OVER-SMOOTH a multimodal density: if the violin's shape is the claim, show it at two bandwidths or say which one you chose. Picker A: Quartiles by Hyndman–Fan type 7; the fences use the same definition, so the box and the outlier rule cannot disagree. Picker B: Bandwidth h = 0.02809 by the silverman rule. Both rules of thumb are derived for normal data and OVER-SMOOTH a multimodal density: if the violin's shape is the claim, show it at two bandwidths or say which one you chose. Picker B: Quartiles by Hyndman–Fan type 7; the fences use the same definition, so the box and the outlier rule cannot disagree.Walk-to-bin element — 30 timed cyclesPicker A: kernel density, h = 0.0342 (silverman rule)Picker A: median 0.4, hinges 0.3 and 0.5, whiskers to 0.3 and 0.5 (1.5×IQR), mean 0.4mean 0.403Picker A: all 15 observation(s), jittered vertically by a seeded hash of each value0.4 min0.5 min0.3 min0.4 min0.3 min0.5 min0.4 min0.4 min0.5 min0.4 min0.3 min0.5 min0.4 min0.3 min0.5 minPicker An = 15, median 0.4 [0.3–0.5]Picker B: kernel density, h = 0.0281 (silverman rule)Picker B: median 0.4, hinges 0.4 and 0.5, whiskers to 0.3 and 0.5 (1.5×IQR), mean 0.4mean 0.437Picker B: all 15 observation(s), jittered vertically by a seeded hash of each value0.5 min0.4 min0.5 min0.4 min0.4 min0.5 min0.4 min0.5 min0.4 min0.5 min0.4 min0.5 min0.3 min0.4 min0.5 minPicker Bn = 15, median 0.4 [0.4–0.5]0.10.30.30.50.60.7Value (min)Raincloud (Allen et al. 2019): half violin = Gaussian kernel density; box = median, hinges and Tukey 1.5×IQR whiskers with the mean as a diamond; points= every individual observation. The points are the data; the cloud and the box are summaries of them.Bandwidth by the silverman rule of thumb: Picker A h = 0.0342; Picker B h = 0.0281. A density's silhouette depends on its bandwidth as much as on itsdata, and both rules of thumb are derived for normal data — they OVER-smooth a genuinely multimodal density. If the shape is the claim, show it at twobandwidths.Vertical offsets in the rain are a deterministic hash of each observation's own value, its position in the list, and a seed taken from the block and group ids— never a random number. The same document therefore draws the same cloud on every machine and every run, and the offset carries no information.1 palette colour(s) darkened or lightened to clear 3:1 against the panel.

Make it your own.

// A direct time study that reports how precise it is, which is the part
// normally missing.
//
// Five elements of a pick-and-pack operation in an ambient distribution
// centre, timed at the bin face. Observed time becomes basic time through
// the rating, and basic time becomes standard time through the allowances;
// both conversions are derivations, so changing the rating moves every
// standard time at once instead of inviting a partial re-typing.
//
// The confidence interval on each element answers the question a standard
// time is normally quoted without: how many cycles would we need to have
// timed for this number to be worth defending? At 30 cycles the walk
// element is precise to about 5.4%, so the study is six cycles short of
// the plus-or-minus 5% the method sheet asks for.

work_study pick_pack {
  title: "Pick and pack, ambient zone — element time study"
  operation: "Order picking to tote and pack-out, 3.4 lines per order average"
  site: "Regional distribution centre, ambient zone B"
  method: "Direct time study, continuous timing, BS 3138 element definitions"
  observer: "Industrial engineering, 2026-02-24 to 2026-02-26"
  rating_scale: "British Standard, 100 = standard rating"
  rating: 105
  rating_factor: = rating / 100
  relaxation_allowance: 11%
  contingency_allowance: 3%
  total_allowance: = relaxation_allowance + contingency_allowance
  allowance_factor: = 1 + total_allowance / 100[%]
  lines_per_order: 3.4
  shift_length: 7.5
  precision_target: 5%
}

work_element walk_to_bin {
  of: pick_pack
  description: "Walk from the previous bin face to the next pick face"
  observations: 30
  frequency: 3.4
  observed_mean: 0.420 min
  observed_sd: 0.061 min
  t_critical: 2.045 source "Student t, two-sided 95%, 29 df"
  basic_time: = observed_mean * pick_pack.rating_factor
  standard_time: = basic_time * pick_pack.allowance_factor
  time_per_order: = standard_time * frequency
  standard_error: = observed_sd / sqrt(observations)
  ci_half_width: = t_critical * standard_error
  precision: = pct(ci_half_width, observed_mean)
  observations_needed: = ceil((t_critical * observed_sd / (0.05 * observed_mean)) ^ 2)
}

work_element locate_and_scan {
  of: pick_pack
  description: "Read the pick label, scan the location barcode"
  observations: 30
  frequency: 3.4
  observed_mean: 0.280 min
  observed_sd: 0.042 min
  t_critical: 2.045 source "Student t, two-sided 95%, 29 df"
  basic_time: = observed_mean * pick_pack.rating_factor
  standard_time: = basic_time * pick_pack.allowance_factor
  time_per_order: = standard_time * frequency
  standard_error: = observed_sd / sqrt(observations)
  ci_half_width: = t_critical * standard_error
  precision: = pct(ci_half_width, observed_mean)
  observations_needed: = ceil((t_critical * observed_sd / (0.05 * observed_mean)) ^ 2)
}

work_element pick_and_place {
  of: pick_pack
  description: "Grasp the item, confirm quantity, place in the tote"
  observations: 30
  frequency: 3.4
  observed_mean: 0.190 min
  observed_sd: 0.031 min
  t_critical: 2.045 source "Student t, two-sided 95%, 29 df"
  basic_time: = observed_mean * pick_pack.rating_factor
  standard_time: = basic_time * pick_pack.allowance_factor
  time_per_order: = standard_time * frequency
  standard_error: = observed_sd / sqrt(observations)
  ci_half_width: = t_critical * standard_error
  precision: = pct(ci_half_width, observed_mean)
  observations_needed: = ceil((t_critical * observed_sd / (0.05 * observed_mean)) ^ 2)
}

work_element pack_and_label {
  of: pick_pack
  description: "Transfer the tote to carton, void fill, seal and label — once per order"
  observations: 20
  frequency: 1
  observed_mean: 0.860 min
  observed_sd: 0.145 min
  t_critical: 2.093 source "Student t, two-sided 95%, 19 df"
  basic_time: = observed_mean * pick_pack.rating_factor
  standard_time: = basic_time * pick_pack.allowance_factor
  time_per_order: = standard_time * frequency
  standard_error: = observed_sd / sqrt(observations)
  ci_half_width: = t_critical * standard_error
  precision: = pct(ci_half_width, observed_mean)
  observations_needed: = ceil((t_critical * observed_sd / (0.05 * observed_mean)) ^ 2)
}

work_element dispatch_scan {
  of: pick_pack
  description: "Scan to the dispatch lane and release the order — once per order"
  observations: 20
  frequency: 1
  observed_mean: 0.240 min
  observed_sd: 0.038 min
  t_critical: 2.093 source "Student t, two-sided 95%, 19 df"
  basic_time: = observed_mean * pick_pack.rating_factor
  standard_time: = basic_time * pick_pack.allowance_factor
  time_per_order: = standard_time * frequency
  standard_error: = observed_sd / sqrt(observations)
  ci_half_width: = t_critical * standard_error
  precision: = pct(ci_half_width, observed_mean)
  observations_needed: = ceil((t_critical * observed_sd / (0.05 * observed_mean)) ^ 2)
}

standard_output pick_pack_output {
  of: pick_pack
  // Named one by one rather than rolled up with sum(kind:work_element,
  // …). The aggregate reads better and is what a study of forty elements
  // would need, but time_per_order is itself DERIVED — basic time, times
  // the allowance factor, times frequency — and the roll-up is taken
  // before those derivations resolve, so it returns zero and the whole
  // chain below it divides by nothing. Five elements is few enough to
  // name, and naming them is also the audit trail a time study is for.
  standard_minutes_per_order: = walk_to_bin.time_per_order + locate_and_scan.time_per_order + pick_and_place.time_per_order + pack_and_label.time_per_order + dispatch_scan.time_per_order
  orders_per_hour: = 60[min] / standard_minutes_per_order
  orders_per_shift: = orders_per_hour * pick_pack.shift_length
  current_actual_per_shift: 78
  performance_index: = pct(current_actual_per_shift, orders_per_shift)
  labour_minutes_per_line: = standard_minutes_per_order / pick_pack.lines_per_order
}

// The walk element is the one with the spread, so it is the one drawn.
// Thirty timed cycles, split by picker, with every reading shown.
distribution walk_observations {
  title: "Walk-to-bin element — 30 timed cycles"
  kind: raincloud
  unit: "min"
  whisker: tukey
  jitter: true
  n: 30

  group picker_a {
    label: "Picker A"
    values: [0.38, 0.45, 0.34, 0.44, 0.29, 0.47, 0.41, 0.36, 0.49, 0.40, 0.33, 0.49, 0.42, 0.31, 0.46]
    n: 15
    mean: 0.4027
  }

  group picker_b {
    label: "Picker B"
    values: [0.45, 0.39, 0.50, 0.42, 0.36, 0.50, 0.43, 0.47, 0.37, 0.48, 0.41, 0.47, 0.35, 0.44, 0.52]
    n: 15
    mean: 0.4373
  }
}

note allowance_basis {
  text: "The 11% relaxation allowance is the site agreement figure for ambient picking with no lifting above shoulder height. It is a negotiated number, not a measured one, and it is worth more than every element time in this study put together: a one point change in it moves the standard time by about 0.05 minutes per order."
  anchor: pick_pack
}

view times: raincloud(walk_observations)

caption times_caption {
  of: times
  title: "Walk element, by picker"
  text: "Every timed cycle of the walk-to-bin element, split by picker. The spread, not the mean, is what decides how many cycles the study needs."
  statistics: "Box shows median and hinges with Tukey whiskers; all 30 observations are drawn."
  n_statement: "n = 30 cycles, 15 per picker, both rated at 105."
  style: journal
}