Test Types & Methods

What Is Ongoing Reliability Testing (ORT)

Ongoing reliability testing pulls units from the line and stress-tests them on a schedule. How ORT works and how to track results over time.

JJulien Buteau
intermediate7 min readMarch 14, 2026

Ongoing reliability testing (ORT) pulls a sample of units from production and stress-tests them continuously, to catch reliability problems that end-of-line functional test cannot see. FQC tells you a unit works today. ORT tells you whether this month's units still work after 500 hours at 55 °C.

ORT vs the Other Reliability Tests

TestWhenSamplePurpose
HALTDesign phaseA few unitsFind design margins by stressing to destruction
HASSProduction rampEvery unit or a large sampleScreen out infant mortality with a proven stress profile
ORTOngoing productionSmall sample, continuouslyDetect reliability drift in the running process
Burn-inProductionEvery unit or a samplePrecipitate early-life failures before shipment

The distinguishing feature of ORT is that it never ends. It runs for the life of the product, on units drawn from normal production, and it exists to answer one question: has anything about the product or the process changed in a way that will show up in the field in six months?

What ORT Catches That FQC Does Not

  • Supplier substitutions. A capacitor vendor change passes functional test and fails at temperature 300 hours in.
  • Process drift. Reflow profile drifts, solder joints get marginal, thermal cycling finds them.
  • Wear-out mechanisms. Connector insertion cycles, relay contacts, fan bearings, battery cycling.
  • Firmware regressions under duration. Memory leaks and counter rollovers that no 90-second EOL test will ever reach.

Designing an ORT Program

DecisionTypical choiceNotes
Sample size2-10 units per weekEnough to detect a shift, small enough to afford
Sampling methodRandom across shifts and linesSystematic sampling hides line-specific problems
Duration500-1000 hours, continuousLong enough to reach the wear-out region
Stress profileElevated temperature, thermal cycling, duty cyclingRepresentative of field use, accelerated
Measurement intervalEvery 24 hours, plus at entry and exitFrequent enough to see drift, not so frequent it dominates
Exit criteriaZero failures, or a defined failure rateDefined before the program starts, not after a failure

Implementing ORT as a Procedure

ORT has a shape that suits a declarative procedure: the same measurements, repeated on a schedule, on a unit that already exists in the system.

procedure.yaml
48 lines
name: ORT Checkpointversion: 1.0.0description: 24-hour ORT checkpoint measurement, per REL-220unit:  serial_number:    default_value: "PCBA000001"  part_number:    default_value: "PCBA-100"plugs:  - name: chamber    python: plugs.chamber:Chamber  - name: dmm    python: plugs.dmm:Multimetermain:  - name: Chamber Conditions    python: phases.chamber_conditions    measurements:      - name: Chamber Temperature        unit: "°C"        description: Soak temperature at time of measurement        validators:          - operator: ">="            expected_value: 54.0          - operator: "<="            expected_value: 56.0  - name: Functional Checkpoint    python: phases.functional_checkpoint    measurements:      - name: Output Voltage        unit: V        description: Same limits as EOL functional test        validators:          - operator: ">="            expected_value: 4.75          - operator: "<="            expected_value: 5.25      - name: Quiescent Current        unit: mA        validators:          - operator: "<="            expected_value: 45.0      - name: Still Booting        validators:          - operator: "=="            expected_value: true
phases/chamber_conditions.py
def chamber_conditions(measurements, chamber):    """Record the actual soak conditions, not the setpoint."""    measurements.chamber_temperature = chamber.read_temperature()
phases/functional_checkpoint.py
def functional_checkpoint(measurements, dmm):    """Re-run the EOL measurements on a unit that has been soaking."""    measurements.output_voltage = dmm.measure_dc_voltage()    measurements.quiescent_current = dmm.measure_dc_current_ma()    measurements.still_booting = True
plugs/chamber.py
class Chamber:    def read_temperature(self) -> float:        return 55.1  # Replace with a real chamber query
plugs/dmm.py
class Multimeter:    def measure_dc_voltage(self) -> float:        return 5.02  # Replace with a real instrument read    def measure_dc_current_ma(self) -> float:        return 41.3  # Replace with a real instrument read

Two deliberate choices in that procedure:

The functional limits are identical to the end-of-line test. ORT is only meaningful as a comparison against the unit's own EOL result. Same measurement names, same limits, so the drift is visible as a trend on one chart rather than two unrelated numbers.

The chamber conditions are measured, not assumed. A checkpoint taken while the chamber was recovering from a door opening is not comparable to one taken at soak. Recording the actual temperature lets you discard or annotate those points instead of chasing a phantom drift.

Recording the Elapsed Hours

The independent variable in ORT is time under stress, so it has to be on the run.

phases/record_elapsed.py
def record_elapsed(run):    """Hours since this unit entered the ORT chamber."""    run.metadata["ort_hours"] = 168    run.metadata["ort_lot"] = "2026-W38"

With ort_hours on every run and the same serial number across checkpoints, the unit's history is the reliability curve: open the serial and the measurements are in order from hour 0 to hour 1000.

Running It on a Schedule

An ORT checkpoint has no operator. Resolve the identify prompt from the procedure and pre-bake any UI values so a cron job or scheduler can drive it:

ort/checkpoint.sh
tofupilot run ./procedure.yaml --upload --json --ui-values ui.json --ui-timeout 300

Reading the Results

SignalWhat it meansAction
A single unit fails at hour 700Possibly normal wear-out, possibly a real defectFailure analysis on that unit; check whether its lot is over-represented
Every unit from one week driftsProcess or supplier change in that windowPull the build records for that lot
Quiescent current climbs across all unitsA wear-out mechanism reaching the populationCompare against the design margin; this is a product problem
Chamber temperature out of bandThe stress was not appliedDiscard the checkpoint, fix the chamber
No failures for a yearEither genuinely robust, or the stress is too gentleRevisit the profile; ORT that never fails may not be testing anything

That last row is the one most programs get wrong. An ORT program with zero findings over a long period is not automatically good news; it may mean the stress profile is below the level that provokes any real mechanism.

If You Already Run OpenHTF

Existing OpenHTF suites run natively on the TofuPilot CLI. The same checkpoint with decorators:

ort_checkpoint.py
22 lines
import openhtf as htffrom openhtf.util import unitsfrom tofupilot.openhtf import upload@htf.measures(    htf.Measurement("output_voltage_V")    .in_range(4.75, 5.25)    .with_units(units.VOLT),    htf.Measurement("quiescent_current_mA")    .in_range(maximum=45.0)    .with_units(units.MILLIAMPERE),)def phase_checkpoint(test):    test.measurements.output_voltage_V = 5.02    test.measurements.quiescent_current_mA = 41.3    test.metadata["ort_hours"] = 168test = htf.Test(phase_checkpoint, part_number="PCBA-100")test.add_output_callbacks(upload())test.execute(test_start=lambda: input("Scan ORT unit serial: "))

Install with pip install "tofupilot[openhtf]", or skip the callback and run it with tofupilot run.

Common Mistakes

MistakeConsequenceFix
Different limits than the EOL testDrift is invisible because the numbers are not comparableReuse the EOL measurement names and limits
Sampling only from one line or shiftLine-specific problems never enter the sampleRandomise across lines and shifts
Not recording elapsed hoursNo reliability curve, just scattered pass/failPut ort_hours on every run
Assuming the chamber setpointCheckpoints taken during recovery pollute the trendMeasure the actual conditions
Stopping ORT when yield looks goodThe program exists precisely to catch what yield cannotKeep it running for the product life
Discarding failed ORT units without analysisThe most informative unit you have gets thrown awayFailure analysis on every ORT failure

More Guides

Put this guide into practice