Skip to content

Long-running DB migration progress

The scariest migrations are the ones where it’s unclear for a long time “is it done or another hour?”. An incremental ping every N% or every N minutes helps.

import os, time, requests
def push(t, m, p=4):
requests.post(f"{os.environ['NOTIFLY_URL']}/message",
params={"token": os.environ["NOTIFLY_TOKEN"]},
json={"title": t, "message": m, "priority": p}, timeout=5)
total = db.count("legacy_users")
processed = 0
last_push = time.time()
last_pct = -1
for batch in db.iter_chunks("legacy_users", 10_000):
migrate(batch)
processed += len(batch)
pct = int(processed / total * 100)
if pct // 10 > last_pct // 10 or time.time() - last_push > 600:
eta = (time.time() - t0) / max(processed, 1) * (total - processed)
push(f"🗄️ Migration {pct}%",
f"{processed:,} / {total:,}\nETA: {int(eta/60)} мин")
last_push = time.time()
last_pct = pct
push("🗄️ Migration: ✅ done", f"Обработано {processed:,} строк за {int((time.time()-t0)/60)} мин", 5)

For migrations performed by an AI agent via apply — wrap them in the agent-run wrapper, and inside call the same push().