DEV Community

Ujjwal Dubey
Ujjwal Dubey

Posted on

Find Where Work Waits: Computing Dwell Time Between Workflow Steps From a Plain CSV Export

Before buying any AI tool, it helps to know where work actually waits. Most CRMs, helpdesks and form tools can export a CSV with a record ID, a status and a timestamp. That is enough to audit a business workflow for waiting time without new software.

The input

record_id,status,changed_at
101,new,2026-10-01T09:02
101,contacted,2026-10-01T15:40
101,quoted,2026-10-03T11:15
102,new,2026-10-01T10:10
102,contacted,2026-10-02T09:30
Enter fullscreen mode Exit fullscreen mode

The script

import csv
from collections import defaultdict
from datetime import datetime
from statistics import median

rows = defaultdict(list)
with open("status_log.csv") as f:
    for r in csv.DictReader(f):
        rows[r["record_id"]].append((datetime.fromisoformat(r["changed_at"]), r["status"]))

waits = defaultdict(list)
for events in rows.values():
    events.sort()
    for (t1, s1), (t2, s2) in zip(events, events[1:]):
        waits[f"{s1} -> {s2}"].append((t2 - t1).total_seconds() / 3600)

for step, hours in sorted(waits.items(), key=lambda kv: -median(kv[1])):
    print(f"{step:25} median {median(hours):6.1f} h  (n={len(hours)})")
Enter fullscreen mode Exit fullscreen mode

Reading the output

The transition with the largest median wait is usually a handoff: someone has to notice, decide or copy something. That is where automation helps most, and often a reminder or a routing rule is enough before any AI is involved.

Two cautions: status changes are only logged when someone updates the record, so long waits can also mean "forgot to update." Check a few records by hand.

This works as a warm-up before a fuller workflow audit. (Disclosure: I co-founded NxFlowAI, whose first audit takes 72 hours.)

NxFlowAI is not affiliated with NexFlow AI or Nexusflow.

Top comments (0)