<?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: aco dog</title>
    <description>The latest articles on DEV Community by aco dog (@aco_dog_32627df9d920ffba4).</description>
    <link>https://dev.to/aco_dog_32627df9d920ffba4</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%2F4082375%2F071b44cc-99d5-465f-9b71-451bb7eecb59.png</url>
      <title>DEV Community: aco dog</title>
      <link>https://dev.to/aco_dog_32627df9d920ffba4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aco_dog_32627df9d920ffba4"/>
    <language>en</language>
    <item>
      <title>I ran a GPU inference app for a month on Azure serverless GPU. Here's the actual bill.</title>
      <dc:creator>aco dog</dc:creator>
      <pubDate>Tue, 18 Aug 2026 01:44:28 +0000</pubDate>
      <link>https://dev.to/aco_dog_32627df9d920ffba4/i-ran-a-gpu-inference-app-for-a-month-on-azure-serverless-gpu-heres-the-actual-bill-i35</link>
      <guid>https://dev.to/aco_dog_32627df9d920ffba4/i-ran-a-gpu-inference-app-for-a-month-on-azure-serverless-gpu-heres-the-actual-bill-i35</guid>
      <description>&lt;p&gt;I run a small internal speech-synthesis service on an NVIDIA T4 via Azure Container Apps' serverless GPU, with &lt;code&gt;min-replicas=0&lt;/code&gt;. The pitch is that you pay nothing while nobody's using it.&lt;/p&gt;

&lt;p&gt;I wanted to know if that's actually true, so I pulled the real numbers out of Azure Cost Management, scoped to just that resource group.&lt;/p&gt;

&lt;p&gt;Short answer: &lt;strong&gt;yes, it's true.&lt;/strong&gt; But the biggest line item on my bill wasn't the GPU.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[browser] → [Container App (T4, min=0 → max=1)]
               ├─ web UI      (FastAPI + uvicorn, :8000)
               └─ inference   (:9880)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Idle for ~5 minutes and it scales to zero replicas. Next request wakes it back up. Cold start is about 5 minutes in my case — a CUDA base image plus loading model weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  The actual numbers
&lt;/h2&gt;

&lt;p&gt;Measured over 48 days, scoped to one resource group. (Billed in JPY; USD figures are approximate.)&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Per month&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Container Apps (GPU)&lt;/td&gt;
&lt;td&gt;$2–7&lt;/td&gt;
&lt;td&gt;Only charged on days I used it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container Registry&lt;/td&gt;
&lt;td&gt;~$11&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Fixed cost. The biggest line item.&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log Analytics&lt;/td&gt;
&lt;td&gt;$0&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Total: &lt;strong&gt;around $13/month&lt;/strong&gt;, including the month where I was actively building and testing.&lt;/p&gt;

&lt;h3&gt;
  
  
  "You only pay when you use it" is literal
&lt;/h3&gt;

&lt;p&gt;Here's the daily distribution. Out of 48 days, &lt;strong&gt;GPU charges appeared on only 12&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Charge that day&lt;/th&gt;
&lt;th&gt;Days&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;$0 (unused)&lt;/td&gt;
&lt;td&gt;36&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$0.01–0.20&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$0.20–0.80&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;~$1.05&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$2.30&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A day of real use costs somewhere between four cents and a dollar. An always-on T4 VM of comparable spec runs a few hundred dollars a month. That's close to two orders of magnitude.&lt;/p&gt;

&lt;p&gt;The tradeoff is the cold start. For an internal tool where people know to expect a few minutes on first use, that's an easy trade. For a customer-facing endpoint, it isn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  The $2.30 day was me forgetting to scale back down
&lt;/h3&gt;

&lt;p&gt;That one outlier day has a boring explanation. I deployed a new image and temporarily forced the app to stay up so I could read the startup logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# force it up to inspect logs&lt;/span&gt;
az containerapp update &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$APP&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$RG&lt;/span&gt; &lt;span class="nt"&gt;--image&lt;/span&gt; &lt;span class="nv"&gt;$ACR&lt;/span&gt;.azurecr.io/my-app:2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--min-replicas&lt;/span&gt; 1 &lt;span class="nt"&gt;--max-replicas&lt;/span&gt; 1

&lt;span class="c"&gt;# ...and this is the line people forget&lt;/span&gt;
az containerapp update &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$APP&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$RG&lt;/span&gt; &lt;span class="nt"&gt;--min-replicas&lt;/span&gt; 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In a min=0 setup, the expensive mistake is never the GPU's hourly rate. It's leaving &lt;code&gt;min-replicas 1&lt;/code&gt; on after a debugging session. Put the scale-back-down step in your deploy checklist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Checking whether you're being billed right now
&lt;/h3&gt;

&lt;p&gt;The Azure portal showing &lt;strong&gt;"Status: Running"&lt;/strong&gt; means &lt;em&gt;the app exists&lt;/em&gt;, not that a replica is up. That confused me early on. The CLI tells the truth:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# empty output = no replicas = not being billed&lt;/span&gt;
az containerapp replica list &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$APP&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$RG&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; table

&lt;span class="c"&gt;# ScaledToZero or Running&lt;/span&gt;
az containerapp revision list &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$APP&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$RG&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"[?properties.active].properties.runningState"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; tsv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The actual surprise: the registry cost more than the GPU
&lt;/h2&gt;

&lt;p&gt;Container Registry was ~$11/month against the GPU's $2–7. Two reasons compounding:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The images are huge.&lt;/strong&gt; A CUDA base image plus bundled model weights runs several tens of GB per image. I bundle the weights deliberately — downloading them at startup would add minutes to an already slow cold start.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Old images never leave.&lt;/strong&gt; I tag every deploy (&lt;code&gt;my-app:1&lt;/code&gt;, &lt;code&gt;:2&lt;/code&gt;, &lt;code&gt;:3&lt;/code&gt;…), and nothing removes the old ones. Storage billing is on the total, so the bill creeps up with every deploy.&lt;/p&gt;

&lt;p&gt;The fix is housekeeping. Keep what's deployed plus one for rollback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# what's actually running&lt;/span&gt;
az containerapp show &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$APP&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$RG&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s2"&gt;"properties.template.containers[0].image"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; tsv

&lt;span class="c"&gt;# tags, newest first&lt;/span&gt;
az acr repository show-tags &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$ACR&lt;/span&gt; &lt;span class="nt"&gt;--repository&lt;/span&gt; my-app &lt;span class="nt"&gt;--orderby&lt;/span&gt; time_desc &lt;span class="nt"&gt;-o&lt;/span&gt; tsv

&lt;span class="c"&gt;# drop the old ones&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;t &lt;span class="k"&gt;in &lt;/span&gt;1 2 3 4 5 6 7 8&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;az acr repository delete &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nv"&gt;$ACR&lt;/span&gt; &lt;span class="nt"&gt;--image&lt;/span&gt; my-app:&lt;span class="nv"&gt;$t&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I went from 10 images down to 2. Storage billing catches up over a few hours, via the registry's garbage collection.&lt;/p&gt;

&lt;p&gt;If you're evaluating serverless GPU, budget for registry storage. It's the line item nobody warns you about, and for a low-traffic workload it can quietly become your largest one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell someone starting out
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zero idle cost is real. A day of use costs cents, not dollars.&lt;/li&gt;
&lt;li&gt;It gets better the &lt;em&gt;less&lt;/em&gt; you use it. Bursty, low-frequency workloads are the sweet spot.&lt;/li&gt;
&lt;li&gt;Cold start (~5 min for a big CUDA image) decides whether this fits your use case. Be honest about that up front.&lt;/li&gt;
&lt;li&gt;Your worst cost accident will be forgetting &lt;code&gt;--min-replicas 0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Watch registry storage, not just GPU seconds.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Getting from zero to a working deployment took considerably longer than it should have. Pinning &lt;code&gt;torch&lt;/code&gt; against &lt;code&gt;transformers&lt;/code&gt;' requirements, a 504 caused by the order services start in, and — on Windows — &lt;code&gt;az acr build&lt;/code&gt; crashing the CLI on a character encoding issue mid-build. None of that is in the docs.&lt;/p&gt;

&lt;p&gt;I wrote all of it up, including the full deployment walkthrough, here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://leanpub.com/zero-idle-gpu" rel="noopener noreferrer"&gt;Zero-Idle GPU: Running Inference on Azure Container Apps&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Happy to answer questions in the comments.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>gpu</category>
      <category>cloud</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
