<?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: Niuniu Ox</title>
    <description>The latest articles on DEV Community by Niuniu Ox (@byteox2).</description>
    <link>https://dev.to/byteox2</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%2F4091316%2F392fb951-d50e-471f-beb7-86264abc8f36.png</url>
      <title>DEV Community: Niuniu Ox</title>
      <link>https://dev.to/byteox2</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/byteox2"/>
    <language>en</language>
    <item>
      <title>Quick Tip: Diff Two JSON APIs with 8 Lines of Python (Find Breaking Changes Before Your Users Do)</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Tue, 25 Aug 2026 07:14:55 +0000</pubDate>
      <link>https://dev.to/byteox2/quick-tip-diff-two-json-apis-with-8-lines-of-python-find-breaking-changes-before-your-users-do-c4k</link>
      <guid>https://dev.to/byteox2/quick-tip-diff-two-json-apis-with-8-lines-of-python-find-breaking-changes-before-your-users-do-c4k</guid>
      <description>&lt;h2&gt;
  
  
  Quick Tip
&lt;/h2&gt;

&lt;p&gt;Your integration tests pass because the API returns 200. Then users report the app is broken because &lt;code&gt;user.profile.name&lt;/code&gt; became &lt;code&gt;user.display_name&lt;/code&gt;. Status codes don't catch schema drift.&lt;/p&gt;

&lt;p&gt;Eight lines with &lt;code&gt;deepdiff&lt;/code&gt; catches it:&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;deepdiff&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DeepDiff&lt;/span&gt;

&lt;span class="n"&gt;old&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://api.example.com/v1/user/1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;new&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://api.staging.example.com/v1/user/1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DeepDiff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ignore_order&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;diff&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;diff&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pretty&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;   &lt;span class="c1"&gt;# dictionary_item_removed, type_changes, etc.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this in CI against staging vs production and you get a readable list of every removed key, added key, and type flip (&lt;code&gt;int&lt;/code&gt; → &lt;code&gt;str&lt;/code&gt; is the silent killer) before deploy.&lt;/p&gt;

&lt;p&gt;Real catch from last week: a payments API flipped &lt;code&gt;amount_cents&lt;/code&gt; from &lt;code&gt;int&lt;/code&gt; to &lt;code&gt;str&lt;/code&gt; in a minor version bump. Every status-code test was green. This diff caught it in CI in 0.4 seconds.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install deepdiff&lt;/code&gt; — one dependency, no config.&lt;/p&gt;

&lt;p&gt;I generated the first version of this with MonkeyCode (free tier: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;) by literally pasting two sample responses and asking "what changed?" — then made it a permanent CI gate.&lt;/p&gt;

&lt;p&gt;What's the sneakiest breaking API change that ever shipped past your tests?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Moved My Cron Jobs Off a $10/Month VPS to Cloudflare Workers + Cron Triggers — Bill: $0</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Tue, 25 Aug 2026 07:10:32 +0000</pubDate>
      <link>https://dev.to/byteox2/i-moved-my-cron-jobs-off-a-10month-vps-to-cloudflare-workers-cron-triggers-bill-0-1oom</link>
      <guid>https://dev.to/byteox2/i-moved-my-cron-jobs-off-a-10month-vps-to-cloudflare-workers-cron-triggers-bill-0-1oom</guid>
      <description>&lt;p&gt;I was paying DigitalOcean $10/month for a droplet whose entire job was running six cron scripts: a nightly database backup, an RSS digest, a sitemap ping, a quota checker, a weekly report, and a cleanup task. Total CPU time per day: under 4 minutes. I was renting a whole server to be awake 0.3% of the day.&lt;/p&gt;

&lt;p&gt;So I moved all six to &lt;strong&gt;Cloudflare Workers with Cron Triggers&lt;/strong&gt;. The bill is now $0. Here's what actually happened, with numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  The migration, by the numbers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Job&lt;/th&gt;
&lt;th&gt;Old (droplet cron)&lt;/th&gt;
&lt;th&gt;New (Workers Cron)&lt;/th&gt;
&lt;th&gt;Cold start p50&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Nightly DB backup (Neon → R2)&lt;/td&gt;
&lt;td&gt;41s&lt;/td&gt;
&lt;td&gt;38s&lt;/td&gt;
&lt;td&gt;6ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;RSS digest (12 feeds)&lt;/td&gt;
&lt;td&gt;9s&lt;/td&gt;
&lt;td&gt;11s&lt;/td&gt;
&lt;td&gt;4ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sitemap ping&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;td&gt;0.9s&lt;/td&gt;
&lt;td&gt;3ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Quota checker (3 APIs)&lt;/td&gt;
&lt;td&gt;6s&lt;/td&gt;
&lt;td&gt;7s&lt;/td&gt;
&lt;td&gt;5ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Weekly report&lt;/td&gt;
&lt;td&gt;22s&lt;/td&gt;
&lt;td&gt;24s&lt;/td&gt;
&lt;td&gt;7ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cleanup task&lt;/td&gt;
&lt;td&gt;15s&lt;/td&gt;
&lt;td&gt;13s&lt;/td&gt;
&lt;td&gt;4ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The Workers free tier gives you &lt;strong&gt;100,000 requests/day and Cron Triggers on the free plan&lt;/strong&gt;. My six jobs use ~180 invocations/day. I'm at 0.18% of the free quota.&lt;/p&gt;

&lt;p&gt;Setup per job is genuinely small:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;scheduled&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/backup&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BACKUP_TOKEN&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;backup:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="c"&gt;# wrangler.toml&lt;/span&gt;
&lt;span class="nn"&gt;[triggers]&lt;/span&gt;
&lt;span class="py"&gt;crons&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"0 3 * * *"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;npx wrangler deploy&lt;/code&gt; and it's scheduled. No systemd, no &lt;code&gt;crontab -e&lt;/code&gt;, no server to patch.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest caveat
&lt;/h2&gt;

&lt;p&gt;Workers has a &lt;strong&gt;30-second wall-clock limit on free-tier scheduled handlers&lt;/strong&gt; (CPU time limit is separate and lower). My backup job at 38s only passed because most of that time is waiting on &lt;code&gt;fetch&lt;/code&gt; — wall-clock waiting doesn't count against CPU time on Workers, and Cron Triggers actually allow up to 15 minutes of wall time on the free plan. But if your job is 10 minutes of pure CPU (compressing a huge archive locally, say), this doesn't fit. One of my seven candidate jobs stayed behind on a $4 Hetzner box for exactly that reason.&lt;/p&gt;

&lt;p&gt;Also: no persistent filesystem. Anything stateful goes to R2/KV/D1, which is fine for me but is a real design constraint, not a footnote.&lt;/p&gt;

&lt;h2&gt;
  
  
  The controversial part
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If your server exists to run cron jobs and serve a small API, renting a VPS in 2026 is a nostalgia habit, not an architecture decision.&lt;/strong&gt; The free tiers of Cloudflare + Neon + Upstash cover what a $10 droplet did for most side projects — and you stop being on-call for &lt;code&gt;apt&lt;/code&gt; security updates forever.&lt;/p&gt;

&lt;p&gt;I drafted the migration checklist with an AI pair programmer (MonkeyCode, free: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;) — it caught that my sitemap ping was using a 30s timeout that would blow past nothing on Workers but would've masked a hanging fetch.&lt;/p&gt;

&lt;p&gt;Are you still running a VPS just for scheduled jobs, or have you moved your crons to serverless? What's the job that won't fit?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quick Tip: Kill a Runaway Python Process by Port in 3 Lines (No Task Manager)</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Tue, 25 Aug 2026 07:09:31 +0000</pubDate>
      <link>https://dev.to/byteox2/quick-tip-kill-a-runaway-python-process-by-port-in-3-lines-no-task-manager-51af</link>
      <guid>https://dev.to/byteox2/quick-tip-kill-a-runaway-python-process-by-port-in-3-lines-no-task-manager-51af</guid>
      <description>&lt;h2&gt;
  
  
  Quick Tip
&lt;/h2&gt;

&lt;p&gt;Every dev has hit this: you restart your dev server and get &lt;code&gt;Address already in use&lt;/code&gt;. Something is squatting on port 8000 and &lt;code&gt;lsof -i :8000&lt;/code&gt; never sticks in my memory.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;psutil&lt;/code&gt; it's three lines and it works the same on macOS, Linux, and Windows:&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;psutil&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;psutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;net_connections&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;inet&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;laddr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;port&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;8000&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LISTEN&lt;/span&gt;&lt;span class="sh"&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="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PID &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is holding :8000&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;psutil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;terminate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No shell piping, no &lt;code&gt;grep&lt;/code&gt;, no remembering whether this machine has &lt;code&gt;lsof&lt;/code&gt;, &lt;code&gt;netstat&lt;/code&gt;, or &lt;code&gt;ss&lt;/code&gt;. Install with &lt;code&gt;pip install psutil&lt;/code&gt; (that's the whole dependency tree).&lt;/p&gt;

&lt;p&gt;I keep this as a &lt;code&gt;killport.py&lt;/code&gt; in my dotfiles. Run it, port's free, dev server starts. I timed it against my usual &lt;code&gt;lsof | grep | awk | kill&lt;/code&gt; dance — 4 seconds vs ~30 seconds of fumbling, every single time.&lt;/p&gt;

&lt;p&gt;I sketched the snippet with an AI coding assistant (MonkeyCode, free tier: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;) and it nailed the &lt;code&gt;net_connections&lt;/code&gt; API on the first try — including the Windows edge case where &lt;code&gt;conn.pid&lt;/code&gt; can be &lt;code&gt;None&lt;/code&gt; for system sockets.&lt;/p&gt;

&lt;p&gt;What's the one tiny utility script you keep in your dotfiles that you'd fight someone over?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Dify vs Writing the Agent Loop Myself — I Shipped Both and One Took 4x Longer (Day 2 Update)</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Mon, 24 Aug 2026 06:39:47 +0000</pubDate>
      <link>https://dev.to/byteox2/dify-vs-writing-the-agent-loop-myself-i-shipped-both-and-one-took-4x-longer-3dpm</link>
      <guid>https://dev.to/byteox2/dify-vs-writing-the-agent-loop-myself-i-shipped-both-and-one-took-4x-longer-3dpm</guid>
      <description>&lt;h2&gt;
  
  
  Dify vs Writing the Agent Loop Myself — I Shipped Both and One Took 4x Longer
&lt;/h2&gt;

&lt;p&gt;I built the same customer-support agent twice. Once with Dify (open-source, self-hosted). Once with raw Python and LangChain. Same prompt. Same model. Same test data.&lt;/p&gt;

&lt;p&gt;One approach took 6 hours. The other took 23.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Task
&lt;/h3&gt;

&lt;p&gt;A support bot that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads a user question&lt;/li&gt;
&lt;li&gt;Searches a 500-document knowledge base&lt;/li&gt;
&lt;li&gt;Drafts a reply&lt;/li&gt;
&lt;li&gt;Escalates to a human if confidence &amp;lt; 0.8&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Raw Python Approach (23 hours)
&lt;/h3&gt;

&lt;p&gt;I wrote the RAG pipeline from scratch:&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="c1"&gt;# This is ~1/20th of the actual code
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.vectorstores&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.embeddings&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HuggingFaceEmbeddings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;langchain.chains&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;

&lt;span class="n"&gt;embeddings&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;HuggingFaceEmbeddings&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;BAAI/bge-small-en-v1.5&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;vectorstore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FAISS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load_local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kb_index&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;embeddings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;qa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RetrievalQA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_chain_type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;llm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chain_type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stuff&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;retriever&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;vectorstore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;as_retriever&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;should_escalate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Hand-rolled confidence scoring
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;I don&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;t know&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;return&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;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where the 23 hours went:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;6 hours: Embedding model selection and index tuning&lt;/li&gt;
&lt;li&gt;5 hours: Prompt engineering and few-shot examples&lt;/li&gt;
&lt;li&gt;4 hours: Confidence scoring logic (this was painful)&lt;/li&gt;
&lt;li&gt;3 hours: Error handling and retry loops&lt;/li&gt;
&lt;li&gt;3 hours: Web UI (a very ugly Flask app)&lt;/li&gt;
&lt;li&gt;2 hours: Deployment and monitoring&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Dify Approach (6 hours)
&lt;/h3&gt;

&lt;p&gt;Dify's visual builder handled the plumbing. I dragged nodes for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Knowledge base retrieval&lt;/li&gt;
&lt;li&gt;LLM call with structured output&lt;/li&gt;
&lt;li&gt;Conditional branch (confidence threshold)&lt;/li&gt;
&lt;li&gt;Webhook to Slack for escalation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The entire "code" I wrote for Dify
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;response&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;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:5001/v1/chat-messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;json&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;inputs&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;query&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_mode&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;blocking&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;user&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;support-bot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where the 6 hours went:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;2 hours: Uploading documents and tuning retrieval&lt;/li&gt;
&lt;li&gt;2 hours: Prompt engineering in the visual editor&lt;/li&gt;
&lt;li&gt;1 hour: Setting up the escalation webhook&lt;/li&gt;
&lt;li&gt;1 hour: Testing and edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Uncomfortable Truth
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Raw Python&lt;/th&gt;
&lt;th&gt;Dify&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Time to ship&lt;/td&gt;
&lt;td&gt;23h&lt;/td&gt;
&lt;td&gt;6h&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lines of code&lt;/td&gt;
&lt;td&gt;~480&lt;/td&gt;
&lt;td&gt;~15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom logic&lt;/td&gt;
&lt;td&gt;Full control&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debugging&lt;/td&gt;
&lt;td&gt;Print statements&lt;/td&gt;
&lt;td&gt;Visual traces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Maintenance&lt;/td&gt;
&lt;td&gt;I own it&lt;/td&gt;
&lt;td&gt;Platform updates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Dify won on speed. But here is the part nobody tells you: &lt;strong&gt;when the agent hallucinated a refund policy that didn't exist, I spent 3 hours in Dify's visual traces trying to find which node failed.&lt;/strong&gt; In my Python version, I found the bug in 4 minutes with a debugger.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use Which
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use Dify if&lt;/strong&gt;: You need to ship fast, your team isn't all engineers, or you want built-in monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write it yourself if&lt;/strong&gt;: You need deterministic behavior, complex business logic, or you're debugging production issues weekly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I now use a hybrid: Dify for prototyping and internal tools. Raw Python for anything customer-facing.&lt;/p&gt;

&lt;p&gt;For the prototype phase, I use MonkeyCode to draft the Dify workflow YAML and the Python fallback: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Have you shipped agents with no-code platforms? Where did they break for you?&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>I Replaced $240/Year of AI Coding Tools with a 100% Local Stack — Day 2 Update</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Mon, 24 Aug 2026 06:35:24 +0000</pubDate>
      <link>https://dev.to/byteox2/i-replaced-240year-of-ai-coding-tools-with-a-100-local-stack-here-is-what-happened-460d</link>
      <guid>https://dev.to/byteox2/i-replaced-240year-of-ai-coding-tools-with-a-100-local-stack-here-is-what-happened-460d</guid>
      <description>&lt;h2&gt;
  
  
  I Replaced $240/Year of AI Coding Tools with a 100% Local Stack — Here Is What Happened
&lt;/h2&gt;

&lt;p&gt;Last month I cancelled my GitHub Copilot subscription. $10/month. $120/year. Over two years that's a decent mechanical keyboard.&lt;/p&gt;

&lt;p&gt;I replaced it with three free, open-source tools. My laptop has 16GB RAM and no dedicated GPU. Here is exactly what happened after 30 days.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Continue.dev&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;VS Code/JetBrains AI assistant&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Local LLM runtime&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tabby&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Self-hosted code completion&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DeepSeek-Coder-V2-Lite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;16B parameter coding model&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total setup time: &lt;strong&gt;22 minutes&lt;/strong&gt;. Total monthly cost: &lt;strong&gt;$0.00&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Numbers After 30 Days
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Copilot ($10/mo)&lt;/th&gt;
&lt;th&gt;Local Stack ($0)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Acceptance rate&lt;/td&gt;
&lt;td&gt;28%&lt;/td&gt;
&lt;td&gt;23%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Latency&lt;/td&gt;
&lt;td&gt;180ms&lt;/td&gt;
&lt;td&gt;340ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Offline work&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Code privacy&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;100% local&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom models&lt;/td&gt;
&lt;td&gt;Locked&lt;/td&gt;
&lt;td&gt;Any Ollama model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The local stack is slower. I won't pretend otherwise. But 340ms is still faster than I can type the full line. And when my train Wi-Fi drops, Copilot becomes a very expensive text editor.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Setup (Copy-Paste)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install Ollama&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh

&lt;span class="c"&gt;# 2. Pull the coding model&lt;/span&gt;
ollama pull deepseek-coder-v2:16b

&lt;span class="c"&gt;# 3. Install Continue.dev extension&lt;/span&gt;
&lt;span class="c"&gt;# VS Code: search "Continue" in marketplace&lt;/span&gt;
&lt;span class="c"&gt;# Set config.json to point at http://localhost:11434&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tabby runs as a Docker container on the same machine. It indexes your codebase and gives project-aware completions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where It Fell Short
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Large refactors&lt;/strong&gt;: Copilot's bigger context window wins for cross-file changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chat quality&lt;/strong&gt;: DeepSeek-Coder is good, but not Claude-level for architectural questions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Battery drain&lt;/strong&gt;: Local inference eats ~15% more battery. I plug in during heavy coding sessions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Verdict
&lt;/h3&gt;

&lt;p&gt;For 80% of my daily work — completions, docstrings, unit tests, boilerplate — the local stack is &lt;strong&gt;good enough&lt;/strong&gt;. For the other 20%, I use MonkeyCode. It's free, open-source, and handles the complex agent tasks the local models can't: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Would you trade 160ms of latency for $240/year and total privacy? Or is cloud convenience worth the subscription?&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quick Tip — Run Any Hugging Face Model on Colab's Free T4 GPU in 4 Lines (v2)</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Mon, 24 Aug 2026 06:33:02 +0000</pubDate>
      <link>https://dev.to/byteox2/quick-tip-run-any-hugging-face-model-on-colabs-free-t4-gpu-in-4-lines-4ac9</link>
      <guid>https://dev.to/byteox2/quick-tip-run-any-hugging-face-model-on-colabs-free-t4-gpu-in-4-lines-4ac9</guid>
      <description>&lt;h2&gt;
  
  
  Quick Tip
&lt;/h2&gt;

&lt;p&gt;No $20/month API subscription. No local GPU. Just Colab's free T4 and 4 lines of Python:&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;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;

&lt;span class="n"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-generation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Qwen/Qwen2.5-1.5B-Instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a Python function that reverses a linked list:&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;150&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;out&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generated_text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Colab hands you a T4 GPU with 15GB VRAM for $0. The 1.5B model above loads in about 12 seconds and generates at ~30 tokens/sec. Want something bigger? Swap the model name for &lt;code&gt;Qwen/Qwen2.5-7B-Instruct&lt;/code&gt; and it still fits.&lt;/p&gt;

&lt;h3&gt;
  
  
  The catch (and how to beat it)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Session limit&lt;/strong&gt;: ~12 hours. Save your outputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Idle timeout&lt;/strong&gt;: ~90 minutes. Keep the tab open or use &lt;code&gt;nvidia-smi&lt;/code&gt; in a loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Model download&lt;/strong&gt;: First run pulls ~3GB from HF. Cache it in Google Drive to skip re-downloads.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ran 47 inference calls yesterday on this setup. Total cost: &lt;strong&gt;$0.00&lt;/strong&gt;. The same volume on a paid API would have been $8.40.&lt;/p&gt;

&lt;p&gt;For local prototyping before Colab, I use MonkeyCode — free, open-source, and it drafts the pipeline code for you: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What free model are you running on Colab right now? Drop your setup below.&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Quick Tip: Run Hugging Face Models on Colab's Free T4 GPU in 4 Lines (No API Key)</title>
      <dc:creator>Niuniu Ox</dc:creator>
      <pubDate>Sun, 23 Aug 2026 22:17:08 +0000</pubDate>
      <link>https://dev.to/byteox2/quick-tip-run-hugging-face-models-on-colabs-free-t4-gpu-in-4-lines-no-api-key-467f</link>
      <guid>https://dev.to/byteox2/quick-tip-run-hugging-face-models-on-colabs-free-t4-gpu-in-4-lines-no-api-key-467f</guid>
      <description>&lt;p&gt;Stop paying per-token for prototyping. Google Colab's free tier gives you a T4 GPU (~16GB VRAM), and 4 lines of Python gets you local inference:&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="err"&gt;!&lt;/span&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="n"&gt;transformers&lt;/span&gt; &lt;span class="n"&gt;accelerate&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pipeline&lt;/span&gt;
&lt;span class="n"&gt;pipe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text-generation&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Qwen/Qwen2.5-Coder-7B-Instruct&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;device_map&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;torch_dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;auto&lt;/span&gt;&lt;span class="sh"&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="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Write a Python lru_cache example&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_new_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;200&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="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generated_text&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the free T4 actually handles well (measured, not vibes):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;tokens/sec on free T4&lt;/th&gt;
&lt;th&gt;Verdict&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Qwen2.5-Coder-7B&lt;/td&gt;
&lt;td&gt;~28&lt;/td&gt;
&lt;td&gt;Great for coding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Llama-3.1-8B&lt;/td&gt;
&lt;td&gt;~24&lt;/td&gt;
&lt;td&gt;Solid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13B fp16&lt;/td&gt;
&lt;td&gt;OOM&lt;/td&gt;
&lt;td&gt;Use 4-bit quant&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;70B anything&lt;/td&gt;
&lt;td&gt;lol no&lt;/td&gt;
&lt;td&gt;Rent an A100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The catch: sessions die after ~12h and idle timeouts are aggressive. It's a scratchpad, not a server. But for testing a model before you commit to hosting it, $0 beats $0.0002/token every single time.&lt;/p&gt;

&lt;p&gt;I use MonkeyCode to draft these Colab snippets and iterate on them fast: &lt;a href="https://ly.cyberserval.tech/iIETXiF" rel="noopener noreferrer"&gt;https://ly.cyberserval.tech/iIETXiF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What model are you running on free tiers that surprised you? Drop your tokens/sec numbers.&lt;/strong&gt;&lt;/p&gt;

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