<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: douzatan</title>
    <description>The latest articles on DEV Community by douzatan (@douzatan).</description>
    <link>https://dev.to/douzatan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3500763%2Fd477d43f-7280-40d1-b783-a04e4503cb67.jpeg</url>
      <title>DEV Community: douzatan</title>
      <link>https://dev.to/douzatan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/douzatan"/>
    <language>en</language>
    <item>
      <title>Onboarding-Videos aus Team-Dokumentation generieren: unser Workflow nach drei Monaten</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 08 Aug 2026 15:45:09 +0000</pubDate>
      <link>https://dev.to/douzatan/onboarding-videos-aus-team-dokumentation-generieren-unser-workflow-nach-drei-monaten-3f6m</link>
      <guid>https://dev.to/douzatan/onboarding-videos-aus-team-dokumentation-generieren-unser-workflow-nach-drei-monaten-3f6m</guid>
      <description>&lt;p&gt;Unser Team hat ein klassisches Problem gelöst, das vermutlich jedes wachsende Entwicklerteam kennt: Die Onboarding-Doku liest niemand, und für Videos hat niemand Zeit.&lt;/p&gt;

&lt;p&gt;Die Lösung war unspektakulär pragmatisch. Wir generieren die Videos jetzt direkt aus den Dokumenten, die wir sowieso pflegen. Kein Kamera-Setup, kein Schnittprogramm, keine zusätzliche Content-Pipeline.&lt;/p&gt;

&lt;p&gt;Dieser Post beschreibt den Workflow, die Einstellungen, die tatsächlich einen Unterschied machen, und die Stellen, an denen der Ansatz an seine Grenzen stößt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ausgangslage: 40 Seiten Confluence, die keiner liest
&lt;/h2&gt;

&lt;p&gt;Wir sind ein Team von elf Leuten. Unsere Onboarding-Doku war solide gepflegt: Architektur-Überblick, Deployment-Prozess, Coding-Standards, Incident-Runbooks.&lt;/p&gt;

&lt;p&gt;Das Problem war nicht die Qualität. Das Problem war das Format. Neue Kollegen bekamen in der ersten Woche einen Berg Text, und die immer gleichen Fragen landeten trotzdem im Team-Channel.&lt;/p&gt;

&lt;p&gt;Der naheliegende Gedanke "machen wir doch Videos draus" scheiterte zweimal an der Realität: Wer selbst aufnimmt, produziert bei unserem Doku-Umfang wochenlang. Und bei jedem Release veraltet ein Teil der Aufnahmen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Kerngedanke: Docs bleiben die Source of Truth
&lt;/h2&gt;

&lt;p&gt;Der Ansatz, der bei uns funktioniert, folgt derselben Logik wie Docs-as-Code: Es gibt genau eine Quelle, und alles andere ist ein generiertes Artefakt.&lt;/p&gt;

&lt;p&gt;Das Dokument bleibt das Original. Das Video wird daraus erzeugt. Ändert sich der Inhalt, wird das Dokument editiert und das Video neu generiert.&lt;/p&gt;

&lt;p&gt;Damit verschwindet das Problem, das jede Video-Initiative in Teams killt: der Pflegeaufwand. Ein veraltetes Video ist bei uns kein Neuaufnahme-Projekt mehr, sondern ein Regenerieren mit aktualisierter Quelle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Der Workflow im Detail
&lt;/h2&gt;

&lt;p&gt;Wir nutzen dafür den AI-Learning-Video-Generator von Leadde. Der Ablauf besteht aus vier Schritten.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schritt 1: Dokument hochladen
&lt;/h3&gt;

&lt;p&gt;Unterstützt werden .pptx, .pdf, .doc, .docx und .txt bis 500 MB. Wir exportieren die jeweilige Doku-Seite als PDF oder Word-Datei.&lt;/p&gt;

&lt;p&gt;Ein Detail, das uns Arbeit erspart hat: Diagramme und Screenshots aus dem Quelldokument werden geprüft und, wenn brauchbar, direkt ins Video übernommen. Unsere Architektur-Diagramme mussten wir nicht neu bauen.&lt;/p&gt;

&lt;p&gt;Alternativ akzeptiert das Tool auch reinen Text oder einen Prompt, aus dem es selbst eine Struktur baut. Für Doku-Fragmente ohne saubere Datei ist das der schnellere Weg.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schritt 2: Output konfigurieren
&lt;/h3&gt;

&lt;p&gt;Die Einstellungen, die bei uns den Unterschied machen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Avatar: über 200 zur Auswahl. Wir haben einen festgelegt und verwenden ihn für die gesamte Serie. Konsistenz schlägt Abwechslung.&lt;/li&gt;
&lt;li&gt;Länge: vier Presets. Zusammenfassung (1 bis 3 Minuten), ausgewogen (3 bis 5), vertieft (5 bis 7), umfassend je nach Quellumfang. Für Onboarding-Module nehmen wir fast immer das ausgewogene Preset.&lt;/li&gt;
&lt;li&gt;Sprache: 88 Optionen. Wir generieren auf Deutsch und für zwei englischsprachige Kollegen zusätzlich auf Englisch, aus derselben Quelle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Der unterschätzte Teil sind die Kontextfelder unter "Weitere Einstellungen": Erzählstil, Zielgruppe, Sprecherhintergrund, Lernziel. Ein Skript, das mit "Zielgruppe: Backend-Entwickler, neu im Team, kennt unseren Stack nicht" generiert wurde, unterscheidet sich deutlich von einem ohne Kontext. Diese Felder leer zu lassen ist der häufigste Anfängerfehler.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schritt 3: Skript reviewen, wie ein Pull Request
&lt;/h3&gt;

&lt;p&gt;Nach der Analyse liefert das Tool eine Gliederung plus komplettes Sprecherskript. Dann gibt es zwei Buttons: im Studio editieren oder direkt generieren.&lt;/p&gt;

&lt;p&gt;Wir behandeln das Skript wie einen PR: Es wird nie ungelesen gemerged. Der Review dauert bei uns zehn Minuten pro Video und folgt einer festen Checkliste:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Einstieg umschreiben. Die generierten Intros sind korrekt, aber generisch.&lt;/li&gt;
&lt;li&gt;Fachbegriffe prüfen. Interne Projektnamen und Abkürzungen paraphrasiert die KI gern falsch.&lt;/li&gt;
&lt;li&gt;Aussprache fixen. Dafür gibt es ein eigenes Tool; einmal korrigiert, sitzt der Begriff in allen folgenden Videos.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Für Serien-Konsistenz nutzen wir zusätzlich die Knowledge-Base-Funktion: Referenzmaterial hinterlegen, damit die Terminologie über alle Videos stabil bleibt statt zu driften.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schritt 4: Generieren und Stichprobe
&lt;/h3&gt;

&lt;p&gt;Die Generierung läuft ein paar Minuten pro Video. Wir queuen mehrere und reviewen im Block.&lt;/p&gt;

&lt;p&gt;Der finale Check: Untertitel kontrollieren (automatisch generiert, Styling anpassbar), Szenenübergänge prüfen, einmal komplett in 1,5-facher Geschwindigkeit ansehen. Einzelne Szenen lassen sich isoliert korrigieren, ohne den Rest anzufassen. Das macht Wartung realistisch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Zahlen nach drei Monaten
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;22 Onboarding-Module als Video, generiert aus bestehender Doku. Reale Arbeitszeit: rund 8 Stunden insgesamt.&lt;/li&gt;
&lt;li&gt;Aufwand pro Video: 15 bis 25 Minuten, der Großteil davon Skript-Review.&lt;/li&gt;
&lt;li&gt;Zwei Releases mit Doku-Änderungen seither. Update-Aufwand: Dokument editieren, regenerieren, fertig. Früher wäre das der Punkt gewesen, an dem die Videos verwaist wären.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Der messbare Effekt im Team: Die Wiederholungsfragen im Channel sind spürbar zurückgegangen, und neue Kollegen kommen mit konkreteren Fragen in die erste Pairing-Session. Kein kontrolliertes Experiment, klar. Aber der Trend war deutlich genug, dass wir den Rest der Doku nachziehen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo der Ansatz an Grenzen stößt
&lt;/h2&gt;

&lt;p&gt;Drei ehrliche Einschränkungen.&lt;/p&gt;

&lt;p&gt;Erstens: Das Skript braucht immer einen menschlichen Review. Die Struktur stimmt, der Ton ist austauschbar. Wer ungeprüft published, bekommt eine Videobibliothek, die klingt wie von einer Maschine, weil sie es ist.&lt;/p&gt;

&lt;p&gt;Zweitens: Ein Avatar ersetzt keinen guten Live-Workshop. Für interaktive Formate, Pairing und Architektur-Diskussionen bleibt der Mensch gesetzt. Die generierten Videos decken den reproduzierbaren Teil ab, nicht den dialogischen.&lt;/p&gt;

&lt;p&gt;Drittens: Garbage in, garbage out. Schlecht strukturierte Doku ergibt schlecht strukturierte Videos. Der Ansatz belohnt Teams, die ihre Doku ohnehin ernst nehmen, und bestraft die anderen doppelt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Integration in den bestehenden Doku-Prozess
&lt;/h2&gt;

&lt;p&gt;Der Workflow oben beschreibt das Generieren. Interessanter ist, wie das Ganze dauerhaft im Team-Prozess lebt, ohne dass es eine Person "nebenbei" tragen muss.&lt;/p&gt;

&lt;p&gt;Unsere Regeln nach drei Monaten Iteration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ownership folgt der Doku.&lt;/strong&gt; Wer ein Doku-Kapitel pflegt, pflegt auch dessen Video. Kein separates Video-Team, keine Übergabe. Das Video ist ein Artefakt des Kapitels, wie ein generiertes Diagramm.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regenerieren ist Teil der Definition of Done.&lt;/strong&gt; Ändert ein PR die Onboarding-Doku substanziell, gehört das Neu-Generieren des betroffenen Videos zur Fertigstellung. Klingt streng, kostet real aber die erwähnten 15 bis 25 Minuten und verhindert das schleichende Veralten, an dem unsere früheren Video-Anläufe gestorben sind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ein Namensschema von Anfang an.&lt;/strong&gt; Videos heißen bei uns wie die Doku-Kapitel, aus denen sie stammen, plus Versionsdatum. Banal, aber die Zuordnung Quelle-zu-Video muss ohne Nachdenken funktionieren, sonst regeneriert irgendwann jemand aus der falschen Version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quartalsweise Stichprobe.&lt;/strong&gt; Einmal pro Quartal sieht sich ein Teammitglied drei zufällige Videos komplett an. Findet es veraltete Inhalte, war der Prozess davor undicht. Bisher zweimal passiert, beide Male ein fehlendes Regenerieren nach Doku-Änderung.&lt;/p&gt;

&lt;p&gt;Was wir bewusst nicht tun: Videos für Inhalte generieren, die sich wöchentlich ändern. Sprint-spezifisches bleibt Text. Die Video-Schicht lohnt sich ab einer Halbwertszeit von ungefähr einem Quartal, darunter frisst die Pflege den Nutzen.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ aus dem Team-Channel
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Braucht man Video-Editing-Kenntnisse?&lt;/strong&gt;&lt;br&gt;
Nein. Der Editor funktioniert wie ein Folien-Tool, nicht wie ein Schnittprogramm. Hochladen, konfigurieren, Skript reviewen, generieren. Wer Slides bauen kann, kann das hier auch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Wie gut ist das deutsche Voiceover?&lt;/strong&gt;&lt;br&gt;
Besser als erwartet, mit einer Einschränkung: Fachbegriffe und Projektnamen brauchen gelegentlich einen manuellen Aussprache-Fix. Der ist einmalig pro Begriff und gilt danach für alle Videos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Was kostet ein Video an Zeit?&lt;/strong&gt;&lt;br&gt;
Nach der Einrichtungsphase 15 bis 25 Minuten Eigenaufwand. Die ersten zwei, drei Videos dauern länger, weil man seine Einstellungen noch sucht. Danach ist es Routine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lohnt sich das für kleine Teams?&lt;/strong&gt;&lt;br&gt;
Gerade für kleine. Große Organisationen haben L&amp;amp;D-Abteilungen; kleine Teams haben niemanden, dessen Job das ist. Genau diese Lücke füllt der generierte Ansatz.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Was ist mit vertraulichen Inhalten in der Doku?&lt;/strong&gt;&lt;br&gt;
Wir trennen vorher: Onboarding-Inhalte, die ins Video dürfen, liegen in eigenen Kapiteln, getrennt von Secrets, Kundendaten und internen Details. Diese Trennung hatten wir aus Doku-Hygiene ohnehin, sie zahlt sich hier doppelt aus. Zusätzlich lassen sich veröffentlichte Videos mit Passwortschutz versehen, was wir für teaminterne Module standardmäßig tun.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Warum nicht einfach Loom-Aufnahmen?&lt;/strong&gt;&lt;br&gt;
Haben wir davor gemacht, und die Aufnahmen waren nach zwei Releases veraltet und wurden nie aktualisiert, weil Neuaufnehmen Aufwand ist. Screencasts sind super für einmalige Erklärungen an eine Person. Für wiederverwendbare Module mit Update-Bedarf verliert das Format gegen generierte Videos, deren Quelle ein editierbares Dokument ist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fazit und Einstiegspunkt
&lt;/h2&gt;

&lt;p&gt;Wer seine Onboarding-Doku pflegt und trotzdem zusieht, wie sie ungelesen bleibt, hat das Rohmaterial bereits fertig. Der Rest ist Transformation, keine Produktion.&lt;/p&gt;

&lt;p&gt;Der pragmatische Test: das meistgefragte Doku-Kapitel exportieren und damit &lt;a href="https://leadde.ai/de/tools/ai-learning-video-generator" rel="noopener noreferrer"&gt;E-Learning-Videos selbst erstellen&lt;/a&gt;, mit ausgewogenem Preset und ausgefüllten Kontextfeldern. Nach einer halben Stunde liegt das erste Modul vor, und die Entscheidung fällt auf Basis eines echten Ergebnisses statt einer Produktseite.&lt;/p&gt;

&lt;p&gt;Bei uns hat genau dieses eine Testvideo den Ausschlag gegeben. Die anderen 21 kamen, weil das erste gut genug war.&lt;/p&gt;

&lt;p&gt;Fragen zum Workflow gern in die Kommentare. Insbesondere Erfahrungen mit anderen Doku-zu-Video-Pipelines würden mich interessieren; unser Setup ist bewusst simpel gehalten, und ich bin sicher, da geht noch mehr.&lt;/p&gt;

&lt;p&gt;Ein Punkt, den ich als Nächstes testen will: die Analytics-Daten der Videos systematischer auswerten. Die Plattform zeigt pro Video, wie weit geschaut wird, und die Abbruchstellen unserer Onboarding-Module sind vermutlich die ehrlichste Doku-Review, die wir je hatten. Wo Leute aussteigen, ist entweder das Video zu lang oder das zugrunde liegende Kapitel schlecht strukturiert. Beides ist ein Fix im Quelldokument, kein Video-Problem. Wenn sich daraus etwas Brauchbares ergibt, schreibe ich einen Follow-up-Post.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>video</category>
    </item>
    <item>
      <title>My 30-minute monthly ritual for picking dev tutorial topics</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 01 Aug 2026 15:27:16 +0000</pubDate>
      <link>https://dev.to/douzatan/my-30-minute-monthly-ritual-for-picking-dev-tutorial-topics-3e6n</link>
      <guid>https://dev.to/douzatan/my-30-minute-monthly-ritual-for-picking-dev-tutorial-topics-3e6n</guid>
      <description>&lt;p&gt;I make developer tutorials on the side, and for a long time my topic pipeline was "whatever bug I fought last." That produces the occasional hit and a lot of misses, because the bugs I happen to hit aren't a representative sample of what my audience is stuck on.&lt;/p&gt;

&lt;p&gt;About a year ago I replaced the vibes with a ritual. Last Sunday of the month, coffee, thirty minutes, one page in my notes app. Here's the whole thing, phase by phase, in case it's useful to steal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 1 — Dump the candidates (5 minutes)
&lt;/h2&gt;

&lt;p&gt;I open a note and brain-dump every topic I could plausibly make a video about that month. No filtering. Bugs I fixed, questions from my Discord, a library I finally understood, something a coworker asked twice.&lt;/p&gt;

&lt;p&gt;The goal here is volume, not quality. I usually land on 12 to 20 candidates. Most will die in the next phase, and that's the point — this is the cheapest place to kill a bad idea, before it costs me a weekend of filming.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 2 — Pull real demand (10 minutes)
&lt;/h2&gt;

&lt;p&gt;This is the phase that changed my numbers, so I'll spend the words here.&lt;/p&gt;

&lt;p&gt;I take each candidate and check whether people actually search for it, and in what words. I use AllyHub's free tool to look up the &lt;a href="https://allyhub.com/tools/youtube-video-finder" rel="noopener noreferrer"&gt;YouTube most searched keywords&lt;/a&gt; around a topic — I type in a candidate like "react useEffect cleanup" and it shows me what people search near it, which phrasings pull more interest, and which videos currently surface for those queries.&lt;/p&gt;

&lt;p&gt;Two columns go in my note for each candidate: rough relative demand, and how strong the existing coverage looks. I'm not chasing precise numbers — the tool gives relative signal, not a view-count promise, and I treat it that way. I just want to know: is anyone looking for this, and is it already answered to death?&lt;/p&gt;

&lt;p&gt;A candidate I was sure about — "clean architecture in Node" — turned out crowded and well-served. One I nearly cut — "prisma migrate drift resolve" — showed steady interest with only scattered forum answers behind it. Column data flipped my instinct completely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 3 — Score and rank (5 minutes)
&lt;/h2&gt;

&lt;p&gt;Now I sort. My scoring is deliberately dumb: I want the intersection of real demand and weak existing coverage. High demand plus ten strong videos already there? Skip — I won't win that. Real demand plus stale or thin coverage? That goes to the top.&lt;/p&gt;

&lt;p&gt;I also flag anything with essentially zero search volume that I still want to make. More on those in a second. They don't get scored against the demand topics — they're a separate bucket.&lt;/p&gt;

&lt;p&gt;By the end of this phase I have a ranked shortlist of three or four topics, and I pick the top one or two to actually produce that month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase 4 — Reality-check with my own judgment (5 minutes)
&lt;/h2&gt;

&lt;p&gt;The data tells me what's wanted. It does not tell me whether I can make a good video about it, and I don't let it pretend otherwise. So the last five minutes are a gut check on each shortlisted topic: do I actually understand this well enough to teach it clearly, do I have a decent example on hand, will I still care about it once the camera's rolling.&lt;/p&gt;

&lt;p&gt;A topic can have great demand and still be a no for me because I'd make a shallow video. Demand is necessary. It's nowhere near sufficient. The quality is entirely on me once I hit record — no keyword tool is going to save a tutorial where I don't know the material.&lt;/p&gt;

&lt;h2&gt;
  
  
  The exemption I keep on purpose
&lt;/h2&gt;

&lt;p&gt;That separate bucket from Phase 3 matters. Some videos I make regardless of search demand, and I refuse to route them through this ritual.&lt;/p&gt;

&lt;p&gt;When I release an open-source tool, I make a walkthrough — nobody's searching for a thing that launched yesterday. When I have an opinion about where a framework is heading, I record it. When something breaks in a way that taught me something, I do a post-mortem. These are bets on trust and voice, not discovery, and running them through a demand filter would just talk me out of the work worth doing.&lt;/p&gt;

&lt;p&gt;So the ritual isn't "only make what people search for." It's "know which bucket a video is in." Discovery videos earn their spot through demand. Authority videos earn it through having something to say. The whole point of thirty minutes on the last Sunday is to stop confusing the two — which I did, expensively, for about two years before I wrote the ritual down.&lt;/p&gt;

</description>
      <category>youtube</category>
    </item>
    <item>
      <title>Your Hackathon Demo Video Has a Second Life — Measure It</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 01 Aug 2026 15:02:59 +0000</pubDate>
      <link>https://dev.to/douzatan/your-hackathon-demo-video-has-a-second-life-measure-it-386j</link>
      <guid>https://dev.to/douzatan/your-hackathon-demo-video-has-a-second-life-measure-it-386j</guid>
      <description>&lt;p&gt;The weekend ends, the judges score, someone wins the API-sponsor prize, and everyone flies home. What most teams forget is that the two-minute demo video they recorded at 3 a.m. is still online, still indexed, and still answering a question people type into search months later. That video outlives the event by a wide margin. The event was one day. The video is a permanent artifact.&lt;/p&gt;

&lt;p&gt;Almost nobody measures the afterlife. Teams check the view count the Monday after — 200 views, mostly teammates and judges — and never look again. They miss the interesting part, which happens slowly and much later.&lt;/p&gt;

&lt;h2&gt;
  
  
  The demo is a landing page you already built
&lt;/h2&gt;

&lt;p&gt;Think about who finds a hackathon demo six months out. Not the judges. It is someone with the exact problem your hack solved, typing "how to X with Y API" into YouTube or Google and landing on your clip. That person is worth a hundred launch-day teammates, because they arrived carrying the problem your project addresses.&lt;/p&gt;

&lt;p&gt;If you shipped the project into a real product, that trickle is a lead source. If you're job hunting, it is a portfolio piece that keeps introducing itself while you sleep. Either way, the number you want isn't the total. It's whether new people keep arriving after the hype is gone.&lt;/p&gt;

&lt;h2&gt;
  
  
  A flat total hides the only signal that matters
&lt;/h2&gt;

&lt;p&gt;Say the video sits at 1,400 views. Fine — but that lump tells you nothing about direction. Two very different stories produce the same 1,400:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A launch spike of 1,300 in week one from your own network, then near-zero. The video is dead; it only ever reached people you already knew.&lt;/li&gt;
&lt;li&gt;300 in week one, then a steady 30–40 a week for the rest of the year. Search found it. Strangers with the problem keep showing up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The second video is the asset. The first is a memento. You cannot tell them apart from a cumulative count — you need the shape over time, the per-week velocity. That is the whole reason to track a curve instead of a total.&lt;/p&gt;

&lt;h2&gt;
  
  
  Snapshot on a schedule and let history accumulate
&lt;/h2&gt;

&lt;p&gt;The mechanics are dull, which is why they get skipped. You have to record the count on a fixed cadence so the gaps between readings become weekly velocity you can trust. Miss a few weeks and you are back to guessing.&lt;/p&gt;

&lt;p&gt;I set a small tool to &lt;a href="https://allyhub.com/tools/youtube-view-tracker" rel="noopener noreferrer"&gt;track YouTube video views&lt;/a&gt; on a daily snapshot for anything I want to watch long-term. It saves each reading, keeps the running history, and draws the per-day curve, so I'm looking at the slope rather than a single figure that only goes up. You configure it once and it keeps building the log on its own — no restart, no re-import when I check back in a quarter later. Daily is more than enough resolution here; a demo's afterlife moves in weeks, not seconds, and a live-updating counter would tell you nothing a once-a-day reading doesn't.&lt;/p&gt;

&lt;p&gt;For deep channel analytics — retention, traffic sources, where a viewer dropped — YouTube Studio is the right place, and better than any outside tool for your own uploads. The external snapshot solves a narrower problem: it works across any public video, including ones on a teammate's or the organizer's channel you don't own, and it keeps the comparison clean over long stretches.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the curve tells you to do next
&lt;/h2&gt;

&lt;p&gt;Read the slope and act on it. A demo that keeps pulling steady weekly views is telling you the topic has durable search demand — that is a signal to write the blog post, cut the follow-up video, or point the project's landing page at that keyword. A demo that spiked and flatlined is telling you the idea traveled through your network but never connected to a standing question people search for.&lt;/p&gt;

&lt;p&gt;Both are useful once the event is over and you're deciding where the project goes next. The hackathon graded your weekend. The view curve grades whether the thing you built keeps finding the people who need it.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Wie ich aus vorhandenen Schulungsunterlagen Lernvideos gemacht habe, ohne etwas zu filmen</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 01 Aug 2026 07:31:38 +0000</pubDate>
      <link>https://dev.to/douzatan/wie-ich-aus-vorhandenen-schulungsunterlagen-lernvideos-gemacht-habe-ohne-etwas-zu-filmen-1m6c</link>
      <guid>https://dev.to/douzatan/wie-ich-aus-vorhandenen-schulungsunterlagen-lernvideos-gemacht-habe-ohne-etwas-zu-filmen-1m6c</guid>
      <description>&lt;p&gt;Unser Team hat brauchbare interne Schulungsunterlagen: Folien, ein paar PDFs, Notizen dazu, wie Dinge bei uns wirklich laufen. Was fehlte, war jemand, der sie sich ansieht. Neue Kolleginnen und Kollegen bekamen eine Foliensammlung ohne Kontext, überflogen sie und stellten dann trotzdem dieselben Fragen. Ein richtiges Lernvideo hätte geholfen, aber das von Hand zu produzieren, war nie realistisch. Also blieb es bei Text, den kaum jemand las.&lt;/p&gt;

&lt;p&gt;Ich habe ausprobiert, Lernvideos direkt aus den Unterlagen zu erzeugen, die wir ohnehin pflegen. Hier eine kurze Bilanz, ehrlich auch bei den Grenzen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Warum Folien als Lernmaterial schwach sind
&lt;/h2&gt;

&lt;p&gt;Folien sind dafür gebaut, einen Vortragenden zu stützen. Ohne die Person bleiben Stichpunkte, denen die wichtigste Ebene fehlt. Ein Dokument ist besser zum Nachschlagen, aber schlechter für den ersten Durchgang, weil kaum jemand ein System von oben nach unten durchliest, um es zu verstehen. Was wirklich einarbeitet, ist ein einmaliger Durchlauf im eigenen Tempo. Genau den hatten wir nie, weil Aufnahme und Schnitt pro Thema mehr Aufwand sind als die eigentliche Arbeit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Das Video aus dem Dokument erzeugen
&lt;/h2&gt;

&lt;p&gt;Ich wollte &lt;a href="https://leadde.ai/tools/ai-learning-video-generator" rel="noopener noreferrer"&gt;Lernvideos mit KI erstellen&lt;/a&gt; und habe dem Tool gegeben, was schon da war: die Folien als Text plus meine Notizen. Er hat eine Gliederung entworfen, die Szenen aufgebaut und die Vertonung erzeugt. Man wählt einen Erzählstil und einen Detailgrad und benennt die Zielgruppe. Ich habe erklärend, ausführlich, Zielgruppe „neue Entwicklerin" eingestellt, und das Skript hat den Stoff vermittelt, statt Stichpunkte vorzulesen.&lt;/p&gt;

&lt;p&gt;Entscheidend für einen Doku-Workflow: Die Eingabe ist das Dokument. Etwas Falsches korrigiere ich, indem ich den Text ändere und neu erzeuge, nicht durch eine neue Aufnahme. Als sich die Einrichtung letzten Monat geändert hat, war das Aktualisieren eine Sache von Minuten, kein Dreh. Für Leute, die den ganzen Tag an Code iterieren, fühlt sich das normal an. Die Unterstützung für viele Sprachen hieß außerdem, dass wir eine Version für nicht deutschsprachige Kolleginnen ausspielen konnten, indem wir das fertige Video übersetzen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wo es an Grenzen stößt
&lt;/h2&gt;

&lt;p&gt;Ehrlich: Der erzeugte Sprecher wirkt bei genauem Hinsehen leicht synthetisch. Für interne Schulung stört mich das nicht, für etwas nach außen Gerichtetes würde ich es abwägen. Es ist außerdem deutlich besser darin, Konzepte und Abläufe zu erklären, als eine echte Bildschirminteraktion zu zeigen. Für den Teil, in dem ich eine echte Terminal-Sitzung zeigen wollte, war eine Bildschirmaufnahme das richtige Werkzeug, nicht dieses. Und das Ergebnis spiegelt nur die Eingabe: Aus schludrigen Notizen wird ein schludriges Video, was nebenbei ehrliches Feedback zu den Notizen selbst war.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was sich geändert hat
&lt;/h2&gt;

&lt;p&gt;Wir haben die Doku nicht ersetzt. Wir haben für die paar Themen, die neue Leute wirklich verinnerlichen sollten, kurze Videoversionen ergänzt, erzeugt aus den Unterlagen, die wir schon pflegen. Neue Kolleginnen sehen den Ablauf jetzt einmal während der Einarbeitung, statt ihm zum ersten Mal im Ernstfall zu begegnen, und die Videos bleiben aktuell, weil sie aus derselben Quelle neu erzeugt werden.&lt;/p&gt;

&lt;p&gt;Wenn ihr Schulungsunterlagen habt und immer vorhattet, Video zu ergänzen, es aber nie getan habt, weil es ein separater Aufwand ist, dann passt das hier. Nehmt das eine Thema, das am häufigsten Rückfragen auslöst, erzeugt aus dem vorhandenen Dokument eine Version im kostenlosen Tarif und legt sie in die Einarbeitung. Bei uns war es das Onboarding zum Deployment, und die zwanzig Minuten haben sich gelohnt.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Our Tutorial Videos Rotted Every Release, So We Stopped Filming Them</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 01 Aug 2026 05:47:46 +0000</pubDate>
      <link>https://dev.to/douzatan/our-tutorial-videos-rotted-every-release-so-we-stopped-filming-them-hb6</link>
      <guid>https://dev.to/douzatan/our-tutorial-videos-rotted-every-release-so-we-stopped-filming-them-hb6</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9mekzonn2ksl1rtdpbyd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9mekzonn2ksl1rtdpbyd.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every release used to break a video.&lt;/p&gt;

&lt;p&gt;We maintain a developer tool, and the short explainer videos attached to it stayed accurate for about six weeks. Then a flag got renamed, a panel moved, the default changed, and the video was quietly wrong. Nobody volunteered to re-record it, because re-recording meant blocking an afternoon, setting up a mic, and doing five takes to get ninety seconds without stumbling over the word "idempotent." So the wrong video stayed up until a user pointed it out in an issue, and then it usually got deleted rather than remade.&lt;/p&gt;

&lt;p&gt;The docs never had this problem. A doc changes in a pull request. Someone reviews the diff, it merges, and the site rebuilds. Video had no equivalent of that loop, so video rotted, and after the second round of rot we stopped making it. That is how a team ends up with docs that are current and a YouTube playlist that is a museum.&lt;/p&gt;

&lt;p&gt;What eventually fixed it was not better recording discipline. It was removing the recording step entirely, so the video became something we regenerate from text like everything else we ship.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why we wanted a presenter and not just a screencast
&lt;/h2&gt;

&lt;p&gt;The obvious answer is a screencast with a voiceover. We had those. They are fine for "here is the sequence of clicks," and they are genuinely better than a talking head for anything where the user needs to see the actual interface respond.&lt;/p&gt;

&lt;p&gt;They are worse for the conceptual half. When the video is explaining why a feature exists, what the mental model is, or which of two approaches you should pick, a cursor moving around a screen while a disembodied voice talks is hard to stay with. I notice it in my own viewing: I keep the tab open, I stop watching, I skim the transcript instead. A face delivering the explanation holds me longer. I do not have clean numbers from our own content to prove this, and I am suspicious of anyone who claims they do, but the pattern was consistent enough that we kept wanting the presenter format and kept failing to produce it.&lt;/p&gt;

&lt;p&gt;The reason we failed was mundane. A talking head requires a specific human being to be available, on camera, on a schedule. On a small team, that human is also the person shipping the feature the video is about. Their time is the constraint, and video loses to shipping every single time. The format was not too hard for us. It was too dependent on a calendar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating the presenter from the script instead
&lt;/h2&gt;

&lt;p&gt;The change was using an &lt;a href="https://leadde.ai/tools/ai-talking-head-generator" rel="noopener noreferrer"&gt;AI talking head generator&lt;/a&gt; to produce the presenter, so the input is a script rather than a recording session.&lt;/p&gt;

&lt;p&gt;The mechanics are dull, which is the point. You paste the script, pick a presenter from the built-in library, choose a voice, and it generates the talking-head video with lip sync. There is a setting for more natural expression so the delivery does not come out flat. You can also generate an avatar from a single photo if you want a consistent face that is specifically yours rather than one from the library, and you can put your own background behind it or drop in a brand kit so the clips in a series match. Output is an MP4 you download, plus a hosted link if you want to embed it.&lt;/p&gt;

&lt;p&gt;The part that mattered for us: fixing a line means editing text and regenerating. Not booking a re-record. Not asking a teammate to sit down again for one sentence. That single property is what turned video from a project into a build step. When we renamed a flag last quarter, updating the video was a two-line diff in a script file and a regenerate, and it was done before the release notes were finished.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scripts live in the repo now
&lt;/h2&gt;

&lt;p&gt;Once video generation takes text as input, the script is source, so we treat it that way.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
  videos/
    01-getting-started.script.md
    02-config-file.script.md
    03-ci-integration.script.md
    README.md          # voice, presenter, aspect ratio per series
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scripts get reviewed in a pull request like anything else. If a PR changes a CLI flag and there is a script mentioning that flag, the reviewer sees both in the same diff, which is the thing that never happened when video lived in a folder on someone's laptop. We do not have automated generation wired to CI, and I would not pretend otherwise: someone still opens the browser, pastes the updated script, and regenerates. But the expensive part is gone, and the cheap part is a five minute chore rather than an afternoon.&lt;/p&gt;

&lt;p&gt;A few things we learned about writing these scripts, none of which are obvious the first time:&lt;/p&gt;

&lt;p&gt;Write for the ear, not the eye. Sentences you would happily publish in a doc are often too long to listen to. Read the script out loud once before generating and cut anything you run out of breath on.&lt;/p&gt;

&lt;p&gt;Do not read code aloud. A synthesized voice narrating &lt;code&gt;--max-retries=3&lt;/code&gt; is unpleasant, and it is unpleasant when a human does it too. Say what the flag does, show the code on screen, and let the two work together.&lt;/p&gt;

&lt;p&gt;Say numbers the way people say them. Written "v2.4.0" gets voiced in ways you will not like. Spell it out phonetically in the script and let the doc keep the clean version.&lt;/p&gt;

&lt;p&gt;The scripts also gave us something we did not plan for. Because our docs are translated, we can generate the same video in other languages from a translated script with the same presenter, which is a lot more approachable than asking someone to re-record a tutorial in a language they do not speak.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it is genuinely not good
&lt;/h2&gt;

&lt;p&gt;This puts a synthetic face on screen, so being straight about it matters more than usual for a dev audience, which is not a crowd that responds well to being sold to.&lt;/p&gt;

&lt;p&gt;It reads as generated. Not badly, but if you look at it with intent, you can tell it is not filmed. For routine explanatory content that is fine and nobody has complained. For anything where you are the point, a conference talk, a project announcement you want to feel personal, a video where a user is deciding whether to trust you as a maintainer, film yourself or do not make the video.&lt;/p&gt;

&lt;p&gt;It does not show your interface. The presenter explains, it does not demonstrate. For the click-by-click sections we still capture the screen with our own recorder and upload that footage, then shrink the avatar into a corner so the interface has the frame. Anyone expecting the tool to record their screen for them is expecting the wrong tool.&lt;/p&gt;

&lt;p&gt;The output is only as good as the script. Our first attempt was lifeless because we fed it a doc page verbatim, and a doc page is written to be scanned, not spoken. Rewriting it as something a person would actually say fixed it. The tool has no idea what your users are confused about unless the script says so.&lt;/p&gt;

&lt;p&gt;And on likeness: only build an avatar from an image you have the right to use. If it is a teammate's face, that needs their explicit yes, and the yes needs to cover the videos you are actually going to make with it. Putting a colleague's face on a video they never agreed to is not a shortcut worth taking.&lt;/p&gt;

&lt;h2&gt;
  
  
  If you want to try this
&lt;/h2&gt;

&lt;p&gt;Do not migrate a whole channel. Pick the one video you already know is out of date and have been avoiding for a month, write the script as a real script rather than a pasted doc page, and generate a couple of versions on a free tier. Watch them with someone who has not read the script.&lt;/p&gt;

&lt;p&gt;If the presenter reads as a deliberate choice rather than an accident, keep it for that format. If it reads as off, you have lost an hour and learned something. For us the test case was the getting-started video, the one that broke on literally every release, and it has been current for three releases running, which it never managed when it depended on somebody being free to film.&lt;/p&gt;

</description>
      <category>devrel</category>
      <category>documentation</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Pick Which Coding Lessons to Record, After Wasting a Term on the Wrong Ones</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Wed, 29 Jul 2026 03:43:29 +0000</pubDate>
      <link>https://dev.to/douzatan/how-i-pick-which-coding-lessons-to-record-after-wasting-a-term-on-the-wrong-ones-407f</link>
      <guid>https://dev.to/douzatan/how-i-pick-which-coding-lessons-to-record-after-wasting-a-term-on-the-wrong-ones-407f</guid>
      <description>&lt;p&gt;I teach web development, partly in a bootcamp and partly on a YouTube channel that started as lecture overflow. For my first full term of recording, I chose topics the way most instructors do: I taught what I thought was foundational, in syllabus order. Syllabus order and "what people actually get stuck on" order turned out to be almost unrelated, and my analytics said so, loudly.&lt;/p&gt;

&lt;p&gt;Key takeaways&lt;br&gt;
Pick tutorial topics from observed search demand, not from syllabus order or personal interest.&lt;br&gt;
Collect the exact phrases learners type, typos included, then check which ones people actually search.&lt;br&gt;
Chase the overlap: real search demand plus weak or dated coverage.&lt;br&gt;
Keyword research decides what to make, not whether your teaching is any good. Those are separate problems.&lt;br&gt;
The term I wasted on syllabus order&lt;br&gt;
My carefully sequenced fundamentals playlist was a graveyard with two or three accidental hits. The hits confused me most, because I could not explain them, which meant I could not repeat them. A content library shaped by the syllabus mostly serves the syllabus.&lt;/p&gt;

&lt;p&gt;The accidental hit that changed my process&lt;br&gt;
I recorded a five-minute throwaway on a CORS error because a student hit it twice in one week. I almost did not post it. It has more views than my entire fundamentals playlist combined, and the comments are all one sentence: thank you, this was the only clear explanation I could find.&lt;/p&gt;

&lt;p&gt;Step 1: collect the phrases learners actually type&lt;br&gt;
Now I keep a running note of every question I see learners ask, in Discord servers, in subreddit threads, and under my own videos. I add the error messages and "how do I" moments from my own week. No filtering yet. The list runs 15 to 20 phrases, written the way people actually typed them, typos preserved. The typos are the real vocabulary.&lt;/p&gt;

&lt;p&gt;Step 2: check the phrases against real search demand&lt;br&gt;
Before I record anything, I spend twenty minutes running that list through a YouTube keyword research tool to see which phrasings people search around a topic and what already surfaces for them. This step deletes about two thirds of my list, which is the point.&lt;/p&gt;

&lt;p&gt;The two gaps worth chasing&lt;br&gt;
First, the vocabulary gap. I teach "asynchronous control flow." Nobody stuck at midnight searches that. They search "why is my await not waiting." I now keep a small glossary mapping my teaching terms to the searched phrasings, and I use the searched version in the title.&lt;/p&gt;

&lt;p&gt;Second, the coverage gap. Some of the most-searched beginner errors are answered only by videos years old, using syntax two versions out of date. That is not competition. That is an opening, and it goes to the front of my queue.&lt;/p&gt;

&lt;p&gt;One honest limit&lt;br&gt;
This tells you what to make, not whether your explanation lands. I have posted well-researched topics with mediocre teaching and watched them underperform a rushed video on a hotter question. Selection gets you found. The teaching still has to be good, and no keyword tool fixes that half for you.&lt;/p&gt;

&lt;p&gt;Try it before your next recording&lt;br&gt;
If your channel has a graveyard and a couple of mystery hits, spend twenty minutes on demand before your next video. Worst case, you confirm your instinct. Best case, you stop making videos nobody was ever going to search for.&lt;/p&gt;

</description>
      <category>youtube</category>
      <category>teaching</category>
      <category>webdev</category>
      <category>contentcreation</category>
    </item>
    <item>
      <title>We route our agents across three model tiers. Here's the logic</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Fri, 17 Jul 2026 15:36:58 +0000</pubDate>
      <link>https://dev.to/douzatan/we-route-our-agents-across-three-model-tiers-heres-the-logic-c9n</link>
      <guid>https://dev.to/douzatan/we-route-our-agents-across-three-model-tiers-heres-the-logic-c9n</guid>
      <description>&lt;p&gt;We rebuilt our agent stack around model routing about two months ago. This is what we learned, including the part where our first version was worse than doing nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup that broke
&lt;/h2&gt;

&lt;p&gt;Our research agent reads vendor documents, extracts claims, checks them against each other, and drafts a recommendation for a human to sign. Forty or so memos a month.&lt;/p&gt;

&lt;p&gt;We built it on one frontier model because that's what was in the tutorial we started from. Every step, same model. It worked well enough that nobody looked at it for a quarter, which is exactly how these things go.&lt;/p&gt;

&lt;p&gt;Then we looked at the bill.&lt;/p&gt;

&lt;p&gt;The distribution was the problem. About 4% of our calls were doing something a cheap model would get wrong. The other 96% were classification, extraction, formatting, and retries, where a cheap model gets the same answer. We had been paying a premium on all of it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt one: a global downgrade (don't do this)
&lt;/h2&gt;

&lt;p&gt;Our first fix was to swap the whole pipeline to a cheaper tier and see what broke.&lt;/p&gt;

&lt;p&gt;Plenty broke, but not where we expected. Classification and extraction were fine. Formatting was fine. What fell apart was the step where the agent had to look at two documents that disagreed and decide which one to trust. The cheap model didn't fail loudly there. It picked one, wrote a confident sentence about it, and moved on. The error flowed straight into the memo.&lt;/p&gt;

&lt;p&gt;That's the lesson that reorganized how we think about this. Cheap models don't fail by producing garbage. They fail by producing something plausible that survives review. On a classification task you notice immediately. On a judgment task you notice when a client does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Attempt two: route by blast radius
&lt;/h2&gt;

&lt;p&gt;The question we now ask at every step is not "is this hard." It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If this step returns a mediocre answer, how far does it travel before someone catches it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That reframing did more for us than any model comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius of one row&lt;/strong&gt; goes to the cheapest tier that passes. A misclassified document gets caught by the next step or by a human scanning a list. Wrong is cheap here. This is most of the pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius of a section&lt;/strong&gt; goes to a balanced tier. Structuring evidence, drafting a paragraph, ordinary summarization. Errors are visible on read-through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius of the whole deliverable&lt;/strong&gt; goes to the premium tier. For us that's exactly two steps: reconciling sources that contradict each other, and the final pass before a human signs. Under 5% of calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Blast radius beyond the deliverable&lt;/strong&gt; goes to a human. Anything touching a customer, money, or production.&lt;/p&gt;

&lt;p&gt;Our spend dropped by a little over half. Memo quality went up slightly, which I attribute mostly to the fact that writing this table forced us to articulate what each step was for. Half the win had nothing to do with models.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the tiers actually differ
&lt;/h2&gt;

&lt;p&gt;Worth understanding why this works rather than cargo-culting the table.&lt;/p&gt;

&lt;p&gt;When Anthropic launched Claude Fable 5 it made a claim that reads like marketing but functions as engineering guidance: the model's lead grows as tasks become longer and more complex. Anthropic says it's a Mythos-class model made safe for general use whose capabilities exceed any model the company has made generally available, and that it stays focused across millions of tokens on long-running tasks while improving its output using its own notes. Anthropic says Stripe used it to complete a codebase-wide migration in a 50-million-line Ruby codebase in a day, against more than two months of manual work.&lt;/p&gt;

&lt;p&gt;The advantage is conditional on difficulty. On a short easy call the tiers converge and you're paying for a margin you can't measure. On a long tangled one the gap is your product.&lt;/p&gt;

&lt;p&gt;That's the whole justification for routing. If the advantage were flat across task types, routing would be pointless and you'd just buy the best model. It isn't flat.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pricing math
&lt;/h2&gt;

&lt;p&gt;Anthropic lists Fable 5 at $10 per million input tokens and $50 per million output tokens.&lt;/p&gt;

&lt;p&gt;The trap in agent workflows is that spend doesn't scale with tasks, it scales with turns. One "check these twelve documents" task is not twelve calls. It's twelve reads, a pile of pairwise comparisons, a revision, a validation pass, and however many retries. The loop is the product and the loop is the cost.&lt;/p&gt;

&lt;p&gt;We run on the &lt;a href="https://buda.im/claude-fable-5" rel="noopener noreferrer"&gt;Buda AI Agent Workspace&lt;/a&gt;, where Fable 5 is a subscription-only premium tier rather than the default, and the credit multipliers are stated where you pick: Sonnet 4.6 at 1.0x, Opus 4.8 at 1.7x, Fable 5 at 3.3x. The specific stack matters less than the property. If the cost of a routing decision isn't visible when you make it, you'll make it once in week one and never revisit it.&lt;/p&gt;

&lt;p&gt;The persistent workspace turned out to matter more than the multipliers. The reason we resisted routing for so long was a worry that switching models mid-workflow would lose the thread. When every step reads the same context, that stops being a concern and routing costs you nothing to adopt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Gotchas
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The safety fallback.&lt;/strong&gt; Anthropic says Fable 5 includes safety classifiers and that some cybersecurity, biology, chemistry, and distillation-related requests may automatically get a response from Claude Opus 4.8 instead, at under 5% of sessions on average. We hit this on a security-review workflow and spent a day chasing a nonexistent bug. Log which model actually answered. It's a one-line change that will save someone an afternoon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Retries are invisible.&lt;/strong&gt; Each retry looks cheap, so nobody instruments them. Ours were about 2.5x my estimate. Track retries per task per tier before you trust any cost model you've built.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Don't route by vibes.&lt;/strong&gt; "This step feels important" is not a criterion. Blast radius is, and two people looking at the same step will usually agree on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do differently
&lt;/h2&gt;

&lt;p&gt;Start with the routing table, not the model choice. Walk your pipeline, mark each step by how far a bad answer travels, and you'll usually find the expensive question is a small identifiable minority you've been funding by inertia.&lt;/p&gt;

&lt;p&gt;The best model available is the right choice for the steps where being wrong is expensive. It's a bad default for everything else, and everything else is most of your bill.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>architecture</category>
      <category>costoptimization</category>
    </item>
    <item>
      <title>I built a view-velocity tracker for our devrel channel, then learned the YouTube API quota lesson the hard way (twice)</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Fri, 10 Jul 2026 17:07:49 +0000</pubDate>
      <link>https://dev.to/douzatan/i-built-a-view-velocity-tracker-for-our-devrel-channel-then-learned-the-youtube-api-quota-lesson-1dlj</link>
      <guid>https://dev.to/douzatan/i-built-a-view-velocity-tracker-for-our-devrel-channel-then-learned-the-youtube-api-quota-lesson-1dlj</guid>
      <description>&lt;p&gt;We ship developer tutorials on a channel nobody outside the company would call famous. Solid mid-size, a couple dozen new subscribers on a good week. For most of last year, our entire notion of "did that video work" was whoever ran the release checking the count a few days later and pasting a screenshot into Slack. That is not measurement. That is a vibe with a timestamp.&lt;/p&gt;

&lt;p&gt;The problem with a raw view count is that it only goes up. It is cumulative by construction, so it can never tell you the one thing you actually care about: is this video still gaining, or did it flatline the day the launch tweet fell off people's timelines? The signal lives in the derivative — views per day, per video, tracked from the moment it goes public. Velocity is where you can see a topic actually land versus a topic that just accumulates dust at a slow, respectable rate.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tuesday-afternoon version
&lt;/h2&gt;

&lt;p&gt;So of course I decided to build the thing. The YouTube Data API hands you a view count if you ask nicely, and a cron job that writes snapshots to Postgres sounded like a Tuesday afternoon. Here is roughly where I started:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;timezone&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;googleapiclient.discovery&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;build&lt;/span&gt;

&lt;span class="n"&gt;VIDEO_IDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...]&lt;/span&gt;  &lt;span class="c1"&gt;# our catalog + a few benchmark videos
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;yt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;youtube&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v3&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;developerKey&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;YT_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
    &lt;span class="c1"&gt;# the API caps id lists at 50, so chunk it
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;chunk&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;video_ids&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;yt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;videos&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;part&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;,&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunk&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;items&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;ts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;datetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;fetch_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;VIDEO_IDS&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;store_row&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;video_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;statistics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;viewCount&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
            &lt;span class="n"&gt;captured_at&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs. It works on the first try, which is exactly the kind of early success that sets you up for later humility.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning the quota ceiling twice
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Quota lesson, part one.&lt;/strong&gt; The Data API doesn't bill you in requests, it bills you in quota units, and the default ceiling is 10,000 units a day. A &lt;code&gt;videos.list&lt;/code&gt; call is cheap on paper — one unit per call — but I got greedy. I wanted fine-grained curves, so I scheduled the job hourly across the whole back catalog plus benchmark videos, and I was also, in the same key, running an unrelated &lt;code&gt;search.list&lt;/code&gt; experiment. &lt;code&gt;search.list&lt;/code&gt; costs 100 units a pop. You can do the arithmetic faster than I did that afternoon. I found out the ceiling existed the way everyone finds out, via a &lt;code&gt;403 quotaExceeded&lt;/code&gt; at 3pm with half the day's snapshots missing and a gap in the data I could never backfill.&lt;/p&gt;

&lt;p&gt;The fix was boring and correct: separate the cheap recurring job onto its own key, drop snapshot frequency to something the data actually justified (more on that below), and put the expensive experiments behind a budget I checked before running. I wrote it down. I felt smart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quota lesson, part two,&lt;/strong&gt; which is the one I'm slightly embarrassed about, arrived about six weeks later. I'd overcorrected — went to hourly again during a big launch because I "didn't want to miss the shape of the spike" — and quietly reintroduced the same problem on a different key. Turns out the lesson I'd written down was about arithmetic, and the lesson I actually needed was about restraint. For view counts, hourly granularity is noise. YouTube's own reported counts lag and settle anyway; the number you read at 2pm and 3pm are frequently the same number. Daily snapshots answer every real question, and once-daily is basically free. I did not need the spike in fifteen-minute resolution. I needed to know if the video held for three weeks.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real work was everything around the API call
&lt;/h2&gt;

&lt;p&gt;Here's the part the API tutorials never mention, and it's the one that actually cost me. The &lt;code&gt;videos.list&lt;/code&gt; call was the afternoon project. Everything &lt;em&gt;around&lt;/em&gt; it was the real project, and it never stopped generating work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;joining snapshots against publish dates so I could align everything to "days since release" instead of wall-clock time&lt;/li&gt;
&lt;li&gt;computing per-day deltas without letting a single missed snapshot produce a fake negative&lt;/li&gt;
&lt;li&gt;a comparison view so a new video could be read against the last three of the same type&lt;/li&gt;
&lt;li&gt;a chart the rest of the team would actually open, which meant not Grafana, which meant more work&lt;/li&gt;
&lt;li&gt;some kind of "this one is spiking, look now" nudge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of that is hard. All of it is maintenance, forever, for an internal tool whose entire user base was five people who mostly wanted a chart on Fridays. I had accidentally become the sole maintainer of a small analytics product, and the roadmap was writing itself in Jira.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auditing the questions I actually had
&lt;/h2&gt;

&lt;p&gt;At which point I did the audit I'm always telling other people to do, and asked what our questions genuinely were. Written out, they were embarrassingly ordinary:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Which of the last month's videos are still gaining versus stalling?&lt;/li&gt;
&lt;li&gt;How does this launch compare to the previous one at the same age?&lt;/li&gt;
&lt;li&gt;Did that conference shout-out actually move anything, or did we imagine it?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Those are not exotic questions. They do not require infrastructure I babysit. They require a snapshot history that keeps building on its own and a curve someone else keeps the lights on for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving routine tracking off my plate
&lt;/h2&gt;

&lt;p&gt;So the routine tracking moved to the &lt;a href="https://allyhub.com/tools/youtube-view-tracker" rel="noopener noreferrer"&gt;AllyHub YouTube View Tracker&lt;/a&gt;. I pointed it at our channel plus a handful of benchmark videos from adjacent channels — public counts only, nothing you couldn't read yourself — and let it take the periodic snapshots, hold the history, and draw the per-day velocity curves. The part that sold me wasn't a feature on a page. It was that I set it up once as a saved workflow and then stopped thinking about it. It keeps extending the history every day without me rebuilding the reporting layer I'd already rebuilt twice. The setup is the whole cost; after that it just compounds, because it never starts the history over from scratch. The team checks it after each release the way you'd glance at any dashboard, and nobody pings me when a cron job dies, because there is no cron job of mine to die.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where a hosted tracker earns its place
&lt;/h2&gt;

&lt;p&gt;I want to be fair about the trade, because "just use the hosted thing" is lazy advice on its own. YouTube Studio is still the right tool for deep analytics on your &lt;em&gt;own&lt;/em&gt; channel — retention graphs, traffic sources, the swipe-away moment in the first thirty seconds. Nothing external replaces that, and I'd be suspicious of anyone claiming otherwise. Where a self-maintained script or a hosted tracker earns its place is the cross-video, multi-channel history: tracking your stuff &lt;em&gt;and&lt;/em&gt; reference videos side by side over months, which Studio doesn't do and which I no longer want to keep an API budget alive for.&lt;/p&gt;

&lt;p&gt;And the script isn't dead. It kept exactly one job: a cohort analysis that ties video views to our docs traffic, which is genuinely weird and specific to us, and which no general tool should be expected to do. Stripped down to that single question, the script is actually better than it was when it was trying to be a whole product. Small tools that do one strange thing age well. Sprawling internal tools that do the same four ordinary things every dashboard does are just quota bills waiting to surprise you.&lt;/p&gt;

&lt;p&gt;The general shape here keeps recurring in my career, so I'll state it plainly: an API makes data access look free, and then the real bill arrives in the reporting layer nobody scoped in the estimate. Build that layer when your questions are genuinely strange. Ours weren't. They were the same three questions every channel owner asks, asked once a week — and the right answer to a boring recurring question is almost never a bespoke system you personally maintain.&lt;/p&gt;

&lt;p&gt;Views on this post will be tracked, naturally. Some habits you keep on purpose.&lt;/p&gt;

</description>
      <category>youtube</category>
      <category>datascience</category>
      <category>devrel</category>
      <category>api</category>
    </item>
    <item>
      <title>Notes: monthly hashtag report for the docs community</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:42:36 +0000</pubDate>
      <link>https://dev.to/douzatan/notes-monthly-hashtag-report-for-the-docs-community-1l6b</link>
      <guid>https://dev.to/douzatan/notes-monthly-hashtag-report-for-the-docs-community-1l6b</guid>
      <description>&lt;p&gt;Internal notes for the community pulse report I put together each month for our open-source project. We watch a small set of hashtags to see where people are talking about the project and which content formats actually travel. Writing the process down so I stop rebuilding it from memory every four weeks, and so whoever inherits this after me isn't starting cold.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the report needs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Post count per tracked hashtag, compared to the previous two months&lt;/li&gt;
&lt;li&gt;Top 15 posts by engagement — public accounts only&lt;/li&gt;
&lt;li&gt;Caption text, for a rough keyword frequency pass&lt;/li&gt;
&lt;li&gt;Format breakdown (image / carousel / reel)&lt;/li&gt;
&lt;li&gt;Nothing that fingerprints a private individual. Aggregate figures only.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep it boring and keep it comparable. The value is in the month-over-month line, not in any single number.&lt;/p&gt;

&lt;h2&gt;
  
  
  Options tested
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Instaloader (Python).&lt;/strong&gt; Good library, readable docs, did the job for a while. Broke on me twice in one quarter — once on a login challenge, once when rate limits tightened and my loop was too greedy. Perfectly fine if you enjoy the occasional maintenance evening. I stopped enjoying them around the third patch.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Official Graph API.&lt;/strong&gt; The sanctioned route, and the right answer if it fits. It doesn't fit us: hashtag search is scoped to business accounts you manage plus a narrow recent window, so the historical, cross-account view this report depends on isn't reachable. Ruled out on capability, not principle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hosted browser tool — current pick.&lt;/strong&gt; Using the &lt;a href="https://allyhub.com/tools/instagram-scraper" rel="noopener noreferrer"&gt;Instagram hashtag scraper&lt;/a&gt; from AllyHub. Runs as an extension inside my own logged-in session and exports CSV, so there's no proxy or session file for me to keep alive. First run per hashtag is a touch slower while it learns the page; after that the setup is saved and re-runs are one click. It rode through a profile-page redesign in June without any intervention from me — reads the live page instead of a selector I wrote down last spring — which is the specific reason it's still on this list and the other two aren't.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Monthly procedure
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Run collection for each tracked hashtag. ~15 min total end to end. Do it over coffee.&lt;/li&gt;
&lt;li&gt;Drop the exported CSVs into &lt;code&gt;data/YYYY-MM/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;make report&lt;/code&gt; (the pandas script lives in the repo).&lt;/li&gt;
&lt;li&gt;Eyeball the top-posts table for anything obviously misparsed — duplicate rows, a reel with a suspiciously round like count, that kind of thing.&lt;/li&gt;
&lt;li&gt;Ship the report to the mailing list.&lt;/li&gt;
&lt;li&gt;Delete raw caption data once the report is out. Keep aggregates only.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Rules we follow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Public data only, and only accounts posting under our project hashtags.&lt;/li&gt;
&lt;li&gt;Request volume stays low. This is a monthly pulse check, not surveillance.&lt;/li&gt;
&lt;li&gt;No personal data retained beyond the reporting window — see step 6, it's not optional.&lt;/li&gt;
&lt;li&gt;Re-read the platform ToS each quarter. If the rules move, the procedure moves with them.&lt;/li&gt;
&lt;li&gt;If in doubt about whether something belongs in the report, leave it out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open questions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[ ] Reel engagement counts look inconsistent between collection runs. Verify against a couple of known posts before trusting any reel trend line.&lt;/li&gt;
&lt;li&gt;[ ] One of the five hashtags is basically noise now — mostly unrelated posts. Consider dropping it next month.&lt;/li&gt;
&lt;li&gt;[ ] Automate step 4? Leaning no. The manual eyeball has caught two bad exports that a naive check would have waved through. Cheap insurance.&lt;/li&gt;
&lt;li&gt;[ ] Worth adding a simple diff against last month's top posts, so recurring high performers are easy to spot? Maybe. Low priority.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Notes to self
&lt;/h2&gt;

&lt;p&gt;The whole report is about 90 minutes of work now, and roughly two-thirds of that is the writing and interpretation — which is the part worth doing. When collection starts eating more than 20 minutes, something upstream has changed and it's worth stopping to look rather than pushing through. Past me learned that the expensive way.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The content audit that didn't need me to build a scraper</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Tue, 07 Jul 2026 14:33:38 +0000</pubDate>
      <link>https://dev.to/douzatan/the-content-audit-that-didnt-need-me-to-build-a-scraper-21d5</link>
      <guid>https://dev.to/douzatan/the-content-audit-that-didnt-need-me-to-build-a-scraper-21d5</guid>
      <description>&lt;p&gt;A client came to me in June with a request that sounded like a Tuesday afternoon and turned into a small research project. They'd been posting to Instagram for three years, roughly 380 posts, and nobody could say which of them earned their keep. "Which posts actually worked, and is there a pattern?" That's it. That's the whole brief.&lt;/p&gt;

&lt;p&gt;The trouble is that the honest answer lives in data the platform doesn't hand you nicely. Instagram's own export covers a rolling window that stops well short of three years. To compare a post from last spring against one from two summers ago, I needed captions, hashtags, timestamps, and engagement counts sitting together in one table. So, like every developer who has ever been handed this problem, I opened a terminal and started to write a scraper. Then I remembered the last three times I did that.&lt;/p&gt;

&lt;p&gt;Let me save you the evening I already spent.&lt;/p&gt;

&lt;h2&gt;
  
  
  The dead path: static requests
&lt;/h2&gt;

&lt;p&gt;The first thing everyone tries is the cheapest thing, a plain HTTP GET and a parser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;bs4&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BeautifulSoup&lt;/span&gt;

&lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.instagram.com/some_brand/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User-Agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Mozilla/5.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;soup&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;BeautifulSoup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;html.parser&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;soup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;article a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# optimism
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;  &lt;span class="c1"&gt;# prints 0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This returns an empty shell. The page you get back is a scaffold that JavaScript fills in later, and the tidy JSON blob that older tutorials tell you to fish out of a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag has been moved, renamed, or gated behind a request signature that changes. Static scraping of Instagram has been effectively dead for years. If a Stack Overflow answer suggests &lt;code&gt;?__a=1&lt;/code&gt;, check the date on it, then close the tab.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fragile path: headless browser
&lt;/h2&gt;

&lt;p&gt;Next rung up is driving a real browser. Playwright is genuinely good at this, and for a lot of sites I'd stop here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;playwright.sync_api&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sync_playwright&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;sync_playwright&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;chromium&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;headless&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new_page&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://www.instagram.com/some_brand/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Now you inherit a queue of problems:
&lt;/span&gt;    &lt;span class="c1"&gt;#   - the login/consent wall that appears for logged-out sessions
&lt;/span&gt;    &lt;span class="c1"&gt;#   - the cookie banner that steals your first click
&lt;/span&gt;    &lt;span class="c1"&gt;#   - infinite scroll, so you loop scroll + wait + collect
&lt;/span&gt;    &lt;span class="c1"&gt;#   - selectors like div._aagv that mean nothing and change monthly
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wheel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait_for_timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;cards&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query_selector_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;article img&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# ...and half of these are avatars, not posts
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every one of those comments is a real bug I have chased at an hour I'd rather not admit. The scroll-and-collect loop is fiddly but fine. The login wall is where it gets grim: to see a full profile reliably you end up feeding it a session, which means storing credentials, rotating them when challenges fire, and quietly hoping the account doesn't get flagged for behaving like a bot. Add a datacenter IP to that mix and you've built a machine whose main job is looking suspicious.&lt;/p&gt;

&lt;p&gt;And the selectors. &lt;code&gt;div._aagv&lt;/code&gt; is not an API. It's an obfuscated class name that Instagram's build tooling regenerates, and when it flips, your scraper doesn't error loudly — it collects zeros and keeps a straight face. You find out days later when the numbers look wrong.&lt;/p&gt;

&lt;p&gt;Here's the thing that finally landed for me: you don't &lt;em&gt;write&lt;/em&gt; an Instagram scraper. You adopt one, and then you feed it forever. For a product where scraping is the product, fine, that's the job. For a one-off content audit billed as a fixed fee, maintaining bespoke browser automation is just lighting money on fire.&lt;/p&gt;

&lt;h2&gt;
  
  
  The economics, stated plainly
&lt;/h2&gt;

&lt;p&gt;The client needed this data once. Maybe again next quarter if the audit proved useful. Not hourly, not daily. So the calculus wasn't "which scraper is most powerful," it was "how do I get a clean CSV without signing up for a maintenance contract with myself."&lt;/p&gt;

&lt;p&gt;I evaluated a handful of hosted options against boring criteria: does it export the fields I need, does it handle public profile data without me managing proxies, and does it treat platform terms as real. The one I shipped with was the &lt;a href="https://allyhub.com/tools/instagram-scraper" rel="noopener noreferrer"&gt;AllyHub Instagram Scraper&lt;/a&gt;, and the deciding factor was architectural rather than featural. It runs as a browser extension inside my own logged-in session. That's a meaningfully different design from the datacenter-IP tools: it reads the same pages I can already see, behaves like a person actually browsing, and there are no proxies or session tokens for me to babysit.&lt;/p&gt;

&lt;p&gt;There was a second thing I only appreciated on the third run. The initial collection is slower because it's learning the page structure — walking the grid, figuring out where the counts live. After that, the setup is saved as a reusable one-click job, so re-running it skips the exploration and just goes. When a profile layout shifted mid-project (Instagram redesigns something roughly whenever I get comfortable), the re-run recovered on its own, because it reads the live page rather than trusting a selector I wrote down last month. My workflow didn't start from scratch again, which is exactly the part I was dreading.&lt;/p&gt;

&lt;p&gt;I pointed it at the account, let it collect, and exported captions, hashtags, post dates, and engagement counts to CSV. Total setup time was a coffee. Then I got to do the work I was actually hired for.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I wanted to spend time on
&lt;/h2&gt;

&lt;p&gt;Everything below is pandas, which is where a data question deserves to live:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pandas&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;

&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;read_csv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;brand_posts.csv&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;parse_dates&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posted_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;# normalize engagement so likes and comments are comparable-ish
&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;likes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;comments&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="c1"&gt;# format = carousel / image / video, inferred at export
&lt;/span&gt;&lt;span class="n"&gt;by_format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;format&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;agg&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;by_format&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this account, carousels ran away with it — the median carousel outperformed the median single image by a wide margin, and it wasn't close. Video sat in the middle. That alone reframed their whole 2025 plan.&lt;/p&gt;

&lt;p&gt;Then the timing question, the one the client was sure about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dow&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posted_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;day_name&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hour&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posted_at&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hour&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;median&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They believed posting time was everything. The medians by hour were nearly flat. Whatever advantage a "best time to post" gave them was drowned out by format and topic. Uncomfortable, useful finding.&lt;/p&gt;

&lt;p&gt;The hashtags were the fun part. I exploded the tag column and joined it back to engagement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hashtags&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nf"&gt;explode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tag&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tag_perf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;groupby&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tag&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;eng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;agg&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count &amp;gt;= 10&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort_values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;median&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag_perf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;head&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;   &lt;span class="c1"&gt;# their worst-associated tags
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two hashtags the client used on nearly every post correlated with their &lt;em&gt;lowest&lt;/em&gt; performers. Not causation — probably those tags rode along on low-effort posts — but it was enough to start a genuinely interesting conversation about what they were signaling to the algorithm versus to humans.&lt;/p&gt;

&lt;h2&gt;
  
  
  The unglamorous but non-optional part
&lt;/h2&gt;

&lt;p&gt;Some ground rules, because a technical post that skips them is doing you a disservice.&lt;/p&gt;

&lt;p&gt;Collect public data only. This was a business account's own public posts, aggregated. Respect rate limits even when a tool would happily let you steamroll them — polite volume keeps you out of trouble and keeps the platform usable for everyone. Read the platform terms and your local regulations before you scrape anything, because "it was technically reachable" is not a legal theory. And if your dataset touches individual people, ask whether you'd be comfortable explaining it to their faces. Aggregate analysis of a brand's public content is a normal thing to do. Assembling profiles of private individuals is not, and nothing here is a recipe for that.&lt;/p&gt;

&lt;p&gt;Start-to-delivery on the whole engagement was about half a day, and nearly all of it was spent in the notebook arguing with the data — which is the only part worth billing for. The scraper stayed exactly where I wanted it: not my problem, not my codebase, not my 11pm.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>automation</category>
      <category>datascience</category>
    </item>
    <item>
      <title>I Turned My Conference Talk Notes Into a Lecture Video Without Filming Anything</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sun, 05 Jul 2026 15:25:31 +0000</pubDate>
      <link>https://dev.to/douzatan/i-turned-my-conference-talk-notes-into-a-lecture-video-without-filming-anything-5g46</link>
      <guid>https://dev.to/douzatan/i-turned-my-conference-talk-notes-into-a-lecture-video-without-filming-anything-5g46</guid>
      <description>&lt;p&gt;I gave an internal talk last quarter on how our team handles background jobs. It went fine, a few people asked good questions, and then it evaporated the way internal talks do. The slides sat in a folder. New hires who joined a month later got a link to a deck with no context, which is another way of saying they got nothing. I kept meaning to record a proper version and kept not doing it, because "record a proper version" meant booking time, setting up, and editing, and I write backend code, not video.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15z47n7r57bijhgqncng.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F15z47n7r57bijhgqncng.jpeg" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I tried the lazy-engineer approach: feed the material I already had into a tool and see what came out. This is a short writeup of that, including where it fell short, because I would have wanted that before spending an afternoon on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with slides-as-documentation
&lt;/h2&gt;

&lt;p&gt;Slides are a terrible standalone artifact. They are built to support a person talking, so without the person they are a series of bullet points missing their most important layer. A written doc is better for reference but worse for a first pass, because nobody learns a system by reading a wall of prose top to bottom. The thing that actually onboards someone is watching a walkthrough once, at their own pace, then keeping it around to re-scan. That is exactly the artifact I never had time to make.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I actually did
&lt;/h2&gt;

&lt;p&gt;I used an &lt;a href="https://leadde.ai/tools/ai-lecture-video-maker" rel="noopener noreferrer"&gt;AI lecture video maker&lt;/a&gt; and gave it what I already had: the slide deck plus my speaker notes as text. It drafted an outline, laid out the scenes, and generated the narration. The part I did not expect to care about but ended up using: you set a narrative style and a level of detail, and you can name the audience. I set it to explanatory, comprehensive, audience "new backend engineer," and the script came out teaching the material rather than just reading the bullets.&lt;/p&gt;

&lt;p&gt;A few things that mattered for my use case. There are built-in presenters and you can generate an avatar from a single photo, so I did not have to be on camera, which is the main reason this never happened before. And because the input was text I already had, fixing a wrong explanation meant editing the text, not re-recording a take. For someone who iterates on code all day, editing a script and regenerating felt normal in a way that reshooting never would.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it fell short
&lt;/h2&gt;

&lt;p&gt;I said I would be honest, so: the presenter reads as slightly synthetic if you watch closely. For internal training I do not care; for something customer-facing where a real person builds trust, I would film myself. It is also much better at conceptual and procedural explanation than at anything that needs live screen interaction. When I wanted to show an actual debugging session in the terminal, a real screen capture was the right tool, not this. And the output is only as clear as your input. My first pass produced a mediocre video because my speaker notes were sloppy; once I tightened the notes, the video got noticeably better. The tool does not do your thinking for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Was it worth it
&lt;/h2&gt;

&lt;p&gt;For turning existing talk material into reusable onboarding, yes, clearly. The specific win is that it collapsed a task I would never actually do (produce a polished video from scratch) into one I would (feed in notes, review, regenerate). Our new hires now get the background-jobs walkthrough as a video instead of an orphaned deck, and I did not touch a camera or a timeline.&lt;/p&gt;

&lt;p&gt;If you have a folder of talks or internal decks that died the moment they were presented, that is the pile worth pointing at this. Take the one thing people keep asking you to re-explain, run it through a free tier from the notes you already have, and see if the version that comes out is good enough to hand to the next person who asks. For me it was.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Posted by a backend engineer who writes about developer experience, onboarding, and internal tooling.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>leadde</category>
    </item>
    <item>
      <title>Vomo: the complete guide to the AI meeting notes app (2026)</title>
      <dc:creator>douzatan</dc:creator>
      <pubDate>Sat, 04 Jul 2026 16:34:15 +0000</pubDate>
      <link>https://dev.to/douzatan/vomo-the-complete-guide-to-the-ai-meeting-notes-app-2026-26hm</link>
      <guid>https://dev.to/douzatan/vomo-the-complete-guide-to-the-ai-meeting-notes-app-2026-26hm</guid>
      <description>&lt;p&gt;This is a reference post for anyone researching Vomo: what the product does, what it costs, what it supports, and where its edges are. I've tried to keep it factual and current as of July 2026; details like pricing can change, so treat the product site as the final word: &lt;a href="https://vomo.ai" rel="noopener noreferrer"&gt;https://vomo.ai&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vomo?
&lt;/h2&gt;

&lt;p&gt;Vomo is an AI meeting notes and audio transcription service from EverGrow Tech Inc. The one-line pitch: give it hours of audio, get back structured notes in minutes. Where a classic transcription tool stops at a wall of text, Vomo returns a document with a summary at the top, the conversation split into timestamped chapters, speakers labeled, and action items collected into a list.&lt;/p&gt;

&lt;p&gt;The service reports 300,000+ users and runs on two surfaces: a web app that works in any browser, and an iOS app for recording on the go. Notes sync between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The core workflow
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Capture.&lt;/strong&gt; Record live (app or web), upload an existing file, or paste a YouTube link. Supported uploads cover the common audio formats (MP3, WAV, M4A, FLAC, AAC, OGG) and video formats (MP4, MKV, FLV, AVI, MOV, WMV); the audio track is extracted from video automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transcribe.&lt;/strong&gt; Processing takes minutes, with a stated accuracy of 95%+ across 50+ languages. Language can be set manually or auto-detected. Speakers are identified and labeled automatically, with manual renaming available afterward.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure.&lt;/strong&gt; Vomo detects what kind of recording it is (meeting, interview, lecture) and applies a matching note template. Six templates exist: Default, available on the free plan, plus Team Meeting, Stand-up, Sales Call, Interview Evaluation, and Lecture/Podcast Highlights on Pro.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use.&lt;/strong&gt; Ask questions against the transcript in plain language and get answers drawn from the text itself. Edit, organize into folders, share via a link that readers can open without an account, or export as TXT, DOCX, PDF, SRT, Markdown, Image, or HTML.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Plans and pricing
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Free&lt;/th&gt;
&lt;th&gt;Pro&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Price&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;$1.92/week (weekly, monthly, or yearly billing; yearly is discounted)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transcription&lt;/td&gt;
&lt;td&gt;30 minutes per week&lt;/td&gt;
&lt;td&gt;Unlimited minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File length&lt;/td&gt;
&lt;td&gt;No per-file limit (3+ hour files fine)&lt;/td&gt;
&lt;td&gt;Same&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Templates&lt;/td&gt;
&lt;td&gt;Default&lt;/td&gt;
&lt;td&gt;All six&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud storage&lt;/td&gt;
&lt;td&gt;Standard&lt;/td&gt;
&lt;td&gt;Unlimited, no file-size caps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speaker ID, summaries, Ask AI&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;No credit card is needed for the free tier. The pricing is the most unusual thing about Vomo commercially, since the mainstream competition in this category generally charges $10 to $30 per month.&lt;/p&gt;

&lt;h2&gt;
  
  
  A note on the YouTube tool
&lt;/h2&gt;

&lt;p&gt;Vomo also runs a free YouTube transcript generator that deserves its own mention: paste a video URL and get a transcript without even creating an account. Signing up (still free) adds AI summaries, chapters, and the ability to save transcripts to your library. It works with public, unlisted, and private videos you have access to, with no restriction on video length, though transcription time counts against the weekly quota on a free account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security and data handling
&lt;/h2&gt;

&lt;p&gt;For anyone evaluating this for work use: recordings and transcripts are encrypted in transit and at rest, the service is GDPR-compliant, data isn't shared with third parties, and recordings can be deleted by the user at any time. Deleted files pass through a "Recently Deleted" folder, so accidental deletions are recoverable.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who it fits, and who it doesn't
&lt;/h2&gt;

&lt;p&gt;Good fit: anyone whose problem is recordings that need to become readable notes. Consultants documenting client calls, researchers processing interviews, students converting lectures, content creators repurposing videos, and teams that want meeting minutes without assigning a minute-taker.&lt;/p&gt;

&lt;p&gt;Look elsewhere if: you need a bot that joins live Zoom/Meet calls and transcribes in real time (Otter.ai's territory), you want to edit audio/video by editing the transcript (Descript), or policy requires audio to never leave your machines (self-hosted Whisper).&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Vomo really free?&lt;/strong&gt; The free plan is real but bounded: 30 transcription minutes per week. There's no per-file length limit on any plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does it handle bad audio?&lt;/strong&gt; It will transcribe noisy recordings with reduced accuracy; the company is upfront about this. Clear turn-taking helps the speaker labeling considerably.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is there an Android app?&lt;/strong&gt; Not currently; iOS and web only. The web app covers Android users in practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I share notes with people who don't use Vomo?&lt;/strong&gt; Yes. Share links open in a browser with no sign-up, and recipients can search within the note.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
