{"record":{"id":"9c7f53ba33ea3341","repo":"apache/beam","slug":"per-element-sleep-time-must-be-at-least-1e-3-after-being","errorCode":null,"errorMessage":"Per element sleep time must be at least 1e-3 after being divided among output elements.","messagePattern":"Per element sleep time must be at least 1e-3 after being divided among output elements\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"sdks/python/apache_beam/testing/synthetic_pipeline.py","lineNumber":280,"sourceCode":"    disable_liquid_sharding=False,\n    size_estimate_override=None,\n):\n  \"\"\"A function which returns a SyntheticSDFStep with given parameters. \"\"\"\n  class SyntheticSDFStep(beam.DoFn):\n    \"\"\"A SplittableDoFn of which behavior can be controlled through prespecified\n       parameters.\n    \"\"\"\n    def __init__(\n        self,\n        per_element_delay_sec_arg,\n        per_bundle_delay_sec_arg,\n        output_filter_ratio_arg,\n        output_records_per_input_record_arg):\n      if per_element_delay_sec_arg:\n        per_element_delay_sec_arg = (\n            per_element_delay_sec_arg // output_records_per_input_record_arg)\n        if per_element_delay_sec_arg < 1e-3:\n          raise ValueError(\n              'Per element sleep time must be at least 1e-3 after being '\n              'divided among output elements.')\n      self._per_element_delay_sec = per_element_delay_sec_arg\n      self._per_bundle_delay_sec = per_bundle_delay_sec_arg\n      self._output_filter_ratio = output_filter_ratio_arg\n\n    def start_bundle(self):\n      self._start_time = time.time()\n\n    def finish_bundle(self):\n      # The target is for the enclosing stage to take as close to as possible\n      # the given number of seconds, so we only sleep enough to make up for\n      # overheads not incurred elsewhere.\n      to_sleep = self._per_bundle_delay_sec - (time.time() - self._start_time)\n\n      # Ignoring sub-millisecond sleep times.\n      if to_sleep >= 1e-3:\n        time.sleep(to_sleep)","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/python/apache_beam/testing/synthetic_pipeline.py#L262-L298","documentation":"When a synthetic step fans out records (output_records_per_input_record > 1), the per-element delay is divided among output elements; __init__ raises ValueError if the divided delay falls below 1e-3 seconds, since the step cannot sleep that little. This is the fan-out-aware variant of the minimum-delay constraint.","triggerScenarios":"Constructing the step with per_element_delay_sec // output_records_per_input_record < 1e-3, e.g. delay 0.002 with 5 output records per input (0.002//5 = 0 < 1e-3).","commonSituations":"Large fan-out factors combined with small delays in load-test specs; tuning delay/fan-out independently without checking their interaction.","solutions":["Increase per_element_delay_sec so that delay // output_records_per_input_record >= 0.001","Lower output_records_per_input_record","Move the remaining delay to per_bundle_delay_sec instead"],"exampleFix":"// before\nSyntheticStep(per_element_delay_sec=0.002, output_records_per_input_record=5)\n// after\nSyntheticStep(per_element_delay_sec=0.005, output_records_per_input_record=5)","handlingStrategy":"validation","validationCode":"if per_element_delay_sec and \\\n        per_element_delay_sec // output_records_per_input_record < 1e-3:\n    raise ValueError('increase delay or reduce output_records_per_input_record')","typeGuard":"def delay_survives_fanout(delay, fanout):\n    return not delay or delay // fanout >= 1e-3","tryCatchPattern":"try:\n    step = SyntheticStep(per_element_delay_sec=d, output_records_per_input_record=n)\nexcept ValueError:\n    d = max(d, 1e-3 * n)\n    step = SyntheticStep(per_element_delay_sec=d, output_records_per_input_record=n)","preventionTips":["Check the delay/fanout interaction whenever tuning either parameter","Derive delay from fanout programmatically instead of hardcoding","Validate specs at parse time"],"tags":["value-out-of-range","synthetic-pipeline","fanout"],"backgroundTag":"value-out-of-range","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}