<?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: Abraham Aragón</title>
    <description>The latest articles on DEV Community by Abraham Aragón (@abrahamaragon91).</description>
    <link>https://dev.to/abrahamaragon91</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%2F4080649%2F41fd37a8-e288-4ca3-8a0b-18682d524b90.png</url>
      <title>DEV Community: Abraham Aragón</title>
      <link>https://dev.to/abrahamaragon91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abrahamaragon91"/>
    <language>en</language>
    <item>
      <title>Designing an Honest “Unlimited” Generative AI Product: Credits, Queues, and Fair Use</title>
      <dc:creator>Abraham Aragón</dc:creator>
      <pubDate>Sun, 16 Aug 2026 22:50:54 +0000</pubDate>
      <link>https://dev.to/abrahamaragon91/designing-an-honest-unlimited-generative-ai-product-credits-queues-and-fair-use-15li</link>
      <guid>https://dev.to/abrahamaragon91/designing-an-honest-unlimited-generative-ai-product-credits-queues-and-fair-use-15li</guid>
      <description>&lt;p&gt;&lt;em&gt;Disclosure: I am building &lt;a href="https://donatello.studio/" rel="noopener noreferrer"&gt;Donatello.studio&lt;/a&gt;. This article describes the product and systems principles behind our access model; it is not an independent review.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Generative AI products have an uncomfortable cost structure. A text request may be inexpensive, while a long video or a complete song can consume orders of magnitude more compute. Yet users reasonably want a simple promise: they should be able to keep creating without discovering a surprise hard quota.&lt;/p&gt;

&lt;p&gt;The word &lt;strong&gt;unlimited&lt;/strong&gt; can describe that promise, but only if we define it precisely. It cannot mean infinite concurrent GPU jobs, zero latency, or immunity from abuse controls. A more defensible definition is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A compliant account has no fixed daily, monthly, or lifetime creation quota, and retains a route to submit work even when normal-priority funding inventory is temporarily unavailable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This post walks through a practical architecture for supporting that definition with credits, queues, fair-use controls, and explicit rights rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Separate access from priority
&lt;/h2&gt;

&lt;p&gt;The first design mistake is treating access and execution priority as the same thing. They are different product states.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access&lt;/strong&gt; answers: may this account submit a valid job?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Priority&lt;/strong&gt; answers: when should the job run relative to other jobs?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Concurrency&lt;/strong&gt; answers: how many jobs may the account run at once?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Throughput&lt;/strong&gt; answers: how quickly may new jobs enter the system?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A product can preserve access while lowering priority during heavy load. That is fundamentally different from returning a quota-exhausted error and forcing an upgrade.&lt;/p&gt;

&lt;p&gt;A small state model might look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NORMAL      -&amp;gt; funded credits, standard queue priority
CONTINUITY  -&amp;gt; no normal credits available, lower queue priority
THROTTLED   -&amp;gt; temporary rate or concurrency limit
BLOCKED     -&amp;gt; verified abuse, rights violation, or security action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Only the last state removes access, and it should require a documented reason. Capacity pressure by itself should move jobs between queues, not silently create a lifetime cap.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Make credits an accounting unit, not a paywall
&lt;/h2&gt;

&lt;p&gt;Credits are useful because different media types have different expected costs. They provide a common accounting layer across image, video, music, and voice generation.&lt;/p&gt;

&lt;p&gt;For a job, a basic estimate can combine model cost, duration, resolution and retry risk:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;estimated_cost = base_model_cost
               * duration_factor
               * resolution_factor
               * retry_risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The user-facing credit price does not need to expose raw provider cost, but the mapping should be stable enough to avoid surprises. Reserve credits before dispatch, then reconcile after completion if the provider reports actual usage.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if balance &amp;gt;= estimate:
    reserve(estimate)
    enqueue(job, priority=NORMAL)
else:
    enqueue(job, priority=CONTINUITY)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The critical design choice is the final branch. In a hard-quota product it becomes reject. In an access-preserving product it becomes a slower, tightly controlled queue.&lt;/p&gt;

&lt;p&gt;Credits can still be earned through optional free activities, partner-funded actions or referrals. Those activities finance normal-priority work. They should improve speed and capacity without becoming the only possible doorway to the product.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Treat partner inventory as volatile
&lt;/h2&gt;

&lt;p&gt;Survey and offer inventory varies by country, device, profile, time of day and partner demand. A user may have many activities today and none tomorrow. Designing as if inventory were constant creates geographical dead ends.&lt;/p&gt;

&lt;p&gt;Monitor at least:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;percentage of eligible sessions with zero activities;&lt;/li&gt;
&lt;li&gt;median credits earnable per user by country and device;&lt;/li&gt;
&lt;li&gt;completion-to-credit success rate;&lt;/li&gt;
&lt;li&gt;reversal and fraud rate;&lt;/li&gt;
&lt;li&gt;percentage of jobs entering continuity access;&lt;/li&gt;
&lt;li&gt;queue wait time by priority class.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to force every market into identical partner economics. The goal is to detect where the normal path is missing and ensure the fallback remains usable.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Build the continuity queue as a real product path
&lt;/h2&gt;

&lt;p&gt;A lower-priority queue should not be a fake button that never completes. It needs an explicit service policy.&lt;/p&gt;

&lt;p&gt;A scheduler can combine job age, expected cost and account trust:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;score = age_minutes * AGE_WEIGHT
      - estimated_cost * COST_WEIGHT
      + trust_score * TRUST_WEIGHT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This prevents small jobs from waiting forever behind expensive jobs while still allowing older work to advance. Useful safeguards include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one active continuity job per account;&lt;/li&gt;
&lt;li&gt;deduplication of identical submissions;&lt;/li&gt;
&lt;li&gt;cancellation before provider dispatch;&lt;/li&gt;
&lt;li&gt;idempotency keys for retries;&lt;/li&gt;
&lt;li&gt;provider-specific circuit breakers;&lt;/li&gt;
&lt;li&gt;transparent status messages and estimated wait bands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interface should say what is happening. “Queued with lower priority” is honest. An unexplained spinner is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Fair use must be behavioral, not arbitrary
&lt;/h2&gt;

&lt;p&gt;A fixed hidden number does not become fair use just because the Terms call it fair use. Controls should respond to behavior that threatens other users or the service.&lt;/p&gt;

&lt;p&gt;Signals can include automated bursts that exceed human interaction patterns, repeated duplicate submissions, many accounts sharing one identity, attempts to bypass concurrency controls and confirmed rights violations.&lt;/p&gt;

&lt;p&gt;Start with reversible actions: reduce concurrency, add cooldowns, require re-authentication or request verification. Reserve permanent blocks for strong evidence and provide an appeal path. Do not use high legitimate usage as an abuse signal by itself. The whole point of unlimited access is that a genuine power user is allowed to be a power user.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Commercial use is not the same as copyright-free
&lt;/h2&gt;

&lt;p&gt;The systems design is incomplete without rights design. A platform can grant commercial permission for output produced by its current routes, but it cannot manufacture rights in an input the user did not own.&lt;/p&gt;

&lt;p&gt;The product should distinguish:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Platform permission&lt;/strong&gt; — whether the Terms permit commercial use of eligible output.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Input rights&lt;/strong&gt; — whether the user may upload the image, recording, likeness or voice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal protectability&lt;/strong&gt; — whether the output qualifies for protection in a jurisdiction.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party claims&lt;/strong&gt; — whether the requested output infringes trademarks, publicity rights, privacy or other rights.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For voice and likeness features, explicit authorization controls are especially important. Clear attestation, logging, reporting and enforcement are better than burying responsibility in generic Terms.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Turn the promise into acceptance criteria
&lt;/h2&gt;

&lt;p&gt;Marketing language becomes safer when engineering and support can test it. Example acceptance criteria:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No compliant account is blocked solely because it crossed a fixed daily, monthly or lifetime count.&lt;/li&gt;
&lt;li&gt;When normal credits are unavailable, the user is offered a continuity submission path.&lt;/li&gt;
&lt;li&gt;Every accepted job exposes a queue state, cancellation state and terminal outcome.&lt;/li&gt;
&lt;li&gt;Capacity controls change priority, throughput or concurrency rather than inventing an undocumented permanent quota.&lt;/li&gt;
&lt;li&gt;Commercial-use language links to current Terms and never claims that all output is automatically copyright-free.&lt;/li&gt;
&lt;li&gt;Users are told that they need rights to inputs, likenesses and voices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These criteria can be covered by product tests, support audits and monitoring dashboards. They turn a vague promise into an operating contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trade-off
&lt;/h2&gt;

&lt;p&gt;The honest trade-off is simple: a free, no-fixed-quota service cannot guarantee instant execution for every workload. It can guarantee that compliant users are not pushed into a surprise purchase solely because they created too much.&lt;/p&gt;

&lt;p&gt;That is the standard we are applying at Donatello: no paid subscription or card required to start; no fixed daily, monthly or lifetime creation quota for compliant accounts; credits for normal priority earned through optional free activities; and continuity access governed by fair use, anti-abuse controls, queues and service capacity. Current production routes permit commercial use under the Terms, while users remain responsible for input and likeness rights.&lt;/p&gt;

&lt;p&gt;The phrase free and unlimited should never be the end of the explanation. It should be the short label for a system whose rules are understandable, observable and designed to keep access open.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>machinelearning</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
