Test Types & Methods

What Is HALT and HASS Testing

HALT finds design limits by stressing to destruction, HASS screens production units. How both work, when to use each, and how to record results.

JJulien Buteau
intermediate9 min readMarch 14, 2026

HALT and HASS are stress testing methods that sound similar and do opposite things. HALT destroys a handful of units on purpose to find where the design breaks. HASS screens production units with a stress profile chosen to be survivable. Confusing them is expensive in both directions.

The Difference in One Table

HALTHASS
Full nameHighly Accelerated Life TestHighly Accelerated Stress Screen
WhenDesign phaseProduction
SampleA few units (3-10)Every unit, or a large sample
GoalFind the design's destruct limitsPrecipitate latent defects
Stress levelIncreased until failure, beyond specFixed, below the destruct limit
Expected outcomeEvery unit eventually failsEvery unit survives
A failure meansUseful information about marginThis unit had a defect
OutputOperating and destruct limitsPass/fail per unit

The single most important relationship: HALT defines the stress levels that HASS is allowed to use. You cannot design a HASS profile without HALT data, because you would be guessing at how much stress the product survives.

HALT: Finding the Limits

HALT applies increasing stress until the product stops working, in steps, one stress type at a time and then combined.

StepStressWhat you learn
1Cold step stressLower operating and destruct limits
2Hot step stressUpper operating and destruct limits
3Rapid thermal transitionsSensitivity to thermal shock
4Vibration step stressMechanical resonances, solder joint weakness
5Combined thermal + vibrationInteraction failures neither finds alone

Two thresholds come out of each stress type:

  • Operating limit. The product stops working but recovers when the stress is removed.
  • Destruct limit. The product is permanently damaged.

The margin between the specification and the operating limit is the number that matters. A product specified to 60 °C with an operating limit of 65 °C has almost no margin; one with an operating limit of 110 °C has plenty.

HALT is not a pass/fail test and has no meaningful yield. Every unit is expected to fail eventually. Stopping HALT because a unit broke defeats the purpose.

Recording HALT

HALT results are limits, not verdicts. The useful record is the stress level at which each failure mode appeared.

phases/thermal_step.py
def thermal_step(measurements, chamber, dut):    """One step of a cold or hot step-stress sequence."""    measurements.chamber_temperature = chamber.read_temperature()    measurements.dut_functional = dut.self_test_passes()    measurements.supply_current = dut.supply_current_ma()
procedure.yaml
27 lines
name: HALT Thermal Stepversion: 1.0.0description: One step in a HALT step-stress sequence; failures are expectedunit:  serial_number:    default_value: "HALT-001"  part_number:    default_value: "PCBA-100"plugs:  - name: chamber    python: plugs.chamber:Chamber  - name: dut    python: plugs.dut:Dutmain:  - name: Thermal Step    python: phases.thermal_step    measurements:      - name: Chamber Temperature        unit: "°C"        description: Actual soak temperature, recorded not asserted      - name: DUT Functional        description: Whether the unit still operates at this step      - name: Supply Current        unit: mA

Note what is missing: validators. A HALT step has no limits, because the point is to record where behaviour changes, not to judge it. A measurement with no validator is recorded and reported without a pass/fail verdict, which is exactly right here.

The failure step is then visible in the unit's history: the temperature at which dut_functional went false is the operating limit, and whether it recovered on the way back tells you if that was also the destruct limit.

phases/record_halt_context.py
def record_halt_context(run):    run.metadata["stress_type"] = "cold_step"    run.metadata["step_number"] = 7    run.metadata["recovered_after_step"] = True

HASS: Screening Production

HASS uses a fixed profile derived from the HALT results, typically set well inside the operating limits, to precipitate latent defects without damaging good units.

ParameterTypical derivation
Temperature extremesInside the operating limits, outside the spec range
Ramp rateAggressive, often 30-60 °C/min
Vibration levelA fraction of the vibration operating limit
CyclesFew; enough to precipitate, not to consume life
Functional testDuring and after stress, not only after

The critical constraint is that HASS must not consume meaningful life from good units. That is verified with a Safety of Screen study: repeat the screen on the same units many times and confirm they still pass. If units start failing after twenty screens, the profile is too aggressive for a product expected to survive years in the field.

Recording HASS

HASS is a normal pass/fail production test, so it has limits like any other:

phases/hass_functional.py
def hass_functional(measurements, chamber, dut):    measurements.chamber_temperature = chamber.read_temperature()    measurements.output_voltage = dut.output_voltage()    measurements.self_test_passed = dut.self_test_passes()
procedure.yaml
39 lines
name: HASS Screenversion: 1.0.0unit:  serial_number:    default_value: "PCBA000001"  part_number:    default_value: "PCBA-100"plugs:  - name: chamber    python: plugs.chamber:Chamber  - name: dut    python: plugs.dut:Dutmain:  - name: HASS Functional    python: phases.hass_functional    measurements:      - name: Chamber Temperature        unit: "°C"        description: Verify the screen was actually applied        validators:          - operator: ">="            expected_value: -38.0          - operator: "<="            expected_value: 82.0      - name: Output Voltage        unit: V        description: Same limits as the ambient functional test        validators:          - operator: ">="            expected_value: 4.75          - operator: "<="            expected_value: 5.25      - name: Self Test Passed        validators:          - operator: "=="            expected_value: true

Run it with tofupilot run ./procedure.yaml --upload.

Two deliberate choices:

The chamber temperature is validated. A screen that was never actually applied, because the chamber did not reach setpoint, produces units that passed a test that did not happen. Verifying the stress was delivered is part of the test.

The functional limits match the ambient test. That makes drift across the screen visible as a comparison against the same unit's earlier run, rather than two unrelated numbers.

HALT and HASS in Context

MethodPhaseUnitsPurpose
HALTDesignA few, destroyedFind design margin
HASSProductionAll or a large sampleScreen out latent defects
ORTOngoing productionSmall continuous sampleDetect reliability drift over time
Burn-inProductionAll or a samplePrecipitate infant mortality by duration

HASS and burn-in overlap in intent. HASS is generally faster and more aggressive, using thermal cycling and vibration; burn-in is longer and gentler, usually powered soak at elevated temperature.

When HASS Is Not Worth It

HASS requires a chamber, a fixture that survives the profile, the HALT data to design it, and a Safety of Screen study. For low-volume or low-criticality products, that investment may exceed the cost of the field failures it prevents. The honest calculation is the expected cost of escapes against the cost of screening.

For high-reliability products, the calculation almost always favours screening, which is why it is standard in aerospace, medical and automotive.

If You Already Run OpenHTF

hass.py
21 lines
import openhtf as htffrom openhtf.util import unitsfrom tofupilot.openhtf import upload@htf.measures(    htf.Measurement("chamber_temperature_C")    .in_range(-38.0, 82.0)    .with_units(units.DEGREE_CELSIUS),    htf.Measurement("output_voltage_V")    .in_range(4.75, 5.25)    .with_units(units.VOLT),)def phase_hass(test):    test.measurements.chamber_temperature_C = 81.2    test.measurements.output_voltage_V = 5.02test = htf.Test(phase_hass, part_number="PCBA-100")test.add_output_callbacks(upload())test.execute(test_start=lambda: input("Scan serial: "))

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

Common Mistakes

MistakeConsequenceFix
Designing HASS without HALT dataEither damaging good units or screening nothingRun HALT first; derive the profile from its limits
Stopping HALT at the first failureNo destruct limit, no margin figureContinue to destruct on every stress type
Putting pass/fail limits on HALT stepsThe data becomes a verdict instead of a limitRecord HALT measurements without validators
No Safety of Screen studyHASS consumes field life from good unitsRepeat the screen and confirm survival
Not verifying the chamber reached setpointUnits pass a screen that never happenedValidate the chamber temperature
Different functional limits than the ambient testDrift across the screen is invisibleReuse the ambient measurement names and limits

More Guides

Put this guide into practice