> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dodopayments.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Midjourney Billing Model

> Deconstruct Midjourney's GPU-time subscription with Relax Mode fallback and build the same model using Dodo Payments.

Midjourney is a generative AI platform that bills by GPU time instead of by image count. A complex, high-resolution render uses more GPU time, and so more of the plan, than a quick low-resolution draft.

## How Midjourney Bills

Each Midjourney subscription includes a monthly allowance of "Fast GPU Time", the computing time spent on your generations. The figures below come from [Midjourney's plan comparison](https://docs.midjourney.com/hc/en-us/articles/27870484040333-Comparing-Midjourney-Plans).

| Plan | Price | Fast GPU Hours | Relax Mode | Stealth Mode |
| :- | :- | :- | :- | :- |
| Basic | \$10/month | \~3.3 hrs | No | No |
| Standard | \$30/month | 15 hrs | Unlimited | No |
| Pro | \$60/month | 30 hrs | Unlimited | Yes |
| Mega | \$120/month | 60 hrs | Unlimited | Yes |

1. **Pricing Tiers**: Midjourney offers four subscription levels from \$10 to \$120 per month. Each includes a set amount of Fast GPU time.
2. **Relax Mode**: Standard and higher plans include unlimited image generations in a low-priority queue after Fast time runs out, so users don't hit a hard wall.
3. **Extra GPU Hours**: Users can buy extra Fast GPU time for \$4 per hour when they need fast results after using their monthly allowance.
4. **Metering in GPU Seconds**: Usage is measured as the GPU time each generation takes, so complex renders cost more than simple drafts.
5. **Community Loop**: Users can earn free GPU time by rating images, which also helps train Midjourney's models.

## What Makes It Unique

The Midjourney model ties what a user pays to the resources they consume:

* **GPU-time billing** prices complex renders higher than simple drafts, in line with their compute cost.
* **Relax Mode** is an unlimited fallback that reduces churn, because users keep access after the monthly allowance runs out.
* **The Fast vs Relax split** encourages upgrades by selling priority processing to users who value speed.
* **Extra GPU Hours** give power users a mid-month top-up for high-priority capacity.

## Build This with Dodo Payments

You can build this model with Dodo Payments by combining subscriptions, usage meters, and logic in your application.

<Steps>
  <Step title="Create a Usage Meter">
    Create a meter that tracks the GPU seconds each customer uses.

    * **Event name**: `gpu.fast_seconds`
    * **Aggregation**: **Sum**, with `gpu_seconds` as the **Over Property**

    Send events only for Fast mode generations. Relax mode generations aren't metered for billing.
  </Step>

  <Step title="Create Subscription Products with Usage Pricing">
    Create your subscription products and add the usage meter with a **Free Threshold** equal to the plan's Fast GPU allowance.

    | Product | Base Price | Free Threshold (seconds) | Overage Rate |
    | :- | :- | :- | :- |
    | Basic | \$10/month | 12,000 (3.3 hrs) | N/A (Hard Cap) |
    | Standard | \$30/month | 54,000 (15 hrs) | \$0.00 (Relax Mode) |
    | Pro | \$60/month | 108,000 (30 hrs) | \$0.00 (Relax Mode) |
    | Mega | \$120/month | 216,000 (60 hrs) | \$0.00 (Relax Mode) |

    Set the price per unit to \$0 on every plan, so usage above the threshold isn't charged. Dodo Payments doesn't stop usage at the threshold. Your application enforces the Basic plan's hard cap and routes the other plans to Relax Mode once the meter passes the threshold.
  </Step>

  <Step title="Implement Application-Level Relax Mode">
    Relax Mode isn't a billing feature. Your application sends requests to a slower queue when the Dodo Payments usage meter shows the customer has passed the plan's threshold.

    ```typescript theme={null}
    // getCustomerUsage, getSubscription, getThresholdForPlan, and queueGeneration are
    // your application's own functions. getCustomerUsage can sum this cycle's events
    // from client.usageEvents.list() or read a counter your app maintains.
    async function handleGenerationRequest(customerId: string, prompt: string) {
      const usage = await getCustomerUsage(customerId, 'gpu.fast_seconds');
      const subscription = await getSubscription(customerId);
      const threshold = getThresholdForPlan(subscription.product_id);
      
      if (usage.current >= threshold) {
        if (subscription.product_id === 'pdt_basic') {
          throw new Error('Fast GPU hours exhausted. Upgrade to Standard for Relax Mode.');
        }
        
        // Relax Mode. Route to low-priority queue
        return await queueGeneration(customerId, prompt, {
          priority: 'low',
          mode: 'relax',
          model: 'standard'
        });
      }
      
      // Fast Mode. Priority processing
      return await queueGeneration(customerId, prompt, {
        priority: 'high',
        mode: 'fast',
        model: 'premium'
      });
    }
    ```
  </Step>

  <Step title="Send Usage Events (Fast Mode Only)">
    Send a usage event to Dodo Payments only when a generation runs in Fast mode.

    ```typescript theme={null}
    import DodoPayments from 'dodopayments';

    async function trackFastGeneration(customerId: string, gpuSeconds: number, jobId: string) {
      // Only track Fast mode generations. Relax mode is free and unlimited
      const client = new DodoPayments({
        bearerToken: process.env.DODO_PAYMENTS_API_KEY,
      });

      await client.usageEvents.ingest({
        events: [{
          event_id: `gen_${jobId}`,
          customer_id: customerId,
          event_name: 'gpu.fast_seconds',
          timestamp: new Date().toISOString(),
          metadata: {
            gpu_seconds: gpuSeconds,
            resolution: '1024x1024',
            mode: 'fast'
          }
        }]
      });
    }
    ```
  </Step>

  <Step title="Sell Extra Fast Hours (One-Time Top-Up)">
    Create a one-time payment product called "Extra Fast GPU Hour" priced at \$4. When a customer buys it, raise their threshold in your application by 3,600 seconds per hour purchased.

    ```typescript theme={null}
    // After customer purchases extra hours
    const session = await client.checkoutSessions.create({
      product_cart: [
        { product_id: 'pdt_extra_gpu_hour', quantity: 5 }
      ],
      customer: { customer_id: customerId },
      return_url: 'https://yourapp.com/dashboard'
    });
    ```
  </Step>

  <Step title="Create Checkout for Subscription">
    Create a checkout session for the subscription plan.

    ```typescript theme={null}
    const session = await client.checkoutSessions.create({
      product_cart: [
        { product_id: 'pdt_mj_standard', quantity: 1 }
      ],
      customer: { email: 'artist@example.com' },
      return_url: 'https://yourapp.com/studio'
    });
    ```
  </Step>
</Steps>

## Accelerate with the Time Range Ingestion Blueprint

The [Time Range Ingestion Blueprint](/developer-resources/ingestion-blueprints/time-range) provides helpers for duration-based billing that make GPU time tracking shorter to write.

```bash theme={null}
npm install @dodopayments/ingestion-blueprints
```

```typescript theme={null}
import { Ingestion, trackTimeRange } from '@dodopayments/ingestion-blueprints';

const ingestion = new Ingestion({
  apiKey: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'live_mode',
  eventName: 'gpu.fast_seconds',
});

// runGeneration, prompt, settings, and customerId come from your application.
const startTime = Date.now();
const result = await runGeneration(prompt, settings);
const durationMs = Date.now() - startTime;

await trackTimeRange(ingestion, {
  customerId: customerId,
  durationMs: durationMs,
  metadata: {
    mode: 'fast',
    resolution: '1024x1024',
  },
});
```

The blueprint builds the event and sends the duration in its metadata. You provide the customer ID and the elapsed time. This example sends `durationMs`, so set the meter's **Over Property** to `durationMs`, or send `durationSeconds` to match a meter over seconds.

<Tip>
  The Time Range Blueprint accepts durations in milliseconds, seconds, or minutes. See the [full blueprint documentation](/developer-resources/ingestion-blueprints/time-range) for all duration options and best practices.
</Tip>

## The Fast vs Relax Architecture

The two queues work by routing each request based on the customer's current usage.

```mermaid theme={null}
flowchart TD
    A[Generation Request] --> B{GPU Usage < Threshold?}
    B -->|Yes| C[Fast Queue]
    C --> D[Priority Processing]
    D --> E[Meter GPU Seconds]
    B -->|No| F{Plan Has Relax Mode?}
    F -->|Yes| G[Relax Queue]
    G --> H[Low Priority, Unmetered]
    F -->|No| I[Request Blocked]
```

1. All requests go through your application.
2. The application compares the customer's Fast GPU usage with the plan's free threshold.
3. If usage is under the threshold, the request goes to the Fast queue and is metered.
4. If usage is over the threshold, the request goes to the Relax queue, which is unmetered and lower priority.
5. The Basic plan has no Relax fallback, so the application blocks requests once the limit is reached.

<Info>
  Relax Mode is an application-level pattern, not a Dodo Payments billing feature. Dodo Payments records your customers' Fast GPU usage. Your application decides whether to block the user or send them to a slower queue.
</Info>

## Key Dodo Features Used

<CardGroup cols={2}>
  <Card title="Subscriptions" icon="calendar" href="/features/subscription">
    Manage recurring billing and plan tiers.
  </Card>

  <Card title="Usage-Based Billing" icon="bolt" href="/features/usage-based-billing/introduction">
    Track and bill based on actual resource consumption.
  </Card>

  <Card title="Event Ingestion" icon="input-pipe" href="/features/usage-based-billing/event-ingestion">
    Send high-volume usage events to the Dodo Payments API.
  </Card>

  <Card title="Meters" icon="gauge" href="/features/usage-based-billing/meters">
    Define how usage events are aggregated and billed.
  </Card>

  <Card title="One-Time Payments" icon="credit-card" href="/features/one-time-payment-products">
    Sell extra hours or top-ups as one-time purchases.
  </Card>

  <Card title="Time Range Blueprint" icon="clock" href="/developer-resources/ingestion-blueprints/time-range">
    Simplified GPU time tracking with duration-based helpers.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.