Disclosure: this article contains an affiliate link; I may earn a commission at no extra cost to you.
FDM printers accumulate small jobs the same way cars do: nozzles wear, belts loosen, grease dries, and PTFE or cutter parts get replaced on a schedule you will not remember if it only lives in your head. You do not need a CMMS. A dated log plus a short script that tells you what is overdue is enough for a home or shop bench.
I have not instrumented a particular brand for this write-up. The habit works on any machine you already own.
What belongs in the log
Keep one append-only record per printer. A CSV is easy to grep and easy to version in git. Suggested columns:
-
date— ISO date of the event -
printer— a short name, not a serial you will typo -
event—print_hours,nozzle_change,belt_check,lube,filter,other -
hours— hours added this session, or blank for a parts event -
note— nozzle size, belt tension, or a short reason
Print hours can be a conservative estimate from your slicer or a firmware print-stats readout if you trust it. The point is consistency, not laboratory precision.
Write a line when you finish a maintenance task, not “sometime this month.” A log that is three weeks late is just a diary of guilt.
A small script that flags overdue work
Save the CSV as maintenance.csv and run the script below from the same folder. Adjust the hour intervals to match your machine and filament mix. Abrasive carbon-fiber work usually shortens a nozzle interval; PLA on a brass nozzle can go longer. Official wear parts and filter-change guidance, if your manufacturer publishes them, should override these placeholders.
#!/usr/bin/env python3
"""Flag overdue 3D printer maintenance from a simple CSV log."""
import csv
from collections import defaultdict
from datetime import date, datetime
from pathlib import Path
LOG = Path("maintenance.csv")
# Hours between recurring jobs. Tune per printer and materials.
INTERVALS = {
"nozzle_change": 150,
"belt_check": 100,
"lube": 200,
"filter": 300,
}
def load_rows(path: Path):
with path.open(newline="", encoding="utf-8") as f:
return list(csv.DictReader(f))
def main():
rows = load_rows(LOG)
hours = defaultdict(float)
last_event = {} # (printer, event) -> (date, hours_then)
running = defaultdict(float)
for row in rows:
p = row["printer"].strip()
ev = row["event"].strip()
d = datetime.strptime(row["date"].strip(), "%Y-%m-%d").date()
extra = float(row["hours"] or 0)
running[p] += extra
hours[p] = running[p]
last_event[(p, ev)] = (d, running[p])
today = date.today()
for printer, total in sorted(hours.items()):
print(f"{printer}: {total:.1f} recorded hours")
for ev, every in INTERVALS.items():
key = (printer, ev)
if key not in last_event:
print(f" missing: no '{ev}' entry yet (every {every} h)")
continue
when, hours_then = last_event[key]
due_in = every - (total - hours_then)
age = (today - when).days
if due_in <= 0:
print(f" OVERDUE: {ev} ({-due_in:.1f} h over, last {when})")
else:
print(f" {ev}: ok for ~{due_in:.1f} h (last {when}, {age} days ago)")
if __name__ == "__main__":
main()
A starter log can be as small as:
date,printer,event,hours,note
2026-11-01,workshop-q,print_hours,12,PETG batch
2026-11-01,workshop-q,nozzle_change,,new 0.4 bimetal
2026-11-08,workshop-q,print_hours,8,nylon dry-box test
The script only knows what you typed. If you skip print_hours for a week, every interval looks healthier than it is. If you log estimated slicer times and your printer actually ran slower, you will get an earlier warning, which is the safer error. Optional extras, if you outgrow the CSV, are a second column for filament type or a yearly archive file so the main log stays short.
How to use it without making a second job out of it
- Add a
print_hoursline when you clear a job off the bed, or once a day if you batch. - After a nozzle swap, belt tension check, rail lubrication, or filter change, add the matching event with an empty
hoursfield. - Run the script before a long unattended print. If a nozzle change is overdue and you are about to start a fiber-filled part, stop and swap first.
- Keep official spare-part lists nearby so the log points at real intervals, not folklore.
If you are comparing enclosed machines while you set up a bench process, official current models are listed on QIDI’s store. I also collected notes on hardened nozzles and carbon-fiber filament here: Hardened nozzles and CF filament.
A maintenance log will not make a printer last forever. It will keep you from discovering a worn nozzle in the last hour of a 20-hour job, which is usually when you notice it without a record.
Top comments (0)