<?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: Ricardo Ghekiere (runflow)</title>
    <description>The latest articles on DEV Community by Ricardo Ghekiere (runflow) (@ricardoghekiere).</description>
    <link>https://dev.to/ricardoghekiere</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%2F3875571%2F789bb090-d1fb-403a-9a9a-eec0f7eb33dd.jpeg</url>
      <title>DEV Community: Ricardo Ghekiere (runflow)</title>
      <link>https://dev.to/ricardoghekiere</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ricardoghekiere"/>
    <language>en</language>
    <item>
      <title>ComfyUI Deploy: Choosing Between Self-Host, Serverless, and Managed (2026)</title>
      <dc:creator>Ricardo Ghekiere (runflow)</dc:creator>
      <pubDate>Fri, 19 Jun 2026 10:34:34 +0000</pubDate>
      <link>https://dev.to/ricardoghekiere/comfyui-deploy-choosing-between-self-host-serverless-and-managed-2026-2i</link>
      <guid>https://dev.to/ricardoghekiere/comfyui-deploy-choosing-between-self-host-serverless-and-managed-2026-2i</guid>
      <description>&lt;p&gt;Most teams who want to deploy ComfyUI pick a platform first and figure out the consequences later. It's the wrong order. Each deployment path (self-hosted GPUs, serverless workers, managed platforms, workflow-as-a-service) makes different tradeoffs on cost, cold starts, customization, and operational overhead. Picking the right one is a function of your volume, your team, and how much of your workflow is standard versus custom.&lt;/p&gt;

&lt;p&gt;"ComfyUI is notoriously hard to productionize" is a phrase you see in deployment threads across Hacker News, Reddit, and GitHub. That's not a statement about the software. It's a statement about how much of the work sits outside ComfyUI itself: GPU orchestration, model provisioning, custom node management, queueing, authentication, quality control, and keeping the whole thing alive under real traffic.&lt;/p&gt;

&lt;p&gt;This guide is the vendor-neutral breakdown that doesn't exist in the current search results. It covers the five real deployment paths, a decision framework for choosing between them, concrete cost math at 1K, 10K, and 100K images per month, and the production-hardening work that applies regardless of the path you pick. Patterns here come from building and running AI image pipelines at scale. Our own infrastructure at Runflow processes over 100,000 AI jobs every month across 17 production-validated workflows, and the lessons below are what survived contact with reality.&lt;/p&gt;

&lt;p&gt;Written for developers and technical founders who are past the "I got a workflow running locally" stage and are now trying to ship it to real users without lighting money on fire.&lt;/p&gt;

&lt;h3&gt;
  
  
  What It Means to Deploy ComfyUI
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Deploying ComfyUI means running the ComfyUI server somewhere your application can reach it reliably, with GPU access, model files, custom nodes, authentication, and the ability to handle concurrent requests without falling over.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The ComfyUI you run locally on a laptop is the same binary that runs in production. What changes is everything around it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Where the GPU lives.&lt;/strong&gt; Your machine, a rented cloud GPU, or a serverless worker that spins up on demand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How models and custom nodes get there.&lt;/strong&gt; Manual download, Docker image, persistent volume, or a provisioning script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How requests reach it.&lt;/strong&gt; Direct HTTP, queue, load balancer, or managed API gateway.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Who owns uptime.&lt;/strong&gt; You, a platform, or a hybrid.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Deploying ComfyUI" therefore isn't one thing. It's picking which of these you own and which you outsource. The rest of this guide is about making that pick deliberately.&lt;/p&gt;

&lt;p&gt;If you want to go deeper on the ComfyUI HTTP and WebSocket interface itself (endpoints, the &lt;code&gt;/prompt&lt;/code&gt; flow, image uploads, integration code), start with our &lt;a href="https://www.runflow.io/blog/comfyui-api" rel="noopener noreferrer"&gt;complete guide to the ComfyUI API&lt;/a&gt;. This article picks up where that one leaves off: once you know how to &lt;em&gt;call&lt;/em&gt; ComfyUI, how do you &lt;em&gt;host&lt;/em&gt; it?&lt;/p&gt;

&lt;h3&gt;
  
  
  The Five Ways to Deploy ComfyUI
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;What you run&lt;/th&gt;
&lt;th&gt;What you outsource&lt;/th&gt;
&lt;th&gt;Best for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1. Self-hosted GPU&lt;/td&gt;
&lt;td&gt;ComfyUI + models + infra&lt;/td&gt;
&lt;td&gt;Nothing except the hardware rental&lt;/td&gt;
&lt;td&gt;High volume, full control, custom nodes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2. Serverless workers&lt;/td&gt;
&lt;td&gt;Your Docker image with ComfyUI&lt;/td&gt;
&lt;td&gt;Scaling, GPU management, queueing&lt;/td&gt;
&lt;td&gt;Spiky or unpredictable traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3. Managed ComfyUI platform&lt;/td&gt;
&lt;td&gt;Your workflows only&lt;/td&gt;
&lt;td&gt;Everything else — server, scaling, API&lt;/td&gt;
&lt;td&gt;Teams that want to ship fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4. Workflow-as-a-Service&lt;/td&gt;
&lt;td&gt;Your workflow definition&lt;/td&gt;
&lt;td&gt;ComfyUI itself — it's abstracted away&lt;/td&gt;
&lt;td&gt;Versioned APIs, non-ComfyUI consumers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5. Local / edge&lt;/td&gt;
&lt;td&gt;Everything, on-device&lt;/td&gt;
&lt;td&gt;Nothing — fully air-gapped&lt;/td&gt;
&lt;td&gt;Regulated data, desktop apps, on-prem&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every production ComfyUI deployment falls into one of five buckets. The rest of the article is structured around these. A summary table of the five paths is provided in the section below.&lt;/p&gt;

&lt;p&gt;Three important notes before the deep dive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;These aren't mutually exclusive.&lt;/strong&gt; Production setups often use a managed platform for 80% of traffic and self-host for the 20% of workflows that need custom nodes. We see this hybrid pattern constantly with teams running consumer-facing products.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can move between them.&lt;/strong&gt; Moving from a managed platform to self-hosted is harder than the reverse. If you're unsure, start with a managed platform and migrate only if volume or control demands it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The "best" path changes with volume.&lt;/strong&gt; At 500 images/month, serverless wins. At 500,000, self-hosted wins. The middle is where the interesting tradeoffs live, and where opinionated managed platforms matter most.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Decision Framework: Which Path Should You Choose?
&lt;/h3&gt;

&lt;p&gt;Use this decision tree to cut the space in half quickly, then read the specific path section for details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Question 1: Do you use custom nodes that aren't in the standard registry?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Yes.&lt;/strong&gt; Rule out most managed platforms (they support only allowlisted nodes). Consider self-hosted, serverless with custom images, or the managed platforms that support bring-your-own nodes (Comfy Deploy, Runflow, ViewComfy).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No.&lt;/strong&gt; Every path stays on the table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question 2: What's your expected monthly image volume?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Under 1,000.&lt;/strong&gt; Use a managed platform or serverless. Not worth building infra.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1,000 to 50,000.&lt;/strong&gt; Serverless workers or mid-tier managed platforms give the best cost-to-effort ratio.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over 50,000.&lt;/strong&gt; Self-hosted starts making sense, but only if you have the ops capacity. Below this, the operational overhead isn't recouped by the cost savings. Above this, a well-priced managed platform can still win if it scales to zero between bursts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question 3: How predictable is your traffic?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steady and predictable.&lt;/strong&gt; Self-hosted on reserved GPUs wins on cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spiky or unpredictable.&lt;/strong&gt; Serverless wins. You only pay for GPU seconds consumed, and a managed platform that scales to zero when idle pays off fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-to-viral.&lt;/strong&gt; Serverless or a managed platform with autoscaling. Do not self-host for this pattern; you'll either over-provision or drop requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question 4: Is your team comfortable running GPU infrastructure?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Yes.&lt;/strong&gt; Self-hosted or serverless.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No.&lt;/strong&gt; Managed platform. The ops time you save is worth more than the per-image premium.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Question 5: Is data sensitivity a hard requirement?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Regulated or proprietary.&lt;/strong&gt; Self-hosted or local. Managed platforms read your workflows and inputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard.&lt;/strong&gt; Any path.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A one-line summary: managed platforms at low volumes, serverless at mid volumes, self-hosted at high volumes, with local and edge reserved for regulatory cases. One practical nuance we've seen repeatedly: teams underestimate how quickly they move up volume tiers once they ship, so optimize for easy migration out of your first choice rather than minimizing its per-image cost.&lt;/p&gt;

&lt;p&gt;The rest of the article walks through each path in detail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path 1: Self-Hosted on Your Own GPU
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Self-hosted ComfyUI deployment means running the ComfyUI server on a GPU you rent or own (typically on Vast.ai, Lambda, CoreWeave, or bare-metal hardware) with full control over models, custom nodes, and the runtime environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the highest-control, lowest-per-image-cost path. It's also the one with the most operational overhead, and the one most teams underestimate.&lt;/p&gt;

&lt;h4&gt;
  
  
  What you actually manage
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The GPU host.&lt;/strong&gt; Rent a 3090 / 4090 / A100 / H100 on Vast, RunPod Community Cloud, Lambda, or CoreWeave. Or buy hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The operating system and Python environment.&lt;/strong&gt; ComfyUI runs on Python 3.10+. CUDA, PyTorch, dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ComfyUI itself.&lt;/strong&gt; &lt;code&gt;git clone&lt;/code&gt;, install requirements, start with &lt;code&gt;python main.py --listen 0.0.0.0 --port 8188&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Models.&lt;/strong&gt; Checkpoints, LoRAs, VAEs, ControlNets, CLIP, upscalers. Often tens of GB. They need to be downloaded to specific directories.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom nodes.&lt;/strong&gt; Installed into &lt;code&gt;ComfyUI/custom_nodes/&lt;/code&gt;. Each has its own dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A reverse proxy.&lt;/strong&gt; Nginx or Caddy, for TLS termination and auth (ComfyUI has no built-in auth).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A queue in front.&lt;/strong&gt; Redis/BullMQ, SQS, or RabbitMQ, because ComfyUI is single-threaded.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and backups.&lt;/strong&gt; GPU utilization, VRAM, queue depth, model integrity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  The provisioning problem
&lt;/h4&gt;

&lt;p&gt;The single biggest time sink in self-hosting is this: every time you start a new GPU instance, you have to reinstall ComfyUI, download every model, install every custom node, and restore your config. On Vast or RunPod Community Cloud this happens often, because instances get interrupted, moved, or you spin up new ones to scale.&lt;/p&gt;

&lt;p&gt;Doing this manually takes 30 to 90 minutes per instance. Do it weekly and you've lost a workday a month. We've seen teams lose multiple engineers' weeks per quarter to this pattern before automating it.&lt;/p&gt;

&lt;p&gt;The fix is a one-line installation script that does the whole setup automatically. Tools like &lt;a href="https://deploy.promptingpixels.com" rel="noopener noreferrer"&gt;deploy.promptingpixels.com&lt;/a&gt; generate a bash one-liner that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installs the ComfyUI version you specify.&lt;/li&gt;
&lt;li&gt;Downloads every model from a list (with support for Hugging Face and Civitai URLs, mapping each to the correct directory).&lt;/li&gt;
&lt;li&gt;Installs every custom node you specify, pinned to a version.&lt;/li&gt;
&lt;li&gt;Configures the environment variables (Hugging Face tokens, API keys).&lt;/li&gt;
&lt;li&gt;Starts the server.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You paste this one-liner into the Jupyter terminal on a fresh Vast or RunPod instance, hit enter, walk away. By the time you come back, ComfyUI is running with your exact setup.&lt;/p&gt;

&lt;p&gt;This is the closest ComfyUI gets to "infrastructure as code." It's the pattern every serious self-hoster converges on eventually, and it's almost never written about. If you're deploying to Vast or RunPod Community Cloud, build or use an install script from day one. For comparison: managed platforms that do this automatically (including Runflow) typically spin up a custom environment per workflow in 1 to 5 minutes, with model and custom-node resolution handled end-to-end.&lt;/p&gt;

&lt;h4&gt;
  
  
  When self-hosting is the right answer
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You run over 50,000 images per month and the per-image cost savings compound.&lt;/li&gt;
&lt;li&gt;You use custom nodes or custom models that managed platforms don't allow.&lt;/li&gt;
&lt;li&gt;Your data can't leave your infrastructure.&lt;/li&gt;
&lt;li&gt;You need specific GPU hardware (H100s, multi-GPU setups, unusual VRAM tiers).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When it isn't
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You're still figuring out your workflow.&lt;/li&gt;
&lt;li&gt;Your traffic is spiky or hasn't ramped yet.&lt;/li&gt;
&lt;li&gt;Your team has zero DevOps capacity.&lt;/li&gt;
&lt;li&gt;You'd rather focus on the product than the infra.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Path 2: Serverless on RunPod
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;RunPod Serverless is the most common path for teams who want ComfyUI to scale on demand without running servers full-time. You package ComfyUI into a Docker image, configure the endpoint, and RunPod handles GPU allocation, scaling, and billing by the second.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RunPod has become the default for this bucket because of three things: the &lt;code&gt;worker-comfyui&lt;/code&gt; image is battle-tested, per-second billing is genuinely pay-as-you-go, and the Hub templates remove most of the initial setup.&lt;/p&gt;

&lt;h4&gt;
  
  
  How it works
&lt;/h4&gt;

&lt;p&gt;At a high level:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start from the **&lt;/strong&gt;&lt;code&gt;runpod/worker-comfyui&lt;/code&gt;**** Docker image.** Several variants exist, pre-loaded with common models (SD3, FLUX schnell/dev, SDXL) or a base image you bring your own models to.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a RunPod Serverless endpoint.&lt;/strong&gt; Either from the Hub (one-click for standard configs) or by pointing at a custom Docker image you've built.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Call the endpoint.&lt;/strong&gt; POST to &lt;code&gt;/run&lt;/code&gt; (async) or &lt;code&gt;/runsync&lt;/code&gt; (sync, up to roughly 120 seconds). The payload includes your workflow JSON in API format plus any input images.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Poll for results.&lt;/strong&gt; The response contains a job ID; poll &lt;code&gt;/status/{id}&lt;/code&gt; until the job completes, then pull the output (base64-encoded images or S3 URLs if you've configured S3 upload).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For workflows that produce images in under 10 seconds, &lt;code&gt;/runsync&lt;/code&gt; is simpler. For anything longer, or anything with queueing, use &lt;code&gt;/run&lt;/code&gt; and poll.&lt;/p&gt;

&lt;h4&gt;
  
  
  Customizing the worker
&lt;/h4&gt;

&lt;p&gt;The default Hub image gets you FLUX or SDXL quickly. For custom models or custom nodes, you have two options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network volumes.&lt;/strong&gt; Mount a persistent disk with your models pre-downloaded. Faster iteration, but ties you to a region.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Docker images.&lt;/strong&gt; Fork the &lt;code&gt;worker-comfyui&lt;/code&gt; Dockerfile, add your model downloads and custom node installs, push to Docker Hub, point your endpoint at it. Slower to iterate, more portable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For production, custom Docker images are the right pattern. Version them, tag them, roll back cleanly. Network volumes are fine for development and testing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Cold starts
&lt;/h4&gt;

&lt;p&gt;The main operational pain. A cold worker takes 20 to 60 seconds to boot, load ComfyUI, and load models into VRAM, and longer for large models (FLUX dev, video models). Mitigations, in order of effectiveness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Active workers.&lt;/strong&gt; Keep 1 to 3 workers always-on. You pay for idle time but serve the first request fast. Standard pattern for user-facing products.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flashboot.&lt;/strong&gt; RunPod's snapshot-based cold-start acceleration. Cuts cold start to 2 to 5 seconds for most workflows. Worth enabling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smaller models where possible.&lt;/strong&gt; FP8 quantized models load faster than FP16.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pre-load models in your Dockerfile.&lt;/strong&gt; Don't download on first request; bake them in.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The architectural move past these point-fixes is dynamic container caching: containers that stay warm across jobs, with models loaded from fast network storage rather than re-fetched on each boot. That's what serious ComfyUI platforms (Runflow included) do internally, because point-fixes stop scaling once your workflow mix is diverse.&lt;/p&gt;

&lt;h4&gt;
  
  
  When serverless is the right answer
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Unpredictable or spiky traffic.&lt;/li&gt;
&lt;li&gt;You need autoscaling without building it yourself.&lt;/li&gt;
&lt;li&gt;Monthly volume in the 1,000 to 50,000 range.&lt;/li&gt;
&lt;li&gt;You're comfortable building a Docker image.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When it isn't
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You need sub-second response times and can't tolerate any cold starts.&lt;/li&gt;
&lt;li&gt;Your workflow takes over 10 minutes (hits RunPod's timeouts).&lt;/li&gt;
&lt;li&gt;You run over 100K images/month steady, where self-hosting undercuts the per-second pricing.&lt;/li&gt;
&lt;li&gt;Your custom nodes aren't Docker-friendly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Path 3: Managed ComfyUI Platforms
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Managed ComfyUI platforms host the server, handle scaling, and expose your workflows as APIs. You only bring the workflow JSON. The tradeoff is less customization in exchange for dramatically less operational work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This category has matured fast. Three years ago there was nothing. Today there are at least five credible options, each with a slightly different angle.&lt;/p&gt;

&lt;h4&gt;
  
  
  Comfy Deploy (comfydeploy.com)
&lt;/h4&gt;

&lt;p&gt;The YC-backed managed platform that started as the open-source &lt;code&gt;comfyui-deploy&lt;/code&gt; project (github.com/BennyKok/comfyui-deploy) and became a hosted product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; You upload a workflow, it becomes an API endpoint. Built-in support for custom nodes, LoRAs, and model management. Handles queueing, scaling, and version control of workflows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; Closest thing to "ComfyUI as a SaaS." Active development. The open-source backend means you can self-host the same stack if you outgrow the managed tier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; Vendor-specific API, not the native ComfyUI &lt;code&gt;/prompt&lt;/code&gt; endpoint. If you later want to move off, you'll rewrite your integration. Pricing is per-request on top of GPU time; at high volume it's more expensive than raw RunPod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams who want to ship a ComfyUI-backed product in days, not weeks, and who value workflow versioning.&lt;/p&gt;

&lt;h4&gt;
  
  
  Runflow (runflow.io)
&lt;/h4&gt;

&lt;p&gt;Our own platform, included here because the positioning is different enough to matter. Runflow is built around the conviction that most managed ComfyUI platforms stop at "deployment," and that the real production work is everything that wraps around it. The tagline is: "deploy your ComfyUI workflow as an API in one click, and unlock what's beyond it."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What it does:&lt;/strong&gt; A plugin inside ComfyUI lets you deploy any workflow to a live API endpoint in 1 to 5 minutes, including every installed custom node, model, and dependency. Missing models pull automatically from Hugging Face and Civitai, covering roughly 99% of cases. A single unified node in the plugin also lets you call over 736 cloud-hosted models (open-source and closed-source, including models you can't run locally) directly from the ComfyUI canvas.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's different:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated quality evaluation via Sentinel.&lt;/strong&gt; Every generated image is scored across 8 quality dimensions (artifact detection, prompt alignment, face fidelity, skin-tone consistency, and more) before delivery, with configurable pass/fail thresholds and built-in retry on failure. This is the BetterPic pattern made native: generate more candidates than you need, score them, deliver only what passes. BetterPic (our headshots case study) generates 240 candidates per user and delivers the top 60. That layer is what took their gross margin from the ~60% most headshot products run at to 87%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-provider routing.&lt;/strong&gt; Requests route across a primary provider (&lt;a href="https://www.runflow.io/compare/fal" rel="noopener noreferrer"&gt;fal.ai&lt;/a&gt;), a cost-optimization layer (&lt;a href="https://www.runflow.io/compare/together" rel="noopener noreferrer"&gt;together.ai&lt;/a&gt;), and a reliability fallback (Replicate), based on availability, reliability, and cost. Provider outages are handled transparently through internal retry. Teams that wire this themselves spend weeks on it; the gap between single-provider and routed pricing is typically 50 to 65%.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic per-workflow containers.&lt;/strong&gt; Each workflow gets its own container, built once per (user, workflow) combination, with a lean base and network-mounted model storage. Pre-warmed workloads stay hot for common workflows. No cold-start cliff when traffic bursts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scales to zero.&lt;/strong&gt; Billed per second. Idle workloads cost nothing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dev, staging, and production environments.&lt;/strong&gt; Promote workflows through environments the way you promote code. Pin by version, roll back with one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in port security check.&lt;/strong&gt; The plugin runs a free, anonymous scan of your local ComfyUI instance and flags exposed ports. Not a deployment feature, but directly addresses the single most common ComfyUI security failure (exposed instances on public IPs).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pricing:&lt;/strong&gt; Roughly half of the market on comparable hardware. A100 at $4.93/hr is about 20% cheaper than Comfy Deploy equivalents; H100 at $5.96/hr is about 29% cheaper. $10 free signup credit, no credit card required. Up to 25% off on multi-month commitments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; Newer platform than Comfy Deploy or RunPod. Opinionated about treating workflows (not models) as the unit of deployment, which is the right model if you've built anything real in ComfyUI but can feel heavy for single-model use cases. Editing happens locally, not in the cloud, which is deliberate: the canvas is for development, the cloud is for running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Teams who want a managed platform that also solves quality scoring, multi-provider routing, and environment management without wiring it themselves.&lt;/p&gt;

&lt;h4&gt;
  
  
  ViewComfy (viewcomfy.com)
&lt;/h4&gt;

&lt;p&gt;Similar positioning to Comfy Deploy, different emphasis. ViewComfy leans harder into shareable web apps; you can turn a workflow into a hosted UI that non-technical users interact with, not just an API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; If your product has internal users or clients running workflows via a web interface, this is the shortest path. Good custom node support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; The web-app layer is useful only if you want it. For pure API use cases, Comfy Deploy or Runflow is more direct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Agencies, content teams, internal tools where humans run workflows through a form.&lt;/p&gt;

&lt;h4&gt;
  
  
  Salad
&lt;/h4&gt;

&lt;p&gt;A GPU-marketplace-backed platform that exposes ComfyUI as a webhook-driven API. Open-source &lt;code&gt;comfyui-api&lt;/code&gt; fork with ergonomic additions like webhooks, dynamic workflow endpoints, and S3 upload built in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; Cheapest GPU pricing among managed options (consumer GPUs from distributed nodes). Good webhook ergonomics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; Distributed GPUs mean more variance. Some jobs land on fast hardware, some on slower. Less predictable latency than RunPod or a dedicated provider.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Batch processing, non-user-facing workloads, cost-sensitive workflows where latency variance is acceptable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Modal
&lt;/h4&gt;

&lt;p&gt;Not ComfyUI-specific, but often used to host ComfyUI. Modal is a Python-native serverless GPU platform where you write a function that wraps ComfyUI, and Modal handles the rest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; Everything is code. Git-based deployment. Excellent developer experience for Python teams. Good cold-start performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; More setup than a button-click platform. You're writing Python wrappers, not dropping in workflows. Premium pricing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Python-heavy teams who want code-defined infrastructure and are already evaluating Modal for other workloads.&lt;/p&gt;

&lt;h4&gt;
  
  
  Choosing between them
&lt;/h4&gt;

&lt;p&gt;A rough guide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fastest time to API.&lt;/strong&gt; Comfy Deploy or Runflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quality scoring and auto-retry built in.&lt;/strong&gt; Runflow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-technical user-facing web apps.&lt;/strong&gt; ViewComfy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cheapest compute, batch jobs.&lt;/strong&gt; Salad&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python-native team, code-defined infra.&lt;/strong&gt; Modal&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Path 4: Workflow-as-a-Service
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Workflow-as-a-service tools convert a ComfyUI workflow into a versioned, deployable service with a standard API, abstracting ComfyUI itself away from consumers of the API.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a newer category and a different idea from managed hosting. Instead of "here's your ComfyUI, run workflows against it," it's "here's your workflow, wrapped as a service with its own schema, docs, and versioning."&lt;/p&gt;

&lt;h4&gt;
  
  
  BentoML's comfy-pack
&lt;/h4&gt;

&lt;p&gt;The leading example. &lt;code&gt;comfy-pack&lt;/code&gt; is a toolkit from the BentoML team that transforms ComfyUI workflows into production-grade APIs. You define input and output schemas using special nodes inserted into your workflow, and comfy-pack generates a standardized REST service with typed inputs, generated client SDKs, and observability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; The generated API looks nothing like ComfyUI. It looks like a normal, versioned REST API. Consumers don't need to know ComfyUI exists. Strong enterprise features (autoscaling, tracing, deployments to BentoCloud or your own Kubernetes).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; Most setup of any path. Requires modifying your workflow to add comfy-pack input/output nodes. If your team isn't already in the BentoML world, the learning curve is real.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Enterprise deployments where ComfyUI is an implementation detail and you want to expose clean APIs to other teams or customers.&lt;/p&gt;

&lt;h4&gt;
  
  
  Replicate (Cog)
&lt;/h4&gt;

&lt;p&gt;Technically adjacent. Replicate's Cog packaging format can wrap a ComfyUI workflow into a versioned model that runs on Replicate's infrastructure. You write a &lt;code&gt;cog.yaml&lt;/code&gt;, define inputs and outputs in Python, push to Replicate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strengths:&lt;/strong&gt; Instant distribution. Once published, anyone can call your model via Replicate's API. Good for open-source workflows and community distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoffs:&lt;/strong&gt; Vendor lock-in to Replicate's infrastructure and pricing. Less flexibility than BentoML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Publishing workflows as models for external consumers.&lt;/p&gt;

&lt;p&gt;Note on the category in general: Runflow borrows the "typed input/output nodes inside the canvas" idea from this world. Dedicated Runflow input and output nodes placed directly on the canvas generate the API contract automatically, so the designer editing the workflow controls the API surface and the developer doesn't have to reverse-engineer graph IDs. That's the single cleanest pattern for custom-input handling we've found, and it's the one we'd push any team toward regardless of platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path 5: Local and Edge Deployment
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Local deployment runs ComfyUI on user-controlled hardware (a desktop app, an on-prem server, or an air-gapped environment) with no cloud dependency.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the smallest bucket by volume but the most important for a specific set of use cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  The three sub-paths
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Desktop application.&lt;/strong&gt; Bundle ComfyUI into an Electron/Tauri app that ships with a GPU runtime. Users run everything locally. Works best with smaller quantized models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-prem server.&lt;/strong&gt; Run ComfyUI on a customer's own hardware, inside their network. Common in enterprise deployments for privacy-sensitive verticals.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Air-gapped.&lt;/strong&gt; No internet at all. Models and custom nodes must be pre-packaged. Common in regulated industries (defense, healthcare, legal).&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When local wins
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data can't leave the user's machine.&lt;/strong&gt; Medical imaging, legal documents, trade secrets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You're shipping software, not a service.&lt;/strong&gt; Creative tools, desktop photo editors, hobbyist workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Internet is unreliable.&lt;/strong&gt; Field workflows, offline creative studios.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The operational pattern here is completely different from the others. You care about installer size, model quantization, first-launch UX, and graceful degradation on weaker GPUs, not autoscaling or cold starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cost Math: What Each Path Actually Costs
&lt;/h3&gt;

&lt;p&gt;The most useful section of this guide, and the one nobody else has. The numbers below assume a standard SDXL workflow at roughly 3 to 4 seconds per 1024x1024 image on an A100, at mid-2026 pricing. Treat them as reference orders of magnitude, not quotes; pricing shifts, and your workflow runtime is specific to you.&lt;/p&gt;

&lt;h4&gt;
  
  
  At 1,000 images per month
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Rough monthly cost&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Managed (Comfy Deploy / ViewComfy)&lt;/td&gt;
&lt;td&gt;$20–80&lt;/td&gt;
&lt;td&gt;~1 hour setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless (RunPod)&lt;/td&gt;
&lt;td&gt;$15–40&lt;/td&gt;
&lt;td&gt;~1 day setup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted (Vast.ai spot)&lt;/td&gt;
&lt;td&gt;$50+ min GPU rental&lt;/td&gt;
&lt;td&gt;~1 week setup&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: Managed platforms.&lt;/strong&gt; The volume is too low to justify setup time for anything else. Even serverless workers have a fixed minimum cost of active workers if you want snappy UX. Self-hosting is actively worse here; you'll pay for idle GPU time. The $10 free signup credit on most managed platforms effectively covers the first month or two of experimentation.&lt;/p&gt;

&lt;h4&gt;
  
  
  At 10,000 images per month
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Rough monthly cost&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;td&gt;$200–800&lt;/td&gt;
&lt;td&gt;Already set up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless (RunPod)&lt;/td&gt;
&lt;td&gt;$80–250&lt;/td&gt;
&lt;td&gt;Already set up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted (reserved A100)&lt;/td&gt;
&lt;td&gt;$300–500&lt;/td&gt;
&lt;td&gt;Ongoing ops time&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: Serverless, with managed platforms close behind.&lt;/strong&gt; This is the sweet spot. You've already done the initial work, traffic is real enough to justify per-second billing, and you avoid the always-on cost of reserved GPUs. Managed platforms are fine but start charging premiums at this volume, except for platforms like Runflow priced at roughly half the managed-market rate, where the premium largely disappears and you get quality scoring and multi-provider routing on top.&lt;/p&gt;

&lt;h4&gt;
  
  
  At 100,000 images per month
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;Rough monthly cost&lt;/th&gt;
&lt;th&gt;Effort&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Managed&lt;/td&gt;
&lt;td&gt;$2,000–8,000&lt;/td&gt;
&lt;td&gt;Passive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Serverless (RunPod)&lt;/td&gt;
&lt;td&gt;$800–2,500&lt;/td&gt;
&lt;td&gt;Passive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted (2× reserved A100s)&lt;/td&gt;
&lt;td&gt;$600–1,400&lt;/td&gt;
&lt;td&gt;~1–2 days/month ops&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Winner: Self-hosted, by a wide margin on per-image cost, but a well-priced managed platform can still hold its own on total cost of ownership.&lt;/strong&gt; At this scale the per-image cost gap compounds. Self-hosting two reserved A100s on Lambda or CoreWeave, running full-time, processes this volume with headroom. The ops overhead (monitoring, deployments, model updates) is real but bounded, and savings versus a generic managed platform easily pay for a part-time engineer. On the other hand: at managed-platform pricing that's roughly half the market (A100 at $4.93/hr, H100 at $5.96/hr), plus scale-to-zero on idle workloads, the break-even against self-hosting can shift 50,000 to 100,000 images of volume higher than it would on typical managed pricing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Break-even intuition
&lt;/h4&gt;

&lt;p&gt;Roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed to Serverless.&lt;/strong&gt; Around 3,000 to 5,000 images/month.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Serverless to Self-hosted.&lt;/strong&gt; Around 50,000 to 75,000 images/month on mainstream managed pricing. Closer to 100,000 to 150,000 on half-market managed pricing (Runflow and similar).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run the math on your own workflow. A 45-second video workflow has completely different economics from a 3-second image workflow. And don't forget to price in the engineer-hours you'll spend on ops if you go self-hosted; that's where most teams get the TCO wrong.&lt;/p&gt;

&lt;h3&gt;
  
  
  Production Hardening (Regardless of Path)
&lt;/h3&gt;

&lt;p&gt;Seven things to handle no matter which path you pick. Teams that skip these run into the same issues in the same order.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Model storage and versioning
&lt;/h4&gt;

&lt;p&gt;Models are tens of GB and change often. Treat them as a first-class asset:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Store canonical copies in object storage (S3, R2, GCS) with content hashes.&lt;/li&gt;
&lt;li&gt;Version them: &lt;code&gt;sdxl-base-v1.0.safetensors&lt;/code&gt;, not &lt;code&gt;base.safetensors&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Have a single source of truth your deployment scripts pull from.&lt;/li&gt;
&lt;li&gt;Never let "whatever's on this GPU" be the answer to "what model version are we running."&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. Custom node supply chain
&lt;/h4&gt;

&lt;p&gt;Community ComfyUI nodes are arbitrary Python code. Some run shell commands, read files, or phone home. A node package that was safe last month may not be this month.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pin every custom node to a specific commit or version tag.&lt;/li&gt;
&lt;li&gt;Review what the node does before installing: read the &lt;code&gt;__init__.py&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Sandbox aggressive nodes where possible.&lt;/li&gt;
&lt;li&gt;Don't install nodes at runtime based on user input, ever.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  3. Queueing
&lt;/h4&gt;

&lt;p&gt;ComfyUI is single-threaded. One workflow executes at a time per instance. Put a queue (Redis, SQS, BullMQ) in front of your ComfyUI instances. This gives you backpressure, retry logic, dead-letter queues, and the ability to scale workers horizontally. &lt;a href="https://www.runflow.io/blog/comfyui-api" rel="noopener noreferrer"&gt;We cover this pattern in depth in the ComfyUI API guide.&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Cold start management
&lt;/h4&gt;

&lt;p&gt;Cold starts are the silent killer of user experience. Pre-warm workers by submitting a dummy workflow at startup, keep at least one active worker on serverless, use FP8 or quantized models where the quality loss is acceptable, and cache models in VRAM across jobs. The robust version of this pattern is dynamic containers: per-workflow images built once, kept warm, with models mounted from fast network storage. That's the architecture we run at Runflow, and it's the one that survives workload diversity past the "top 3 models" stage.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Automated quality evaluation
&lt;/h4&gt;

&lt;p&gt;This is the one teams skip until it costs them customers. At small volumes you eyeball outputs. At production volume, defects become statistical certainties: face distortions, wrong backgrounds, artifacts that pass at thumbnail and fail at full resolution.&lt;/p&gt;

&lt;p&gt;The pattern that works: generate N candidates per user request, score every candidate across three tiers (generic quality, use-case-specific quality, custom business rules), deliver only what passes the threshold. BetterPic (one of our largest customers) runs this at 240 candidates per user and delivers the top 60. Customer-support tickets about quality dropped from the 30 to 40% range into low single digits once this layer was in place. Build your own scoring layer or use a drop-in (Sentinel, internal tools built on CLIP plus specialized vision models). The principle matters more than the vendor.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Authentication
&lt;/h4&gt;

&lt;p&gt;ComfyUI has no built-in auth. The server happily accepts any request on any endpoint. Put it behind a reverse proxy with API key auth, bind the ComfyUI process to localhost, and validate incoming workflow JSON for allowed node classes before forwarding. A Shodan search turns up thousands of exposed ComfyUI instances, most of them on hobbyist boxes with nothing between the public internet and a command-executing endpoint. If you want a quick external check of your own exposure, the Runflow ComfyUI plugin runs a free, anonymous port scan (no account required).&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Observability
&lt;/h4&gt;

&lt;p&gt;The metrics that matter, in priority order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Queue depth. Are you falling behind?&lt;/li&gt;
&lt;li&gt;Per-workflow latency. Which workflows are slow, and is that drifting?&lt;/li&gt;
&lt;li&gt;Per-node failure rate. Where in the graph are errors concentrated?&lt;/li&gt;
&lt;li&gt;GPU utilization. Are you paying for idle time?&lt;/li&gt;
&lt;li&gt;Model cache hit rate. Are you reloading models unnecessarily?&lt;/li&gt;
&lt;li&gt;Quality pass rate. What percentage of generations are clearing your scoring thresholds, and is that drifting?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most teams skip this and then spend a week debugging a production issue they'd have spotted in a dashboard.&lt;/p&gt;

&lt;h4&gt;
  
  
  8. Output handling
&lt;/h4&gt;

&lt;p&gt;Don't serve ComfyUI's &lt;code&gt;output/&lt;/code&gt; directory directly. It's shared across all workflows and across tenants in multi-tenant setups. Pull images via &lt;code&gt;/view&lt;/code&gt; immediately after completion, upload to tenant-scoped object storage keys, return signed URLs to your application, and run a cleanup job on the local disk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deployment Automation: Installation Scripts and Infra-as-Code
&lt;/h3&gt;

&lt;p&gt;The pattern that separates teams who spend their Monday morning reinstalling ComfyUI from teams who don't.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why installation scripts matter
&lt;/h4&gt;

&lt;p&gt;If you're on Vast.ai or RunPod Community Cloud, instances are ephemeral. They get interrupted, reclaimed, or you spin up new ones to scale. Every one of those events means setting up ComfyUI from scratch, which means re-downloading tens of gigabytes of models, reinstalling custom nodes, and restoring config.&lt;/p&gt;

&lt;p&gt;Done manually, this is 30 to 90 minutes per instance. Automated, it's a one-liner and a few minutes of download time.&lt;/p&gt;

&lt;h4&gt;
  
  
  What a good installation script does
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# 1. Install specific ComfyUI version&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /workspace
git clone https://github.com/comfyanonymous/ComfyUI
&lt;span class="nb"&gt;cd &lt;/span&gt;ComfyUI
git checkout v0.3.70
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# 2. Download models to correct directories&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; models/checkpoints models/loras models/vae
wget &lt;span class="nt"&gt;-O&lt;/span&gt; models/checkpoints/sdxl-base.safetensors &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"https://huggingface.co/.../sd_xl_base_1.0.safetensors"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Install pinned custom nodes&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;custom_nodes
git clone https://github.com/ltdrdata/ComfyUI-Impact-Pack
&lt;span class="nb"&gt;cd &lt;/span&gt;ComfyUI-Impact-Pack &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git checkout v6.8.2 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="c"&gt;# 4. Start the server&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /workspace/ComfyUI
python main.py &lt;span class="nt"&gt;--listen&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8188
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice you'll parameterize the ComfyUI version, the model list (each with Hugging Face or Civitai URLs and target directories), the custom node list (each pinned to a commit), and environment variables for API tokens.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tools that generate these scripts
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://deploy.promptingpixels.com" rel="noopener noreferrer"&gt;deploy.promptingpixels.com&lt;/a&gt; is the most useful tool we've found for this. You configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ComfyUI version&lt;/li&gt;
&lt;li&gt;Models (searchable from Hugging Face and Civitai, automatically mapped to correct directories)&lt;/li&gt;
&lt;li&gt;Custom nodes (from the ComfyUI registry, pinned to versions)&lt;/li&gt;
&lt;li&gt;Provider (Vast.ai or RunPod)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It emits a one-line bash command you paste into your new instance's terminal. The full script is inspectable; you can download and modify it, or fork the pattern into your own tooling. Preset configurations for common setups (SDXL + ControlNet, Qwen Image Edit, Flux) save even more time.&lt;/p&gt;

&lt;h4&gt;
  
  
  The ops discipline this enables
&lt;/h4&gt;

&lt;p&gt;Once you have installation scripts, three things become possible:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Reproducible environments.&lt;/strong&gt; Your dev, staging, and production ComfyUI instances can be guaranteed identical.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast recovery.&lt;/strong&gt; An interrupted instance isn't a crisis; you spin up a replacement and run the script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version-controlled infrastructure.&lt;/strong&gt; Your install script lives in git. You can diff, review, and roll back changes to your ComfyUI environment the same way you do code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For Docker-based deployments (RunPod Serverless, Modal), the equivalent is your Dockerfile. Same idea, different syntax. The principle is identical: your environment is code, not clicks. Managed platforms collapse this further; on Runflow, the environment is resolved automatically from what the user has installed locally when they click deploy, and the same resolution applies across dev, staging, and production.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Deployment Failures and How to Avoid Them
&lt;/h3&gt;

&lt;p&gt;Ranked by how often we see them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Running out of VRAM on the first real workload.&lt;/strong&gt; The workflow that ran fine on your 24GB dev card OOMs on the 16GB production card. Test on the exact GPU tier you'll deploy on, or use FP8 / quantized models with VRAM headroom.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Cold starts nobody measured.&lt;/strong&gt; Your latency looks fine in testing because the GPU was warm. The first user request after a quiet period takes 45 seconds. Measure cold-start latency explicitly; add warm workers or Flashboot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Custom nodes that work locally but not in production.&lt;/strong&gt; Usually because of Python version, CUDA version, or missing system dependencies. Pin everything. Build your deployment environment from the same base image as production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Model paths hardcoded in workflow JSON.&lt;/strong&gt; Dev server has &lt;code&gt;sd_xl_base_1.0.safetensors&lt;/code&gt;; production server renamed it to &lt;code&gt;base.safetensors&lt;/code&gt;. Your workflow validation fails. Parameterize model names and resolve them per-environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Queue drift.&lt;/strong&gt; You submit jobs faster than workers can process them. No queue depth monitoring, so nobody notices until users complain. Always alert on queue depth and consumer lag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Running ComfyUI directly on port 443 with no auth.&lt;/strong&gt; The single most common way ComfyUI instances end up on someone's scanning list within 24 hours. Always bind to localhost and front with a reverse proxy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;7. Deploying updates with no rollback plan.&lt;/strong&gt; You push a new ComfyUI version, a new model, or a new custom node. Something breaks. Now what? Tag and version everything, and keep the previous image, script, or snapshot one command away.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Treating "it works on localhost" as good enough.&lt;/strong&gt; Localhost doesn't have network latency, TLS overhead, queue contention, or real concurrency. Always run a load test at 2x your expected peak before launch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;9. Shipping without automated quality scoring.&lt;/strong&gt; You can eyeball 100 images. You can't eyeball 10,000. This is the failure mode that doesn't bite until you're at scale, and by then you've already shipped bad outputs to paying customers. Build scoring before you need it, not after.&lt;/p&gt;

&lt;h3&gt;
  
  
  FAQ
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;What does it mean to deploy ComfyUI?&lt;/strong&gt; Deploying ComfyUI means running the ComfyUI server in an environment your application can reach reliably, with GPU access, required models and custom nodes, authentication, and the ability to handle concurrent requests. The core binary is the same as what you run locally; deployment is about the infrastructure around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the easiest way to deploy ComfyUI to production?&lt;/strong&gt; For most teams, a managed platform like Comfy Deploy, Runflow, or a serverless endpoint on RunPod is the fastest path from workflow to production API. All three abstract away GPU management, scaling, and queueing, letting you focus on your workflow. Runflow adds automated quality scoring and multi-provider routing on top, which matters if you're shipping to real users at volume. Self-hosting is cheaper at high volumes but has meaningful operational overhead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does it cost to deploy ComfyUI?&lt;/strong&gt; Cost depends on volume and path. At 1,000 images per month, expect $20 to $80 on a managed platform. At 10,000 per month, roughly $80 to $250 on serverless. At 100,000+ per month, self-hosted on reserved GPUs (around $600 to $1,400 for two A100s) beats most managed options, though half-market-priced managed platforms stay competitive up to several times that volume.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I deploy ComfyUI without Docker?&lt;/strong&gt; Yes. On Vast.ai, RunPod Community Cloud, or a bare-metal server, you can install ComfyUI directly via &lt;code&gt;git clone&lt;/code&gt; and run it with Python. Docker becomes necessary when you deploy to serverless platforms (RunPod Serverless, Modal) because they package your environment as a container image. On managed platforms like Runflow, you skip Docker entirely; the platform builds the container for you based on what your workflow needs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's the difference between Comfy Deploy and Runflow?&lt;/strong&gt; Both are managed ComfyUI platforms that expose your workflows as APIs. Comfy Deploy is the more mature product and has an open-source backend. Runflow is newer and focuses on the production work beyond deployment: automated quality scoring via Sentinel (8 dimensions, configurable thresholds, built-in retry), multi-provider routing for cost and reliability, dev/staging/prod environment promotion, and pricing that's roughly half of comparable managed options. Pick Comfy Deploy if you want the most established managed option. Pick Runflow if you want quality scoring and routing built in and want to pay less for the GPU underneath.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is RunPod the best way to deploy ComfyUI?&lt;/strong&gt; RunPod is the most popular path for serverless ComfyUI deployment because of its &lt;code&gt;worker-comfyui&lt;/code&gt; image, per-second pricing, and relatively low cold-start times with Flashboot. Whether it's "best" depends on your volume and requirements. Managed platforms win for very low volume, and self-hosting wins at very high volume. Managed platforms with quality scoring and multi-provider routing built in, like Runflow, win when quality is part of your product and you don't want to wire those pieces yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I deploy ComfyUI to production with custom nodes?&lt;/strong&gt; Three options: self-host and install the nodes directly into &lt;code&gt;ComfyUI/custom_nodes/&lt;/code&gt;, build a custom Docker image based on &lt;code&gt;runpod/worker-comfyui&lt;/code&gt; that installs your nodes at build time, or use a managed platform that supports custom nodes (Comfy Deploy, Runflow, and ViewComfy all do). Runflow automatically resolves every installed plugin and model from your local ComfyUI when you click deploy, which means custom nodes "just work" as long as they exist on Hugging Face, Civitai, or a reachable repository. Always pin node versions to a specific commit to avoid surprises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I deploy ComfyUI on AWS or GCP directly?&lt;/strong&gt; Yes, but it's usually not the easiest path. You'd run ComfyUI on an EC2 GPU instance (AWS) or Compute Engine (GCP), handle your own scaling, and build the queueing layer yourself. Unless you need AWS or GCP for compliance or integration reasons, a purpose-built platform (RunPod, Modal, Comfy Deploy, Runflow) is faster to ship.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I deploy ComfyUI for offline or air-gapped environments?&lt;/strong&gt; Pre-package ComfyUI, all required models, and all custom nodes into a single installer or container. The target environment won't be able to download dependencies at runtime, so everything must ship with it. This is common for regulated industries but requires careful attention to installer size and model quantization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it safe to expose ComfyUI directly to the internet?&lt;/strong&gt; No. ComfyUI has no built-in authentication. Every endpoint, including file uploads and VRAM management, is public by default. Always put it behind a reverse proxy with API key authentication, bind the ComfyUI process to localhost or a private network, and validate incoming workflow JSON for allowed node classes. If you want a fast external check on your current setup, the Runflow ComfyUI plugin runs a free, anonymous port scan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I know if my ComfyUI outputs are good enough to ship?&lt;/strong&gt; You don't, without automated scoring. Manual review doesn't scale past a few dozen images per day. The pattern that works at production scale is tiered scoring (generic quality, use-case-specific quality, custom business rules), configurable pass/fail thresholds per dimension, and automatic retry on failures. You can build this yourself on CLIP plus specialized vision models, or use a service like Sentinel (built into Runflow and available standalone). The architecture matters more than the vendor; shipping without it is the most common self-inflicted scaling failure we see.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where to Go Next
&lt;/h3&gt;

&lt;p&gt;The order of operations that works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Get a workflow running locally&lt;/strong&gt; and exported in API format.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick a path&lt;/strong&gt; using the decision framework above. Default to serverless for 1K to 50K images/month; reconsider only if you have specific reasons.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build an installation script or Docker image&lt;/strong&gt; for your setup on day one. This single discipline separates teams that ship from teams that thrash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Put a queue and a reverse proxy in front&lt;/strong&gt; before you have users. Both are cheap to add now and painful to retrofit later.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add automated quality scoring&lt;/strong&gt; before you're at volume. You will not retrofit this calmly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instrument the six metrics:&lt;/strong&gt; queue depth, per-workflow latency, per-node failures, GPU utilization, model cache hits, quality pass rate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run a 2x peak load test&lt;/strong&gt; before launch.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once your deployment is stable, the next question is how to integrate it into your application cleanly: endpoints, the &lt;code&gt;/prompt&lt;/code&gt; flow, image uploads, WebSocket versus polling, production integration patterns. That's the &lt;a href="https://www.runflow.io/blog/comfyui-api-developer-guide" rel="noopener noreferrer"&gt;complete guide to the ComfyUI API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Deployment is where most ComfyUI projects stall. It doesn't have to be. Five paths, one decision framework, and a few disciplines in common (queue, scoring, routing, environment promotion), and you're past the part that kills most teams. Everything beyond that is product work, which is the part you actually wanted to be doing anyway.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.runflow.io/blog/comfyui-deploy-self-host-serverless-managed" rel="noopener noreferrer"&gt;Runflow&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>comfyui</category>
      <category>deploy</category>
      <category>infrastructure</category>
      <category>production</category>
    </item>
    <item>
      <title>Nano Banana product photography: why it fails on shoes (2026)</title>
      <dc:creator>Ricardo Ghekiere (runflow)</dc:creator>
      <pubDate>Thu, 18 Jun 2026 21:19:40 +0000</pubDate>
      <link>https://dev.to/ricardoghekiere/nano-banana-product-photography-why-it-fails-on-shoes-2026-1l9e</link>
      <guid>https://dev.to/ricardoghekiere/nano-banana-product-photography-why-it-fails-on-shoes-2026-1l9e</guid>
      <description>&lt;p&gt;Thirty seconds to generate a product shot. Two more to fall for it. Then you zoom in and your stomach drops.&lt;/p&gt;

&lt;p&gt;That gap is the whole story of Nano Banana product photography right now.&lt;/p&gt;

&lt;p&gt;The shot looks like a finished campaign. The model is sitting there, the yellow shoes are on, the lighting is real. You would sign it off in a hurry. Then you read the text on the side of the shoe, and it is running the wrong way.&lt;/p&gt;

&lt;p&gt;We make AI product images for brands every week, so we hit this the expensive way. This post is the inside version: the one tagging trick that makes Nano Banana behave, the failure that kills the shot, and what we changed so it stops happening across hundreds of products.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/sISou-yA4Q4" rel="noopener noreferrer"&gt;https://youtu.be/sISou-yA4Q4&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The reference-tagging trick most Nano Banana users skip
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Tag each reference image by its role, then tell the model what not to touch.&lt;/strong&gt; Most people drop one photo in and hope. The cleaner way is to load every angle you have and label it.&lt;/p&gt;

&lt;p&gt;In our editor that looks like three references. Image 1 is the base photo you want the shoe added to. Image 2 is the side view of the shoe. Image 3 is the top view. The prompt then reads like an instruction, not a wish: "the top view of the yellow shoe is image 3, the side view is image 2, do not change anything else."&lt;/p&gt;

&lt;p&gt;Most brands do not even have a top view of their own product. That is fine. The point is to give the model every angle that exists so it has a fair reference to work from, instead of inventing the parts it cannot see.&lt;/p&gt;

&lt;p&gt;It costs you thirty seconds of setup. It saves you the reshoot.&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%2Fo6ugceo4x2mnf88xpw5x.jpg" 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%2Fo6ugceo4x2mnf88xpw5x.jpg" alt="Nano Banana product photography setup with reference images tagged image 1, 2 and 3 for the base photo and shoe views" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Nano Banana gives you, and why it looks fine
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On the first pass the output is clean and believable, which is exactly the problem.&lt;/strong&gt; You hit generate, the result comes back, and every quick check passes.&lt;/p&gt;

&lt;p&gt;You glance at it. You see the yellow shoe in the frame. The color is roughly right. The side reads something like "E level". Great, you think, the photoshoot worked.&lt;/p&gt;

&lt;p&gt;This is the moment that fools teams. The shot is 90% correct, and 90% correct reads as done when you are moving fast. Nobody zooms in on a render that already looks like a catalog page.&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%2Fnrpgqcsm58enh2ouqcam.jpg" 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%2Fnrpgqcsm58enh2ouqcam.jpg" alt="AI product photo generated by Nano Banana that looks correct at first glance" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Nano Banana quietly breaks on products
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The thing it gets wrong is text and orientation, and you will not catch it until someone points at it.&lt;/strong&gt; Zoom into the shoe and the letters are off. That part you can almost forgive.&lt;/p&gt;

&lt;p&gt;The real miss is direction. The text on this shoe, "E LOVE", is meant to run top to bottom. Nano Banana flipped it so it climbs upward instead. The letters are there, the word is almost readable, and the whole thing is wrong.&lt;/p&gt;

&lt;p&gt;Here is the rule we use now: if a human cannot cleanly read the text in your reference, the model cannot either. It will guess, and a guess on a logo is how you ship a shoe that no real store would sell. We wrote up the same failure on apparel in &lt;a href="https://www.runflow.io/blog/fix-ai-mangled-logos-on-garments" rel="noopener noreferrer"&gt;how to fix AI-mangled brand logos on garments&lt;/a&gt;.&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%2F160q6p77gz5k470668of.jpg" 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%2F160q6p77gz5k470668of.jpg" alt="Zoomed view of the AI generated shoe showing the E LOVE text rendered incorrectly" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why a "good enough" shot is still a hard pass
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;One reversed logo is a problem across a whole catalog when you are shooting hundreds of products.&lt;/strong&gt; At a single shoot, you catch it. You squint, you spot it, you regenerate.&lt;/p&gt;

&lt;p&gt;At three hundred products, you do not.&lt;/p&gt;

&lt;p&gt;That is the math that keeps brands off AI for real catalogs. A wrong image is a returned order, a confused customer, and a brand that looks careless on its own product page. The technology demos beautifully on one shoe. It falls over the moment volume removes the human who was checking each frame.&lt;/p&gt;

&lt;p&gt;So the question is not whether Nano Banana can make one great product shot. It can. The question is whether you can trust the next three hundred without looking at them.&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%2F8z8rfit4k4dt87vq8mf6.jpg" 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%2F8z8rfit4k4dt87vq8mf6.jpg" alt="The flipped E LOVE text on the AI generated shoe, the error that makes the shot unusable" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The fix: feed reliable data, not a flat photo
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Ground the edit in a 3D model of the product so the geometry and the text come from the real object.&lt;/strong&gt; A single photo gives the model a hint. A 3D file gives it the truth.&lt;/p&gt;

&lt;p&gt;We run the same input through a workflow with a 3D preset, a &lt;code&gt;.glb&lt;/code&gt; or &lt;code&gt;.fbx&lt;/code&gt; of the shoe. The "Refine with a 3D model" step re-renders the photo using the product's actual diffuse map and geometry, so the model is not inventing the parts it cannot see. It is reading them.&lt;/p&gt;

&lt;p&gt;The difference is immediate. The yellow now matches the real shoe instead of drifting a few shades off. And "E LOVE" runs the right way, top to bottom, because the text came from the model and not from a guess. That is the version you can put on a product page.&lt;/p&gt;

&lt;p&gt;This is the same approach we broke down in &lt;a href="https://www.runflow.io/blog/3d-to-product-photography" rel="noopener noreferrer"&gt;turning 3D files into photorealistic product photos&lt;/a&gt; and in &lt;a href="https://www.runflow.io/blog/3d-to-ai-product-images-at-scale" rel="noopener noreferrer"&gt;how we turn 3D files into product images at scale&lt;/a&gt;.&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%2Fojbkd9n2dywuq9j25i34.jpg" 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%2Fojbkd9n2dywuq9j25i34.jpg" alt="Running the same shoe input through a 3D model workflow preset for accurate product photography" width="800" height="516"&gt;&lt;/a&gt;&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%2Ff9mudfbogxwdo001smx2.jpg" 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%2Ff9mudfbogxwdo001smx2.jpg" alt="The corrected AI product photo with matching yellow color and text running the right way" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Catching the errors you cannot eyeball
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At volume you need a check that flags the bad frame before it ships, not a person squinting at every render.&lt;/strong&gt; The 3D model fixes the input. The quality pass fixes the output.&lt;/p&gt;

&lt;p&gt;Every render runs through a set of checks that look at the image and call out what is off. Something wrong on the bottom of the shoe, a logo that reads backwards, a color that drifted. The system marks it, you fix that one, and the rest move on. The little "checks pass" badge in the corner is doing the job a tired human used to do at 11pm before a launch.&lt;/p&gt;

&lt;p&gt;That is the half nobody talks about. Reliable images at scale need reliable data going in and an automatic check on the way out. Skip either one and you are back to manual review, which does not survive past a few dozen products. We tested where these checks matter most in &lt;a href="https://www.runflow.io/blog/product-isolation-failures" rel="noopener noreferrer"&gt;the failure modes that kill production AI product isolation&lt;/a&gt;.&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%2F2a4fv3ylc6o40dvg9l7o.jpg" 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%2F2a4fv3ylc6o40dvg9l7o.jpg" alt="Automated quality check highlighting an error on an AI generated product photo" width="800" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Running this from one shoot to thousands
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Once the workflow is right, you call it as an API and the same logic runs on every product without a person in the loop.&lt;/strong&gt; The demo above is a UI. The thing that scales is the endpoint behind it.&lt;/p&gt;

&lt;p&gt;The shape is simple: POST your inputs to the model's run endpoint, then poll for the result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://api.runflow.io/v1/models/google/nano-banana-pro/runs &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer rf_live_your_key"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "input": {
      "prompt": "place the yellow shoe on the model, keep the logo orientation exactly as the reference, do not change anything else",
      "image_urls": [
        "https://yourapp.com/base.jpg",
        "https://yourapp.com/shoe-side.jpg",
        "https://yourapp.com/shoe-top.jpg"
      ]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get back a run ID. Poll it until the status is finished:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://api.runflow.io/v1/runs/RUN_ID &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer rf_live_your_key"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You pay a simple fixed price per call, and you do not need to keep a GPU team warm to make it run. The model surface, including the Pro and edit variants, lives on the &lt;a href="https://www.runflow.io/run/nano-banana" rel="noopener noreferrer"&gt;Nano Banana run page&lt;/a&gt;. If your real workflow is more than one model call, the 3D step plus the QA step plus the edit, you can ship the whole graph as one endpoint with &lt;a href="https://www.runflow.io/deploy" rel="noopener noreferrer"&gt;ComfyUI Deploy&lt;/a&gt;. The full path from a ComfyUI test to production is in &lt;a href="https://www.runflow.io/blog/nano-banana-api" rel="noopener noreferrer"&gt;run the Nano Banana API, then take it to production&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Raw Nano Banana vs a 3D-grounded workflow
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The difference is not the model. It is what you feed it and what you check on the way out.&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;&lt;/th&gt;
&lt;th&gt;Raw single-photo edit&lt;/th&gt;
&lt;th&gt;3D-grounded workflow&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Color accuracy&lt;/td&gt;
&lt;td&gt;Drifts a few shades&lt;/td&gt;
&lt;td&gt;Matches the real product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logo and text orientation&lt;/td&gt;
&lt;td&gt;Guessed, often flipped&lt;/td&gt;
&lt;td&gt;Read from the 3D model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catching a bad frame&lt;/td&gt;
&lt;td&gt;Manual, by eye&lt;/td&gt;
&lt;td&gt;Automatic quality checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works at one shoot&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Works at one thousand&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;&lt;strong&gt;Can Nano Banana do product photography?&lt;/strong&gt;&lt;br&gt;
Yes, for a single shot it is very good. The trouble shows up at volume and on fine detail like logos and text, where it tends to guess and sometimes flips the orientation. For a catalog you want a workflow that grounds the edit in real product data and checks every output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why does Nano Banana flip text and logos on products?&lt;/strong&gt;&lt;br&gt;
The model works from a flat reference image. When the text is small or partly hidden, it reconstructs what it thinks should be there instead of copying the exact letters and direction. If a human cannot clearly read the text in your reference, the model usually cannot either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the image-tagging trick?&lt;/strong&gt;&lt;br&gt;
You load each reference photo and label it by role, then point the prompt at the labels. For example, image 1 is the base photo, image 2 is the side view, image 3 is the top view, and the prompt says which is which and what to leave alone. It gives the model every angle that exists instead of letting it invent the parts it cannot see.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I fix the color being slightly off?&lt;/strong&gt;&lt;br&gt;
Feed a 3D model of the product so the render reads the actual diffuse map instead of sampling color from one photo. The "refine with a 3D model" step pulls the real material, so the yellow stays the same yellow across every shot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I need a 3D file for every product?&lt;/strong&gt;&lt;br&gt;
For high-volume catalogs it pays off fast, because the 3D file fixes color, geometry, and text in one pass. For a one-off shot you can often get away with good reference tagging alone. The more products you run, the more a 3D source earns its place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I check AI product images at scale?&lt;/strong&gt;&lt;br&gt;
Run every render through automatic quality checks that flag the bad frames, then only review the ones that fail. Reviewing every image by eye stops working past a few dozen products, which is where most AI photoshoot projects quietly die.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this cheaper than a real photoshoot?&lt;/strong&gt;&lt;br&gt;
For a large catalog, yes, once the workflow is set up. You skip the studio, the reshoots, and the per-product cost drops sharply. The setup work is the 3D source and the checks, and that is the part that makes the savings hold.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I call this as an API?&lt;/strong&gt;&lt;br&gt;
Yes. POST your prompt and reference images to the model's run endpoint and poll the run ID for the result. The same code runs the same workflow on one product or one thousand, with simple fixed pricing per call.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which model should I use for product shots?&lt;/strong&gt;&lt;br&gt;
Start with Nano Banana for identity-preserving edits, since that is its strength. Then ground it with a 3D source and add the quality pass. The model matters less than the data you give it and the check you run after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to go next
&lt;/h2&gt;

&lt;p&gt;You have both halves now: the tagging trick that makes Nano Banana behave, and the 3D-plus-QA workflow that makes it survive a real catalog. Here is the order that works.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Tag your references by role and tell the model what not to touch.&lt;/li&gt;
&lt;li&gt;Generate, then zoom in on every logo and line of text before you trust the shot.&lt;/li&gt;
&lt;li&gt;For anything you sell, ground the edit in a 3D file so color and text come from the real product. See &lt;a href="https://www.runflow.io/blog/3d-to-product-photography" rel="noopener noreferrer"&gt;turning 3D files into photorealistic product photos&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add an automatic quality check so a bad frame gets flagged, not shipped.&lt;/li&gt;
&lt;li&gt;Test the model on your own products on the &lt;a href="https://www.runflow.io/run/nano-banana" rel="noopener noreferrer"&gt;Nano Banana run page&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;When the volume is real, ship the whole workflow as one endpoint with &lt;a href="https://www.runflow.io/deploy" rel="noopener noreferrer"&gt;ComfyUI Deploy&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start free at &lt;a href="https://www.runflow.io" rel="noopener noreferrer"&gt;runflow.io&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.runflow.io/blog/nano-banana-product-photography" rel="noopener noreferrer"&gt;Runflow&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>videosource</category>
      <category>nanobananaproductphotography</category>
      <category>aiproductphotography</category>
      <category>aiphotoshoot</category>
    </item>
    <item>
      <title>Portrait Generation Benchmark Q1 2026: Flux.2 vs SDXL vs Proprietary</title>
      <dc:creator>Ricardo Ghekiere (runflow)</dc:creator>
      <pubDate>Thu, 18 Jun 2026 20:55:04 +0000</pubDate>
      <link>https://dev.to/ricardoghekiere/portrait-generation-benchmark-q1-2026-flux2-vs-sdxl-vs-proprietary-54fe</link>
      <guid>https://dev.to/ricardoghekiere/portrait-generation-benchmark-q1-2026-flux2-vs-sdxl-vs-proprietary-54fe</guid>
      <description>&lt;p&gt;Every quarter, we benchmark every major image generation model against real production workloads from our platform. Not synthetic tests, actual jobs from customers generating AI headshots at scale.&lt;/p&gt;

&lt;p&gt;This quarter, we tested &lt;strong&gt;8 models&lt;/strong&gt; across &lt;strong&gt;12,000 inference jobs&lt;/strong&gt;, scoring each on quality (FID, CLIP, human eval), cost per image, and p95 latency. Here’s the full breakdown.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why We Benchmark Differently
&lt;/h2&gt;

&lt;p&gt;Most model comparisons use academic datasets, ImageNet, LAION, curated prompt sets. That’s useful for research, but it tells you nothing about how a model performs on &lt;em&gt;your&lt;/em&gt; workload.&lt;/p&gt;

&lt;p&gt;At Runflow, we route tens of thousands of real inference jobs per day. We see exactly how models perform on corporate headshots, e-commerce product photos, and creative portraits, the actual use cases customers care about.&lt;/p&gt;

&lt;p&gt;Our Sentinel evaluation engine scores every output automatically across three dimensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FID Score&lt;/strong&gt; — Measures distributional similarity to high-quality reference sets, per niche&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CLIP Alignment&lt;/strong&gt; — How well the output matches the input prompt and reference image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human Eval&lt;/strong&gt; — Blind A/B testing with trained evaluators (n=500 per model pair)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Models
&lt;/h2&gt;

&lt;p&gt;We tested the following models, all running on our multi-cloud orchestration layer to normalize for infrastructure differences:&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;Version&lt;/th&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flux.2 [dev]&lt;/td&gt;
&lt;td&gt;v2.0.1&lt;/td&gt;
&lt;td&gt;Open Source&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Flux.2 [schnell]&lt;/td&gt;
&lt;td&gt;v2.0.1&lt;/td&gt;
&lt;td&gt;Open Source&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDXL Lightning&lt;/td&gt;
&lt;td&gt;4-step&lt;/td&gt;
&lt;td&gt;Open Source&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SDXL Turbo&lt;/td&gt;
&lt;td&gt;1-step&lt;/td&gt;
&lt;td&gt;Open Source&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proprietary A&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Closed Source&lt;/td&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proprietary B&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;Closed Source&lt;/td&gt;
&lt;td&gt;API&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Results: Quality Scores
&lt;/h2&gt;

&lt;p&gt;The composite quality score combines FID (40%), CLIP alignment (30%), and human evaluation (30%). All scores are normalized to a 0–100 scale.&lt;/p&gt;

&lt;p&gt;The headline: &lt;strong&gt;Flux.2 [dev] scored 95&lt;/strong&gt;, matching or exceeding proprietary models across all three evaluation dimensions. For the first time in our benchmarks, an open-source model leads the portrait generation category outright.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results: Cost per Image
&lt;/h2&gt;

&lt;p&gt;Cost calculations include GPU compute, orchestration overhead, and our platform fee. All models were run on equivalent hardware (A100 80GB) through our multi-cloud orchestration layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results: Latency (p95)
&lt;/h2&gt;

&lt;p&gt;Latency was measured end-to-end from API request to image delivery, including model loading (cold start) and network transfer. All measurements are p95 across the full 12K job dataset.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SDXL Turbo:&lt;/strong&gt; 0.8s — Single step, extremely fast&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flux.2 [schnell]:&lt;/strong&gt; 1.2s — 4 steps, excellent tradeoff&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SDXL Lightning:&lt;/strong&gt; 1.4s — 4 steps, solid performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flux.2 [dev]:&lt;/strong&gt; 4.8s — 20 steps, highest quality&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proprietary A:&lt;/strong&gt; 6.2s — API overhead adds latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proprietary B:&lt;/strong&gt; 8.1s — Slowest, queue-based&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Open source has caught up.&lt;/strong&gt; Flux.2 [dev] matches proprietary quality at a fraction of the compute cost. The moat for closed-source portrait models is effectively gone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speed vs quality is a real tradeoff.&lt;/strong&gt; SDXL Turbo is 6x faster than Flux.2 [dev] but scores 13 points lower. Choose based on your use case.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-niche scoring matters.&lt;/strong&gt; SDXL Lightning beats Flux.2 [schnell] on corporate headshots but loses on creative portraits. Aggregate scores hide important nuances.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability is infrastructure, not model choice.&lt;/strong&gt; The same model can have wildly different uptime depending on your GPU provider. Runflow routes across multiple datacenters for consistent availability.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Methodology Notes
&lt;/h2&gt;

&lt;p&gt;All benchmark results are reproducible. We publish our evaluation pipeline, reference datasets, and scoring rubrics in our &lt;a href="https://github.com/runflow" rel="noopener noreferrer"&gt;open benchmark repository&lt;/a&gt;. If you find discrepancies, we want to know—open an issue or reach out directly.&lt;/p&gt;

&lt;p&gt;Models labeled “Proprietary A” and “Proprietary B” are anonymized per our testing agreements. We’ll name them explicitly once we have permission from the providers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;Q2 benchmarks will expand to include video generation models (Wan2.6, Kling 2.1, Seedance) and our new virtual try-on pipeline. We’re also adding latency-under-load testing to simulate real production traffic patterns.&lt;/p&gt;

&lt;p&gt;Want to run these benchmarks on your own workload? &lt;a href="https://cal.com/team/runflow/talk-to-founders?duration=25" rel="noopener noreferrer"&gt;Talk to our team&lt;/a&gt; — we’ll set up a custom evaluation against your production data.&lt;/p&gt;

&lt;p&gt;Test&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://www.runflow.io/blog/portrait-generation-benchmark-q1-2026" rel="noopener noreferrer"&gt;Runflow&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>benchmark</category>
      <category>portraits</category>
      <category>flux2</category>
      <category>sdxl</category>
    </item>
    <item>
      <title>I Generated 35 Million AI Images. The Model Was Never the Product.</title>
      <dc:creator>Ricardo Ghekiere (runflow)</dc:creator>
      <pubDate>Sun, 12 Apr 2026 22:23:01 +0000</pubDate>
      <link>https://dev.to/ricardoghekiere/i-generated-35-million-ai-images-the-model-was-never-the-product-2n9j</link>
      <guid>https://dev.to/ricardoghekiere/i-generated-35-million-ai-images-the-model-was-never-the-product-2n9j</guid>
      <description>&lt;p&gt;Most teams building with AI image generation APIs obsess over which model to use. FLUX or Stable Diffusion? Which checkpoint? Which LoRA?&lt;/p&gt;

&lt;p&gt;I ran an AI headshot company that generated over 35 million images in two years. Crossed $2.2M in revenue. Hit 87% gross margins. And the model we used was open source. Free.&lt;/p&gt;

&lt;p&gt;The model was never what made it work. The workflow around the model was.&lt;/p&gt;

&lt;p&gt;Here's what I learned building AI image pipelines at scale, and why most teams get the architecture completely wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "generate and pray" problem
&lt;/h2&gt;

&lt;p&gt;Here's how most teams ship AI-generated images today:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User sends a request&lt;/li&gt;
&lt;li&gt;Call an image generation API&lt;/li&gt;
&lt;li&gt;Return whatever comes back&lt;/li&gt;
&lt;li&gt;Hope it's good&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works fine at 10 images a day. It breaks completely at 10,000.&lt;/p&gt;

&lt;p&gt;At scale, defects become statistical certainties. Face distortions. Wrong backgrounds. Artifacts that look fine at thumbnail size and horrific at full resolution. Skin tone inconsistencies. Missing fingers (the classic).&lt;/p&gt;

&lt;p&gt;When you generate 100 images, you might get lucky. When you generate 100,000, you will ship garbage. Guaranteed. The only question is how much.&lt;/p&gt;

&lt;p&gt;We learned this the hard way. Our first month running AI headshots, we generated a batch of images for a customer and delivered them without any automated QA. The customer's feedback: "Why does my colleague have three ears?"&lt;/p&gt;

&lt;p&gt;That was the last time we shipped without scoring.&lt;/p&gt;

&lt;h2&gt;
  
  
  The assembly line, not the craftsman
&lt;/h2&gt;

&lt;p&gt;In 1913, a skilled craftsman took 12 hours to build a single car chassis. Henry Ford didn't hire a better craftsman. He built the assembly line. Specialized stations. Quality inspection at every step. Rework loops when something failed. Result: 93 minutes per chassis. 8x faster. 69% cheaper.&lt;/p&gt;

&lt;p&gt;Most AI image teams today are still in the craftsman era. One model call. One output. Ship it.&lt;/p&gt;

&lt;p&gt;What we built instead was an assembly line for AI images. Three distinct layers, each solving a different problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: Generate more than you need
&lt;/h2&gt;

&lt;p&gt;This sounds wasteful. It's the opposite.&lt;/p&gt;

&lt;p&gt;For every customer request, we didn't generate 1 image. We generated 240 candidates. Only the best 60 made it to the customer. The other 180 went straight to the trash.&lt;/p&gt;

&lt;p&gt;The math works because GPU time is cheap compared to a bad customer experience. At our volumes, generating 4x more candidates added roughly $0.02 per delivered image. A single refund from a bad image costs 100x that.&lt;/p&gt;

&lt;p&gt;The key insight: treat image generation like a funnel, not a function call. You're not calling an API. You're running a selection process.&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;# Simplified version of our generation loop
&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&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;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="n"&gt;num_candidates&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;generate_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;seed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;random_seed&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nf"&gt;select_cheapest_available_provider&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Score all candidates
&lt;/span&gt;&lt;span class="n"&gt;scored&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;quality_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;candidates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Deliver only what passes threshold
&lt;/span&gt;&lt;span class="n"&gt;delivered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scored&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;threshold&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Layer 2: Score everything before it ships
&lt;/h2&gt;

&lt;p&gt;This is where most teams have a blind spot. They generate images but have no automated way to evaluate whether the output is actually good.&lt;/p&gt;

&lt;p&gt;We built a three-tier scoring system:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 1: Generic quality.&lt;/strong&gt; Does the image have artifacts? Is it sharp? Does it match the prompt? These checks apply to every single image regardless of use case. Think of it as a basic sanity check.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 2: Use-case specific.&lt;/strong&gt; For headshots, this meant: face fidelity, expression naturalness, skin tone consistency, lighting quality, background coherence. A perfectly sharp image with a distorted face is still unusable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tier 3: Custom rules.&lt;/strong&gt; Business-specific criteria. "No visible branding in the background." "Skin tone must be within 2 stops of reference." "Eyes must be open." Whatever the client cares about.&lt;/p&gt;

&lt;p&gt;Each dimension gets scored independently. The final decision isn't a single number. It's a pass/fail across all dimensions, with configurable thresholds.&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;quality_score&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="c1"&gt;# Tier 1: Generic
&lt;/span&gt;    &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;artifacts&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="nf"&gt;detect_artifacts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sharpness&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="nf"&gt;measure_sharpness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;prompt_alignment&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="nf"&gt;clip_similarity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Tier 2: Use-case specific
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;use_case&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;headshot&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;face_fidelity&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="nf"&gt;score_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;expression&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="nf"&gt;score_expression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;skin_tone&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="nf"&gt;score_skin_consistency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reference&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Tier 3: Custom rules
&lt;/span&gt;    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;custom_rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Pass/fail per dimension
&lt;/span&gt;    &lt;span class="n"&gt;passed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dim&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;thresholds&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;dim&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;dim&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ScoredImage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;passed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result: we eliminated manual QA entirely. No human ever looked at the rejected images. The scoring layer caught everything.&lt;/p&gt;

&lt;p&gt;When we didn't have this (early days), our customer support tickets were 40% image quality complaints. After implementing automated scoring, they dropped to under 3%.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Route to the cheapest GPU that can do the job
&lt;/h2&gt;

&lt;p&gt;This is the one nobody talks about.&lt;/p&gt;

&lt;p&gt;When you're calling AI image generation APIs at scale, you're probably using one provider. Maybe &lt;a href="http://fal.ai" rel="noopener noreferrer"&gt;fal.ai&lt;/a&gt;, maybe Replicate, maybe &lt;a href="http://Together.ai" rel="noopener noreferrer"&gt;Together.ai&lt;/a&gt;. You picked one, integrated it, and moved on.&lt;/p&gt;

&lt;p&gt;That's leaving money on the table.&lt;/p&gt;

&lt;p&gt;We built a routing layer that checked multiple providers on every single request and sent the job to the cheapest one that was currently available and fast enough.&lt;/p&gt;

&lt;p&gt;Why this matters: provider pricing varies wildly. Not just between providers, but within the same provider over time. Spot pricing changes. Capacity fluctuates. Cold start times spike during peak hours.&lt;/p&gt;

&lt;p&gt;Some real numbers from our routing data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider scenario&lt;/th&gt;
&lt;th&gt;Cost per image (1 megapixel)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single provider, no routing&lt;/td&gt;
&lt;td&gt;$0.035&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cheapest provider at any given moment&lt;/td&gt;
&lt;td&gt;$0.012&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;With fallback on timeout/error&lt;/td&gt;
&lt;td&gt;$0.014&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That's a 60-65% cost reduction just from routing. At 100K+ images per month, this is the difference between a viable business and burning cash.&lt;/p&gt;

&lt;p&gt;The routing decision is simple in concept:&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="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;select_provider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_healthy_providers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Filter by capability
&lt;/span&gt;    &lt;span class="n"&gt;capable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;supports&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

    &lt;span class="c1"&gt;# Sort by current effective cost
&lt;/span&gt;    &lt;span class="n"&gt;capable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;current_cost_per_image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requirements&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

    &lt;span class="c1"&gt;# Return cheapest, with fallback chain
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;capable&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="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;capable&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;fallback_provider&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice, there's more to it. You need health checking (is this provider actually responding right now?), timeout handling (if it takes too long, abort and retry on a different provider), and cost tracking (did the actual cost match what we expected?).&lt;/p&gt;

&lt;p&gt;But the basic pattern is dead simple: check what's available, pick the cheapest, have a fallback.&lt;/p&gt;

&lt;h2&gt;
  
  
  The numbers that convinced me
&lt;/h2&gt;

&lt;p&gt;Before the routing and scoring layers, our unit economics looked like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;COGS: ~40% of revenue&lt;/li&gt;
&lt;li&gt;Customer complaints about quality: ~40% of support tickets&lt;/li&gt;
&lt;li&gt;Manual QA required: yes, for every batch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;COGS: 11% of revenue&lt;/li&gt;
&lt;li&gt;Quality complaints: under 3% of tickets&lt;/li&gt;
&lt;li&gt;Manual QA: zero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gross margins went from roughly 60% to 87%. On the same models. Same images. Same customers. The only thing that changed was the workflow around the model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this pattern works for any AI image use case
&lt;/h2&gt;

&lt;p&gt;We started with headshots. But the pattern applies everywhere.&lt;/p&gt;

&lt;p&gt;Background removal? Same thing. Commercial APIs charge $0.02 to $0.20 per image. Self-hosted open source models can do it for $0.0004. But only if you have the routing and quality layers to handle provider failures, cold starts, and the occasional garbage output.&lt;/p&gt;

&lt;p&gt;Product photography? Virtual try-on? Ad creative generation? The specific models change. The scoring dimensions change. But the architecture stays the same:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate more candidates than you need&lt;/li&gt;
&lt;li&gt;Score every candidate automatically&lt;/li&gt;
&lt;li&gt;Route to the cheapest capable provider&lt;/li&gt;
&lt;li&gt;Only deliver what passes your quality bar&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's not complicated. It's just a pattern most teams haven't adopted yet because they're still in the "call one API and hope" phase.&lt;/p&gt;

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

&lt;p&gt;If I were starting a new AI image product today, I'd build the scoring layer before I built the product. Not after. Not when quality becomes a problem. Before.&lt;/p&gt;

&lt;p&gt;Here's why: the scoring layer changes what's possible. When you can automatically evaluate quality, you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use cheaper models and compensate with volume&lt;/li&gt;
&lt;li&gt;Switch providers without regression testing every image by hand&lt;/li&gt;
&lt;li&gt;Set up automated retry loops (generate, score, regenerate if failed)&lt;/li&gt;
&lt;li&gt;Give customers quality guarantees instead of quality hopes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model is a commodity. There are hundreds of them. New ones every week. The workflow is the moat.&lt;/p&gt;

&lt;h2&gt;
  
  
  What we're building now
&lt;/h2&gt;

&lt;p&gt;We took everything we learned from generating 35 million images and turned it into &lt;a href="https://www.runflow.io" rel="noopener noreferrer"&gt;Runflow&lt;/a&gt;. It's the infrastructure layer we wish existed when we started: automated quality evaluation, multi-provider routing, one-click deployment for ComfyUI workflows. The things that took us two years to build from scratch.&lt;/p&gt;

&lt;p&gt;If you're running AI image generation at any kind of scale and want to compare notes, I'm always up for a conversation. Find me on &lt;a href="https://www.linkedin.com/in/ricardoghekiere/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or drop a comment.&lt;/p&gt;

&lt;p&gt;The model is never the product. The workflow is the product.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Ricardo Ghekiere, CEO at &lt;a href="https://www.runflow.io" rel="noopener noreferrer"&gt;Runflow&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nanobanana</category>
      <category>infrastructure</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
