PulsCar study: 12-volt battery and charging-system failures in NHTSA complaints and recalls Article: https://www.pulscar.io/blog/car-battery-alternator-failure-study License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/) - credit "PulsCar analysis of NHTSA complaint and recall data" with a link to the article. SOURCE FILES (downloaded 23 September 2026 from https://static.nhtsa.gov/odi/ffdd/; NHTSA rebuilds them daily) COMPLAINTS_RECEIVED_2015-2019.zip 81302701 bytes e5e989aed1bae5630d86d17b6738d5a5d9a0619b975bafcab1b8ea012c7b01aa COMPLAINTS_RECEIVED_2020-2024.zip 75873830 bytes adf52d6ca894b167562c95c0e7bb209c046ca32d73abe5fc09c8aef56ce3b3ef COMPLAINTS_RECEIVED_2025-2026.zip 40055238 bytes 0e850380d968c921b61bb61c8bf138c6a6527cd5f96db29cc5227774c392f81a FLAT_RCL_POST_2010.zip 14775354 bytes 686ca9de2f484e8db1aff27e0ba9f5a75c794da5d3b54de1ca3c7b610cd07daa Complaints: 1,105,443 rows; one complaint = one ODINO, PROD_TYPE = V; 780,071 distinct vehicle complaints, received (LDATE) 20150101 to 20260921. Recalls: vehicle campaigns (RCLTYPECD = V) in FLAT_RCL_POST_2010. SCRIPTS (published next to this file) analysis.py - every complaint and recall number in the article. Python 3 standard library only. python3 analysis.py fetch573.py - finds and downloads the Part 573 reports for every campaign below and extracts their text. python3 fetch573.py part573.py - reads the manufacturers' Part 573 Safety Recall Reports (text from `pdftotext -layout`) and writes part573_reports.csv. Report PDFs were located through https://api.nhtsa.gov/safetyIssues/byNhtsaId?filter=recalls&nhtsaId= and downloaded from https://static.nhtsa.gov/odi/rcl//RCLRPT--.PDF. Where a campaign has several reports (amendments), the latest Submission Date is used. python3 part573.py /p573_index.json It also classifies the report's "Identification of Any Warning that can Occur" field (rules in the script): not reported / no warning / dashboard warning / other signs only. Text reports found: 193 of 271 campaigns (older ones are scanned letters or absent). The exact regular expressions are in analysis.py; they are summarized here. COMPLAINT RULES (Python re, case-insensitive; the file is in capitals before 2021 and mixed case after) Step 1 MENTION: battery|batteries, alternator(s), "charging system", "voltage regulator" (whole words). -> 37,912 Step 2 EXCLUDE: high-voltage / EV traction / key-fob context (hybrid batter*, high voltage, HV battery, traction battery, lithium, li-ion, charging station, supercharg*, charge port, state of charge, range, kWh, electric vehicle, EV, PHEV, BEV, plug-in, battery pack, drive battery, propulsion, fob, remote/key battery) UNLESS the text also says 12V / 12 volt / auxiliary battery / low-voltage battery; motorcycle wording. -> 33,196 Step 3 FAILURE DESCRIBED (any of): dead|weak|drained|discharged|failed|failing|bad [12V] battery; battery [was|is|went| keeps|kept|would|has] [completely|totally] dead|died|dies|dying|drained|drains|discharged|failed|fails|weak; alternator failed|went out|went bad|died|quit|stopped working/charging|was bad/faulty/not charging|replaced; new|replaced|bad|faulty|defective|failed alternator; not|wasn't|stopped|no longer charging; charging system failure|fault|warning|light|message|problem; service|check [battery] charging system; battery light|lamp| indicator; charging light; low [battery] voltage; voltage dropped|low; jump start, jumped the car/battery. A match is ignored when the 45 characters before it (same sentence) contain afraid/worr*/concern*/fear*/might/ may/in case/risk*, or when never/not/no stands at most two words before it. -> FAILURE SET 10,776 Step 4 SETTING, checked in this order: ON THE ROAD if ONE sentence contains both a driving context (while/when/as [I was|the contact was|...] driving, in motion, on the highway/freeway/interstate/road, traveling, going N, merging, accelerating, turning, stopped at, at a light/stop sign; at|going|approximately N mph; on the highway; in traffic; in the middle of the road/intersection) AND a failure verb (died, dies, stalled, shut off/down, turned off, cut off/out, lost power, lost electrical, loss of power, went dead, quit/stopped running, engine stopped/quit). -> 1,849 (17.2%) NO START OR DEAD WHEN PARKED otherwise, if: would not / did not / won't / failed to / could not / unable to start, crank or turn over; no-start; no crank; dead battery; battery was dead; jump start. -> 4,040 (37.5%) OTHER OR UNCLEAR: everything else. -> 4,887 (45.4%) ALTERNATOR NAMED: the word alternator anywhere in the text. WARNINGS (on-the-road group only): battery/charging warning = battery [warning|saver] light|lamp|indicator|message| warning; charging [system] light|message|warning; service/check [battery] charging system; alternator light; low voltage warning; battery saver. Explicit no warning = no/never/zero [dash|check engine|warning|battery] lights|codes|messages|warnings; without [any] warning; warning light did not come on. Time given = a number or word (a few, two, ten...) + minutes|miles|seconds|blocks + later|after|down the road, in a complaint that also names a battery/charging warning. WHAT ELSE: steering = power steering, steering went/was/locked/heavy/hard, could not steer; brakes = brake|brakes; lights = lights went out/off, dash went dark/blank, everything went dark, lost all electrical, no headlights, hazards did not work; many lights = christmas tree, all the warning lights came on, multiple warning lights; transmission = transmission, shift*, stuck in gear/park, limp mode. VOLTAGES QUOTED: a number d.d or d.dd followed by V / volt(s) / VDC, kept if 5.0-16.5. POWERTRAIN from MODELTXT/MAKETXT only (FUEL_TYPE is mostly blank): electric = EV names list in analysis.py or make TESLA/RIVIAN/LUCID/POLESTAR/FISKER/VINFAST; hybrid = HYBRID|PHEV|PLUG-IN|PRIUS|HEV|4XE. MONTHS: FAILDATE (date of incident) years 2014-2026; rate = failure-set complaints per 100 complaints of any kind with an incident in the same calendar month. Cold states: MN WI MI ND SD ME VT NH NY PA OH IL IA MA MT WY ID NE CT RI IN AK CO UT. Hot states: FL TX AZ NV LA MS AL GA SC HI NM OK AR CA. State = owner's STATE field. TOWED / CRASH / FIRE: the form's Y/N fields. SPEED: VEH_SPEED 1-149. AGE: year received minus model year (0-40). MILES: 101-399,999. RECALL RULES Campaigns with at least one record whose COMPNAME starts with ELECTRICAL SYSTEM:12V/24V/48V BATTERY (includes :CABLES), ELECTRICAL SYSTEM:ALTERNATOR/GENERATOR/REGULATOR or ELECTRICAL SYSTEM:STARTER ASSEMBLY; RCLTYPECD = V. -> 271 campaigns. Population = POTAFF per campaign, summed once per campaign (a vehicle in two campaigns counts twice). Consequence class from the consequence summary (field 21): fire = "fire"; stall = stall | loss of motive/drive/propulsion power | lose(s)/losing power | shut down/off | power loss | loss of electrical | engine/vehicle stop|shut; no start = not start | no-start | fail to start | unable to start | inability to start | cannot be started | prevent ... from starting. Classes: fire only, fire and stall, stall only, no start only, other. MODEL YEARS for any recalled vehicle named in the article come only from the Part 573 report ("Vehicle N :" lines), never from api.nhtsa.gov/recalls/recallsByVehicle, which attributes a campaign's full year span to every model in it. HAND AUDITS (samples drawn by analysis.py with random.seed(20260923), written to audit_samples.txt, read in full) Failure set, 40 read: 32 describe a 12-volt battery or charging problem happening; 7 use the words around another fault (battery light during an engine failure, a jump start that did not help, "acting like" the battery died); 1 could not be judged from its text. On the road, 40 read: 37 describe the car dying/stalling/shutting off/losing power while in use; 3 do not (infotainment screen off, stereo off, a hypothetical "could have shut down"); in a few of the 37 the owner's account points to a non-12V cause (engine failure, throttle body). Not on the road, 40 read: 5 do describe the car dying or losing power while being driven, in words the rule does not catch ("lost total battery power", "suddenly stopped") or with driving and stall in different sentences. Scaled up, misses outnumber false matches: the on-the-road count is a floor. Rule change made after a first reading: added "lost motive power" / "loses motive power" (NHTSA call-center wording) and excluded "lost power steering" from the failure verbs; the final samples above were drawn after that change. Owner-quoted voltages: contexts read for samples of each band (below 11.8 V mostly batteries measured after a no-start, several at 4-7 V; 13.2-15.0 V mostly a normal charging reading while the battery kept dying; 12.4-12.99 V mostly a battery tested at rest). LIMITS Complaints are self-reported and unverified; NHTSA uses them as a signal, not as findings. Nothing here is a failure rate or a ranking. Counts follow sales, fleet age, recalls and owners' willingness to file. The federal file is a poor sample of routine cold-morning no-starts, which owners rarely report as safety complaints. The failure set can include complaints in which the battery is a symptom of another fault (for example a battery light during an engine failure). No data from PulsCar's app or users is used anywhere.