.do

Tiered Pricing Models

Scale pricing based on volume with tier-based discounting strategies

Tiered pricing adjusts rates based on consumption volume, rewarding high-volume customers with better pricing while maximizing revenue from all segments. This model incentivizes growth and provides predictable scaling economics.

When to Use Tiered Pricing

Best for:

  • Services with low marginal costs
  • High-volume usage patterns
  • Customer growth incentives
  • Market segmentation strategies
  • Scale economies you can pass on

Not ideal for:

  • High fixed costs per unit
  • Minimal volume variation
  • Complex value propositions
  • Services with flat cost structures

Core Patterns

Pattern 1: Volume-Based Tiers

Charge different rates based on total usage volume:

import $, { db, on, send } from 'sdk.do'

const dataProcessingService = await $.Service.create({
  name: 'Data Processing Pipeline',
  type: $.ServiceType.DataProcessing,

  pricing: {
    model: 'volume-tiered',
    unit: 'gigabyte',
    tiers: [
      {
        name: 'tier-1',
        min: 0,
        max: 100,
        rate: 0.1, // $0.10/GB for first 100 GB
      },
      {
        name: 'tier-2',
        min: 100,
        max: 1000,
        rate: 0.08, // $0.08/GB for 100-1,000 GB
      },
      {
        name: 'tier-3',
        min: 1000,
        max: 10000,
        rate: 0.06, // $0.06/GB for 1,000-10,000 GB
      },
      {
        name: 'tier-4',
        min: 10000,
        max: Infinity,
        rate: 0.04, // $0.04/GB for 10,000+ GB
      },
    ],
  },
})

// Calculate tiered pricing
function calculateTieredPrice(
  volume: number,
  tiers: any[]
): {
  total: number
  breakdown: Array<{ tier: string; volume: number; rate: number; cost: number }>
} {
  let remainingVolume = volume
  let total = 0
  const breakdown = []

  for (const tier of tiers) {
    if (remainingVolume <= 0) break

    // Calculate volume in this tier
    const tierMax = tier.max === Infinity ? Infinity : tier.max - tier.min
    const volumeInTier = Math.min(remainingVolume, tierMax)

    // Calculate cost for this tier
    const cost = volumeInTier * tier.rate
    total += cost

    breakdown.push({
      tier: tier.name,
      volume: volumeInTier,
      rate: tier.rate,
      cost,
    })

    remainingVolume -= volumeInTier
  }

  return { total, breakdown }
}

on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== dataProcessingService.id) return

  try {
    // Process data
    const result = await processData(request.inputs.data)
    const volumeGB = result.processedBytes / 1024 ** 3

    // Calculate tiered pricing
    const pricing = calculateTieredPrice(volumeGB, dataProcessingService.pricing.tiers)

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        processedData: result.data,
        statistics: result.stats,
        volumeProcessed: volumeGB,
      },
    })

    // Charge customer
    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: pricing.total,
      description: `Data Processing - ${volumeGB.toFixed(2)} GB`,
      breakdown: {
        volume: volumeGB,
        tiers: pricing.breakdown,
        total: pricing.total,
        averageRate: pricing.total / volumeGB,
      },
    })
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

async function processData(data: any) {
  // Simulate data processing
  const processedBytes = Buffer.byteLength(JSON.stringify(data))
  return {
    data: { processed: true },
    stats: { bytes: processedBytes },
    processedBytes,
  }
}

Example Pricing:

  • 50 GB = $5.00 (50 × $0.10)
  • 500 GB = $42.00 (100 × $0.10 + 400 × $0.08)
  • 5,000 GB = $370.00 (100 × $0.10 + 900 × $0.08 + 4,000 × $0.06)
  • 50,000 GB = $2,770.00 (full tier progression + 40,000 × $0.04)

Savings Illustration:

  • 50 GB at flat $0.10 rate = $5.00 (no savings)
  • 5,000 GB at tiered rates = $370.00 vs $500.00 flat = 26% savings
  • 50,000 GB at tiered rates = $2,770.00 vs $5,000.00 flat = 45% savings

Pattern 2: All-Units Tiering

Apply the tier rate to all units once a threshold is reached:

const transcriptionService = await $.Service.create({
  name: 'Audio Transcription Service',
  type: $.ServiceType.Transcription,

  pricing: {
    model: 'all-units-tiered',
    unit: 'minute',
    tiers: [
      {
        name: 'standard',
        threshold: 0,
        rate: 0.05, // $0.05/minute for 0-999 minutes
      },
      {
        name: 'volume',
        threshold: 1000,
        rate: 0.04, // $0.04/minute for 1,000-9,999 minutes
      },
      {
        name: 'enterprise',
        threshold: 10000,
        rate: 0.03, // $0.03/minute for 10,000+ minutes
      },
    ],
  },
})

// All-units calculation: once you reach a tier, all units use that rate
function calculateAllUnitsTieredPrice(
  volume: number,
  tiers: any[]
): {
  total: number
  tier: string
  rate: number
  savings: number
} {
  // Find applicable tier (highest threshold not exceeding volume)
  let applicableTier = tiers[0]
  for (const tier of tiers) {
    if (volume >= tier.threshold) {
      applicableTier = tier
    }
  }

  const total = volume * applicableTier.rate
  const standardRate = tiers[0].rate
  const savings = volume * standardRate - total

  return {
    total,
    tier: applicableTier.name,
    rate: applicableTier.rate,
    savings,
  }
}

on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== transcriptionService.id) return

  try {
    // Transcribe audio
    const transcription = await transcribeAudio(request.inputs.audioUrl)
    const minutes = Math.ceil(transcription.duration / 60)

    // Calculate pricing using all-units model
    const pricing = calculateAllUnitsTieredPrice(minutes, transcriptionService.pricing.tiers)

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        transcript: transcription.text,
        duration: transcription.duration,
        confidence: transcription.confidence,
        words: transcription.words,
      },
    })

    // Charge customer
    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: pricing.total,
      description: `Audio Transcription - ${minutes} minutes`,
      breakdown: {
        minutes,
        tier: pricing.tier,
        rate: pricing.rate,
        total: pricing.total,
        savings: pricing.savings,
      },
    })
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

async function transcribeAudio(audioUrl: string) {
  // Simulate transcription
  return {
    text: 'Transcribed text...',
    duration: 120, // seconds
    confidence: 0.95,
    words: 250,
  }
}

Example Pricing (All-Units Model):

  • 500 minutes = $25.00 (500 × $0.05)
  • 1,500 minutes = $60.00 (1,500 × $0.04) - saves $15 vs standard
  • 15,000 minutes = $450.00 (15,000 × $0.03) - saves $300 vs standard

Key Difference: In all-units tiering, crossing a threshold retroactively applies the better rate to ALL units, not just those above the threshold.

Pattern 3: Monthly Accumulated Tiers

Track monthly usage and apply tiers progressively:

const apiService = await $.Service.create({
  name: 'RESTful API Platform',
  type: $.ServiceType.API,

  pricing: {
    model: 'monthly-accumulated-tiered',
    unit: 'request',
    resetPeriod: 'month',
    tiers: [
      {
        name: 'free',
        min: 0,
        max: 10000,
        rate: 0, // First 10k requests free
      },
      {
        name: 'starter',
        min: 10000,
        max: 100000,
        rate: 0.0001, // $0.0001 per request for 10k-100k
      },
      {
        name: 'growth',
        min: 100000,
        max: 1000000,
        rate: 0.00008, // $0.00008 per request for 100k-1M
      },
      {
        name: 'scale',
        min: 1000000,
        max: Infinity,
        rate: 0.00005, // $0.00005 per request for 1M+
      },
    ],
  },
})

// Track monthly usage
on($.APIRequest.completed, async (apiRequest) => {
  // Record usage
  await db.create($.UsageRecord, {
    customerId: apiRequest.customerId,
    serviceId: apiService.id,
    timestamp: new Date(),
    units: 1,
    metadata: {
      endpoint: apiRequest.endpoint,
      method: apiRequest.method,
      statusCode: apiRequest.statusCode,
    },
  })
})

// Monthly billing
on($.BillingCycle.ended, async (cycle) => {
  const customers = await db.query($.Customer, { status: 'active' })

  for (const customer of customers) {
    // Get monthly usage
    const usage = await db.query($.UsageRecord, {
      where: {
        customerId: customer.id,
        serviceId: apiService.id,
        timestamp: { gte: cycle.start, lte: cycle.end },
      },
    })

    const totalRequests = usage.length

    // Calculate tiered pricing
    const pricing = calculateTieredPrice(totalRequests, apiService.pricing.tiers)

    if (pricing.total > 0) {
      // Create invoice
      await send($.Invoice.create, {
        customerId: customer.id,
        period: { start: cycle.start, end: cycle.end },
        lineItems: pricing.breakdown.map((tier) => ({
          description: `API Requests (${tier.tier}) - ${tier.volume.toLocaleString()} requests`,
          quantity: tier.volume,
          rate: tier.rate,
          amount: tier.cost,
        })),
        total: pricing.total,
      })
    }
  }
})

Example Monthly Billing:

  • Month 1: 50,000 requests = $4.00 (first 10k free + 40k × $0.0001)
  • Month 2: 500,000 requests = $45.00 (10k free + 90k × $0.0001 + 400k × $0.00008)
  • Month 3: 2,000,000 requests = $129.00 (full tier progression)

Pattern 4: Commit-Based Tiers

Customers commit to volume for better rates:

const cloudStorageService = await $.Service.create({
  name: 'Cloud Storage Platform',
  type: $.ServiceType.Storage,

  pricing: {
    model: 'commit-tiered',
    unit: 'terabyte-month',
    payAsYouGo: {
      rate: 0.15, // $0.15/TB-month without commitment
    },
    commitments: [
      {
        name: 'starter-commit',
        monthlyCommit: 10, // 10 TB minimum
        rate: 0.12, // $0.12/TB-month (20% discount)
        term: 12, // 12-month contract
        overage: 0.13, // $0.13/TB over commitment
      },
      {
        name: 'growth-commit',
        monthlyCommit: 100, // 100 TB minimum
        rate: 0.1, // $0.10/TB-month (33% discount)
        term: 12,
        overage: 0.11,
      },
      {
        name: 'enterprise-commit',
        monthlyCommit: 1000, // 1 PB minimum
        rate: 0.08, // $0.08/TB-month (47% discount)
        term: 12,
        overage: 0.09,
      },
    ],
  },
})

on($.StorageCommitment.create, async (commitmentRequest) => {
  const commitment = cloudStorageService.pricing.commitments.find((c) => c.name === commitmentRequest.tier)

  if (!commitment) {
    throw new Error('Invalid commitment tier')
  }

  // Create commitment contract
  const contract = await db.create($.Commitment, {
    customerId: commitmentRequest.customerId,
    serviceId: cloudStorageService.id,
    tier: commitment.name,
    monthlyCommit: commitment.monthlyCommit,
    rate: commitment.rate,
    overageRate: commitment.overage,
    term: commitment.term,
    startDate: new Date(),
    endDate: addMonths(new Date(), commitment.term),
    status: 'active',
  })

  // Charge first month
  await send($.Payment.charge, {
    customerId: commitmentRequest.customerId,
    amount: commitment.monthlyCommit * commitment.rate,
    description: `Storage Commitment - ${commitment.monthlyCommit} TB`,
    contractId: contract.id,
  })

  return contract
})

// Monthly billing with commitment
on($.BillingCycle.ended, async (cycle) => {
  const commitments = await db.query($.Commitment, {
    where: {
      serviceId: cloudStorageService.id,
      status: 'active',
      endDate: { gte: cycle.end },
    },
  })

  for (const commitment of commitments) {
    // Get actual usage
    const usage = await getMonthlyStorageUsage(commitment.customerId, cycle.start, cycle.end)

    const averageTB = usage.averageTerabytes

    // Calculate charges
    const baseCharge = commitment.monthlyCommit * commitment.rate
    let overageCharge = 0

    if (averageTB > commitment.monthlyCommit) {
      const overage = averageTB - commitment.monthlyCommit
      overageCharge = overage * commitment.overageRate
    }

    const total = baseCharge + overageCharge

    // Create invoice
    const lineItems = [
      {
        description: `Storage Commitment - ${commitment.monthlyCommit} TB`,
        quantity: commitment.monthlyCommit,
        rate: commitment.rate,
        amount: baseCharge,
      },
    ]

    if (overageCharge > 0) {
      lineItems.push({
        description: `Storage Overage - ${(averageTB - commitment.monthlyCommit).toFixed(2)} TB`,
        quantity: averageTB - commitment.monthlyCommit,
        rate: commitment.overageRate,
        amount: overageCharge,
      })
    }

    await send($.Invoice.create, {
      customerId: commitment.customerId,
      period: { start: cycle.start, end: cycle.end },
      lineItems,
      total,
      metadata: {
        actualUsage: averageTB,
        commitment: commitment.monthlyCommit,
        utilizationRate: (averageTB / commitment.monthlyCommit) * 100,
      },
    })

    // Alert if underutilized
    if (averageTB < commitment.monthlyCommit * 0.7) {
      await send($.Customer.notify, {
        customerId: commitment.customerId,
        type: 'commitment-underutilized',
        message: `Your storage usage is only ${Math.round((averageTB / commitment.monthlyCommit) * 100)}% of your commitment`,
        recommendation: 'Consider downgrading your commitment to save money',
      })
    }
  }
})

async function getMonthlyStorageUsage(customerId: string, start: Date, end: Date) {
  // Calculate average storage used during the period
  const samples = await db.query($.StorageSample, {
    where: {
      customerId,
      timestamp: { gte: start, lte: end },
    },
  })

  const averageBytes = samples.reduce((sum, s) => sum + s.bytes, 0) / samples.length
  const averageTerabytes = averageBytes / 1024 ** 4

  return { averageTerabytes }
}

function addMonths(date: Date, months: number): Date {
  const result = new Date(date)
  result.setMonth(result.getMonth() + months)
  return result
}

Commitment Pricing:

  • Pay-as-you-go: $0.15/TB-month
  • 10 TB commitment: $0.12/TB-month (save $360/year)
  • 100 TB commitment: $0.10/TB-month (save $6,000/year)
  • 1 PB commitment: $0.08/TB-month (save $84,000/year)

Example Billing:

  • Customer with 100 TB commitment uses 120 TB:
    • Base: 100 TB × $0.10 = $10.00
    • Overage: 20 TB × $0.11 = $2.20
    • Total: $12.20

Pattern 5: Dynamic Tier Promotion

Automatically promote customers to better tiers:

const emailDeliveryService = await $.Service.create({
  name: 'Transactional Email Service',
  type: $.ServiceType.Email,

  pricing: {
    model: 'dynamic-tiered',
    unit: 'email',
    evaluationPeriod: 'rolling-30-days',
    tiers: [
      {
        name: 'starter',
        threshold: 0,
        rate: 0.001, // $0.001 per email
        features: ['basic-analytics', 'email-support'],
      },
      {
        name: 'professional',
        threshold: 50000, // Auto-promote at 50k emails/month
        rate: 0.0008, // $0.0008 per email (20% discount)
        features: ['advanced-analytics', 'priority-support', 'custom-domains'],
      },
      {
        name: 'enterprise',
        threshold: 500000, // Auto-promote at 500k emails/month
        rate: 0.0005, // $0.0005 per email (50% discount)
        features: ['all-features', 'dedicated-ip', 'phone-support', 'sla-guarantee'],
      },
    ],
  },
})

// Track rolling 30-day usage
async function getRolling30DayVolume(customerId: string): Promise<number> {
  const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000)

  const usage = await db.query($.UsageRecord, {
    where: {
      customerId,
      serviceId: emailDeliveryService.id,
      timestamp: { gte: thirtyDaysAgo },
    },
  })

  return usage.reduce((sum, record) => sum + record.units, 0)
}

// Determine applicable tier
async function determineCustomerTier(customerId: string): Promise<any> {
  const rolling30DayVolume = await getRolling30DayVolume(customerId)

  let applicableTier = emailDeliveryService.pricing.tiers[0]
  for (const tier of emailDeliveryService.pricing.tiers) {
    if (rolling30DayVolume >= tier.threshold) {
      applicableTier = tier
    }
  }

  return applicableTier
}

on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== emailDeliveryService.id) return

  try {
    // Send email
    const result = await sendTransactionalEmail(request.inputs)

    // Determine current tier
    const tier = await determineCustomerTier(request.customerId)

    // Record usage
    await db.create($.UsageRecord, {
      customerId: request.customerId,
      serviceId: emailDeliveryService.id,
      timestamp: new Date(),
      units: 1,
      rate: tier.rate,
      cost: tier.rate,
      tier: tier.name,
    })

    // Check for tier promotion
    const rolling30Day = await getRolling30DayVolume(request.customerId)
    const nextTier = emailDeliveryService.pricing.tiers.find((t) => t.threshold > rolling30Day && rolling30Day >= t.threshold * 0.9)

    let upgradeNotice
    if (nextTier) {
      upgradeNotice = {
        message: `You're close to ${nextTier.name} tier! Send ${Math.ceil(nextTier.threshold - rolling30Day)} more emails to unlock ${(((tier.rate - nextTier.rate) / tier.rate) * 100).toFixed(0)}% discount`,
        currentTier: tier.name,
        nextTier: nextTier.name,
        emailsToUpgrade: nextTier.threshold - rolling30Day,
        potentialSavings: (tier.rate - nextTier.rate) * rolling30Day,
      }
    }

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        messageId: result.messageId,
        status: result.status,
      },
      pricing: {
        tier: tier.name,
        rate: tier.rate,
        rolling30DayVolume: rolling30Day,
        upgradeNotice,
      },
    })
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

// Daily tier evaluation and notification
on($.DailyJob.run, async () => {
  const customers = await db.query($.Customer, { status: 'active' })

  for (const customer of customers) {
    const currentTier = await determineCustomerTier(customer.id)
    const previousTier = await db.findOne($.CustomerTier, {
      customerId: customer.id,
      serviceId: emailDeliveryService.id,
    })

    // Check for tier change
    if (!previousTier || previousTier.tierName !== currentTier.name) {
      // Update tier
      await db.upsert($.CustomerTier, {
        where: { customerId: customer.id, serviceId: emailDeliveryService.id },
        create: {
          customerId: customer.id,
          serviceId: emailDeliveryService.id,
          tierName: currentTier.name,
          tierRate: currentTier.rate,
          promotedAt: new Date(),
        },
        update: {
          tierName: currentTier.name,
          tierRate: currentTier.rate,
          promotedAt: new Date(),
        },
      })

      // Send promotion notification
      if (previousTier && currentTier.threshold > emailDeliveryService.pricing.tiers.find((t) => t.name === previousTier.tierName)?.threshold) {
        await send($.Email.send, {
          to: customer.email,
          template: 'tier-promotion',
          data: {
            oldTier: previousTier.tierName,
            newTier: currentTier.name,
            newRate: currentTier.rate,
            discount: (((previousTier.tierRate - currentTier.rate) / previousTier.tierRate) * 100).toFixed(0),
            newFeatures: currentTier.features,
          },
        })
      }
    }
  }
})

async function sendTransactionalEmail(inputs: any) {
  // Simulate email sending
  return {
    messageId: `msg_${Date.now()}`,
    status: 'sent',
  }
}

Dynamic Tier Behavior:

  • Continuous evaluation of rolling 30-day usage
  • Automatic promotion when thresholds are reached
  • Immediate rate adjustment on next request
  • Proactive notification when approaching next tier

Example Progression:

  • Day 1-20: 30,000 emails at $0.001 = $30.00
  • Day 21: Crosses 50k threshold → auto-promoted to Professional
  • Day 21-30: 25,000 emails at $0.0008 = $20.00
  • Month total: 55,000 emails, cost = $50.00 (vs $55.00 at flat rate)

Pattern 6: Package Tiers with Included Units

Combine base fees with included usage:

const videoTranscodingService = await $.Service.create({
  name: 'Video Transcoding Platform',
  type: $.ServiceType.VideoProcessing,

  pricing: {
    model: 'package-tiered',
    packages: [
      {
        name: 'hobby',
        monthlyFee: 0,
        included: {
          minutes: 60, // 1 hour free per month
        },
        overage: {
          rate: 0.05, // $0.05 per minute over
        },
        limits: {
          maxResolution: '1080p',
          formats: ['mp4'],
        },
      },
      {
        name: 'creator',
        monthlyFee: 29,
        included: {
          minutes: 1000, // ~16 hours included
        },
        overage: {
          rate: 0.03, // $0.03 per minute over
        },
        limits: {
          maxResolution: '4k',
          formats: ['mp4', 'webm', 'mov'],
          features: ['thumbnails', 'previews'],
        },
      },
      {
        name: 'professional',
        monthlyFee: 99,
        included: {
          minutes: 5000, // ~83 hours included
        },
        overage: {
          rate: 0.02, // $0.02 per minute over
        },
        limits: {
          maxResolution: '8k',
          formats: ['all'],
          features: ['all', 'priority-queue', 'api-access'],
        },
      },
      {
        name: 'studio',
        monthlyFee: 499,
        included: {
          minutes: 30000, // 500 hours included
        },
        overage: {
          rate: 0.01, // $0.01 per minute over
        },
        limits: {
          maxResolution: '8k',
          formats: ['all'],
          features: ['all', 'dedicated-resources', 'sla', 'phone-support'],
        },
      },
    ],
  },
})

on($.VideoTranscode.request, async (request) => {
  // Get customer's package
  const subscription = await db.findOne($.Subscription, {
    customerId: request.customerId,
    serviceId: videoTranscodingService.id,
    status: 'active',
  })

  const pkg = subscription
    ? videoTranscodingService.pricing.packages.find((p) => p.name === subscription.packageName)
    : videoTranscodingService.pricing.packages[0] // Default to hobby

  try {
    // Get monthly usage
    const monthStart = new Date()
    monthStart.setDate(1)
    monthStart.setHours(0, 0, 0, 0)

    const monthlyUsage = await db.query($.UsageRecord, {
      where: {
        customerId: request.customerId,
        serviceId: videoTranscodingService.id,
        timestamp: { gte: monthStart },
      },
    })

    const usedMinutes = monthlyUsage.reduce((sum, u) => sum + u.units, 0)

    // Check resolution limit
    if (request.inputs.resolution > pkg.limits.maxResolution) {
      return await send($.ServiceRequest.reject, {
        requestId: request.id,
        reason: `Resolution ${request.inputs.resolution} exceeds ${pkg.name} package limit (${pkg.limits.maxResolution})`,
        upgrade: {
          requiredPackage: videoTranscodingService.pricing.packages.find((p) => p.limits.maxResolution >= request.inputs.resolution)?.name,
        },
      })
    }

    // Transcode video
    const result = await transcodeVideo(request.inputs)
    const minutes = Math.ceil(result.duration / 60)

    // Calculate cost
    let cost = 0
    const breakdown: any = {
      package: pkg.name,
      monthlyFee: pkg.monthlyFee,
      includedMinutes: pkg.included.minutes,
      usedMinutes: usedMinutes + minutes,
    }

    // Calculate overage if applicable
    if (usedMinutes + minutes > pkg.included.minutes) {
      const overageMinutes = Math.max(0, usedMinutes + minutes - pkg.included.minutes)
      cost = overageMinutes * pkg.overage.rate

      breakdown.overageMinutes = overageMinutes
      breakdown.overageRate = pkg.overage.rate
      breakdown.overageCost = cost
    } else {
      breakdown.remainingMinutes = pkg.included.minutes - (usedMinutes + minutes)
    }

    // Record usage
    await db.create($.UsageRecord, {
      customerId: request.customerId,
      serviceId: videoTranscodingService.id,
      timestamp: new Date(),
      units: minutes,
      cost,
      metadata: {
        videoId: result.videoId,
        resolution: request.inputs.resolution,
        format: request.inputs.format,
      },
    })

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        transcodedUrl: result.url,
        thumbnailUrl: result.thumbnail,
        duration: result.duration,
      },
      pricing: breakdown,
    })

    // Charge overage if applicable
    if (cost > 0) {
      await send($.Payment.charge, {
        customerId: request.customerId,
        amount: cost,
        description: `Video Transcoding Overage - ${breakdown.overageMinutes} minutes`,
        breakdown,
      })
    }

    // Suggest upgrade if consistently hitting overage
    if (usedMinutes > pkg.included.minutes * 1.5) {
      const nextPackage = videoTranscodingService.pricing.packages[videoTranscodingService.pricing.packages.findIndex((p) => p.name === pkg.name) + 1]

      if (nextPackage) {
        await send($.Customer.notify, {
          customerId: request.customerId,
          type: 'package-upgrade-suggestion',
          message: `You're using ${usedMinutes} minutes/month. Upgrade to ${nextPackage.name} for better value.`,
          comparison: {
            currentCost: pkg.monthlyFee + (usedMinutes - pkg.included.minutes) * pkg.overage.rate,
            upgradeCost: nextPackage.monthlyFee,
            savings: pkg.monthlyFee + (usedMinutes - pkg.included.minutes) * pkg.overage.rate - nextPackage.monthlyFee,
          },
        })
      }
    }
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

async function transcodeVideo(inputs: any) {
  // Simulate video transcoding
  return {
    videoId: `video_${Date.now()}`,
    url: `https://cdn.example.com/video_${Date.now()}.mp4`,
    thumbnail: `https://cdn.example.com/thumb_${Date.now()}.jpg`,
    duration: 300, // 5 minutes
  }
}

Package Tier Value:

  • Hobby (Free): 60 min included, $0.05/min overage
    • 100 min usage = $2.00 (60 free + 40 × $0.05)
  • Creator ($29/mo): 1,000 min included, $0.03/min overage
    • 1,500 min usage = $44.00 ($29 + 500 × $0.03)
  • Professional ($99/mo): 5,000 min included, $0.02/min overage
    • 6,000 min usage = $119.00 ($99 + 1,000 × $0.02)
  • Studio ($499/mo): 30,000 min included, $0.01/min overage
    • 35,000 min usage = $549.00 ($499 + 5,000 × $0.01)

Pattern 7: Graduated Bulk Discounts

Offer increasing discounts at volume milestones:

const printingService = await $.Service.create({
  name: 'Print-on-Demand Service',
  type: $.ServiceType.Printing,

  pricing: {
    model: 'graduated-bulk',
    basePrice: 10.0, // $10 per unit at base
    discounts: [
      {
        quantity: 1,
        discount: 0, // No discount
        price: 10.0,
      },
      {
        quantity: 50,
        discount: 0.1, // 10% off at 50+
        price: 9.0,
      },
      {
        quantity: 100,
        discount: 0.2, // 20% off at 100+
        price: 8.0,
      },
      {
        quantity: 500,
        discount: 0.3, // 30% off at 500+
        price: 7.0,
      },
      {
        quantity: 1000,
        discount: 0.4, // 40% off at 1,000+
        price: 6.0,
      },
      {
        quantity: 5000,
        discount: 0.5, // 50% off at 5,000+
        price: 5.0,
      },
    ],
  },
})

function calculateBulkPrice(
  quantity: number,
  discounts: any[]
): {
  unitPrice: number
  total: number
  discount: number
  savings: number
} {
  // Find applicable discount tier
  let applicableTier = discounts[0]
  for (const tier of discounts) {
    if (quantity >= tier.quantity) {
      applicableTier = tier
    }
  }

  const unitPrice = applicableTier.price
  const total = quantity * unitPrice
  const baseTotal = quantity * discounts[0].price
  const savings = baseTotal - total

  return {
    unitPrice,
    total,
    discount: applicableTier.discount,
    savings,
  }
}

on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== printingService.id) return

  const quantity = request.inputs.quantity

  try {
    // Calculate pricing
    const pricing = calculateBulkPrice(quantity, printingService.pricing.discounts)

    // Process print order
    const result = await processPrintOrder(request.inputs)

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        orderId: result.orderId,
        items: result.items,
        estimatedShipDate: result.shipDate,
      },
    })

    // Charge customer
    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: pricing.total,
      description: `Print Order - ${quantity} units`,
      breakdown: {
        quantity,
        unitPrice: pricing.unitPrice,
        discount: `${(pricing.discount * 100).toFixed(0)}%`,
        subtotal: quantity * printingService.pricing.basePrice,
        discountAmount: pricing.savings,
        total: pricing.total,
      },
    })

    // Show next discount tier
    const nextTier = printingService.pricing.discounts.find((d) => d.quantity > quantity)

    if (nextTier) {
      const additionalNeeded = nextTier.quantity - quantity
      const nextSavings = quantity * (pricing.unitPrice - nextTier.price)

      await send($.Customer.notify, {
        customerId: request.customerId,
        type: 'bulk-discount-opportunity',
        message: `Order ${additionalNeeded} more units to unlock ${(nextTier.discount * 100).toFixed(0)}% discount`,
        data: {
          currentQuantity: quantity,
          currentDiscount: pricing.discount,
          nextTierQuantity: nextTier.quantity,
          nextDiscount: nextTier.discount,
          additionalUnitsNeeded: additionalNeeded,
          potentialSavings: nextSavings,
        },
      })
    }
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

async function processPrintOrder(inputs: any) {
  // Simulate print processing
  return {
    orderId: `order_${Date.now()}`,
    items: inputs.quantity,
    shipDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
  }
}

Graduated Bulk Pricing:

  • 25 units = $250.00 ($10 each, no discount)
  • 75 units = $675.00 ($9 each, 10% off, save $75)
  • 250 units = $2,000.00 ($8 each, 20% off, save $500)
  • 1,500 units = $9,000.00 ($6 each, 40% off, save $6,000)
  • 10,000 units = $50,000.00 ($5 each, 50% off, save $50,000)

Pattern 8: Multi-Dimensional Tiering

Apply different tier structures to multiple dimensions:

const analyticsService = await $.Service.create({
  name: 'Advanced Analytics Platform',
  type: $.ServiceType.Analytics,

  pricing: {
    model: 'multi-dimensional-tiered',
    dimensions: {
      dataVolume: {
        unit: 'gigabyte',
        tiers: [
          { min: 0, max: 100, rate: 0.5 },
          { min: 100, max: 1000, rate: 0.4 },
          { min: 1000, max: Infinity, rate: 0.3 },
        ],
      },
      computeHours: {
        unit: 'hour',
        tiers: [
          { min: 0, max: 10, rate: 5.0 },
          { min: 10, max: 100, rate: 4.0 },
          { min: 100, max: Infinity, rate: 3.0 },
        ],
      },
      apiCalls: {
        unit: 'call',
        tiers: [
          { min: 0, max: 10000, rate: 0.001 },
          { min: 10000, max: 100000, rate: 0.0008 },
          { min: 100000, max: Infinity, rate: 0.0005 },
        ],
      },
    },
  },
})

function calculateMultiDimensionalPrice(
  usage: {
    dataVolume: number
    computeHours: number
    apiCalls: number
  },
  dimensions: any
): {
  total: number
  breakdown: any
} {
  const breakdown: any = {}
  let total = 0

  for (const [dimension, volume] of Object.entries(usage)) {
    const tierConfig = dimensions[dimension]
    const pricing = calculateTieredPrice(volume, tierConfig.tiers)

    breakdown[dimension] = {
      volume,
      unit: tierConfig.unit,
      cost: pricing.total,
      tiers: pricing.breakdown,
    }

    total += pricing.total
  }

  return { total, breakdown }
}

on($.ServiceRequest.created, async (request) => {
  if (request.serviceId !== analyticsService.id) return

  try {
    // Run analytics job
    const result = await runAnalyticsJob(request.inputs)

    // Calculate multi-dimensional pricing
    const usage = {
      dataVolume: result.dataProcessedGB,
      computeHours: result.computeHours,
      apiCalls: result.apiCalls,
    }

    const pricing = calculateMultiDimensionalPrice(usage, analyticsService.pricing.dimensions)

    // Deliver result
    await send($.ServiceResult.deliver, {
      requestId: request.id,
      outputs: {
        results: result.data,
        insights: result.insights,
        visualizations: result.visualizations,
      },
    })

    // Charge customer
    await send($.Payment.charge, {
      customerId: request.customerId,
      amount: pricing.total,
      description: 'Analytics Job',
      breakdown: pricing.breakdown,
    })
  } catch (error) {
    await send($.ServiceRequest.fail, {
      requestId: request.id,
      error: error.message,
    })
  }
})

async function runAnalyticsJob(inputs: any) {
  // Simulate analytics processing
  return {
    data: { results: [] },
    insights: ['Insight 1', 'Insight 2'],
    visualizations: ['chart1.png', 'chart2.png'],
    dataProcessedGB: 150,
    computeHours: 25,
    apiCalls: 15000,
  }
}

Multi-Dimensional Pricing Example:

  • Data: 150 GB = $55 (100 @ $0.50 + 50 @ $0.40)
  • Compute: 25 hours = $110 (10 @ $5 + 15 @ $4)
  • API: 15,000 calls = $14 (10k @ $0.001 + 5k @ $0.0008)
  • Total: $179

Advanced Patterns

Tier Forecasting

Help customers understand future costs:

async function forecastTierCosts(customerId: string, serviceId: string, projectedVolumes: number[]) {
  const service = await db.findOne($.Service, { id: serviceId })
  const historicalUsage = await db.query($.UsageRecord, {
    where: { customerId, serviceId },
    orderBy: { timestamp: 'desc' },
    limit: 90, // Last 90 days
  })

  const averageDaily = historicalUsage.reduce((sum, u) => sum + u.units, 0) / 90

  return projectedVolumes.map((volume) => {
    const pricing = calculateTieredPrice(volume, service.pricing.tiers)

    return {
      volume,
      cost: pricing.total,
      averageRate: pricing.total / volume,
      savings: volume * service.pricing.tiers[0].rate - pricing.total,
      daysToReach: Math.ceil(volume / averageDaily),
      breakdown: pricing.breakdown,
    }
  })
}

Tier Optimization Recommendations

Suggest optimal usage patterns:

async function suggestTierOptimization(customerId: string, serviceId: string) {
  const service = await db.findOne($.Service, { id: serviceId })
  const usage = await getMonthlyUsage(customerId, serviceId)

  const suggestions = []

  // Check if customer is just below a tier threshold
  for (let i = 0; i < service.pricing.tiers.length - 1; i++) {
    const currentTier = service.pricing.tiers[i]
    const nextTier = service.pricing.tiers[i + 1]

    if (usage.total >= currentTier.min && usage.total < nextTier.min) {
      const gap = nextTier.min - usage.total
      const gapPercentage = (gap / usage.total) * 100

      // If within 20% of next tier
      if (gapPercentage <= 20) {
        const currentCost = calculateTieredPrice(usage.total, service.pricing.tiers).total
        const nextTierCost = calculateTieredPrice(nextTier.min, service.pricing.tiers).total
        const additionalCost = nextTierCost - currentCost
        const additionalUnits = gap

        suggestions.push({
          type: 'tier-threshold',
          message: `You're ${gap} units away from ${nextTier.name} tier`,
          analysis: {
            currentUsage: usage.total,
            currentCost,
            nextTierThreshold: nextTier.min,
            additionalUnitsNeeded: additionalUnits,
            additionalCost,
            newRate: nextTier.rate,
            potentialSavingsPerUnit: currentTier.rate - nextTier.rate,
          },
        })
      }
    }
  }

  return suggestions
}

Best Practices

1. Clear Tier Communication

Show customers exactly where they stand:

async function getTierStatus(customerId: string, serviceId: string) {
  const service = await db.findOne($.Service, { id: serviceId })
  const usage = await getCurrentPeriodUsage(customerId, serviceId)

  const currentTier = service.pricing.tiers.find((t) => usage.total >= t.min && usage.total < t.max)

  const nextTier = service.pricing.tiers.find((t) => t.min > usage.total)

  return {
    current: {
      tier: currentTier.name,
      usage: usage.total,
      rate: currentTier.rate,
      range: `${currentTier.min}-${currentTier.max} ${service.pricing.unit}s`,
    },
    next: nextTier
      ? {
          tier: nextTier.name,
          threshold: nextTier.min,
          rate: nextTier.rate,
          unitsToNextTier: nextTier.min - usage.total,
          potentialSavings: (currentTier.rate - nextTier.rate) * usage.total,
        }
      : null,
    progress: nextTier ? (usage.total / nextTier.min) * 100 : 100,
  }
}

2. Fair Tier Transitions

Handle month-to-month tier changes gracefully:

on($.BillingCycle.ended, async (cycle) => {
  const customers = await db.query($.Customer, { status: 'active' })

  for (const customer of customers) {
    const usage = await getUsageForPeriod(customer.id, cycle.start, cycle.end)

    // Determine tier for the full period
    const tier = determineTierForUsage(usage.total)

    // Apply tier rate retroactively to all usage
    const cost = calculateTieredPrice(usage.total, tier.tiers).total

    await send($.Invoice.create, {
      customerId: customer.id,
      period: { start: cycle.start, end: cycle.end },
      amount: cost,
      breakdown: {
        usage: usage.total,
        tier: tier.name,
        calculation: 'end-of-period',
      },
    })
  }
})

3. Volume Commitment Benefits

Reward customers who commit to volume:

async function offerVolumeCommitment(customerId: string) {
  const historicalUsage = await getHistoricalUsage(customerId, 6) // 6 months

  const averageMonthly = historicalUsage.reduce((sum, m) => sum + m.usage, 0) / 6

  // Offer commitment at 80% of average usage
  const recommendedCommit = Math.floor(averageMonthly * 0.8)

  const payAsYouGoRate = 0.1
  const commitRate = 0.07 // 30% discount

  const projectedSavings = (payAsYouGoRate - commitRate) * recommendedCommit * 12

  return {
    recommendation: {
      monthlyCommit: recommendedCommit,
      rate: commitRate,
      discount: 0.3,
      projectedAnnualSavings: projectedSavings,
    },
    comparison: {
      currentAverageMonthly: averageMonthly,
      currentEstimatedCost: averageMonthly * payAsYouGoRate,
      commitCost: recommendedCommit * commitRate,
      monthlySavings: averageMonthly * payAsYouGoRate - recommendedCommit * commitRate,
    },
  }
}

Real-World Examples

Cloud Storage (AWS S3 Style)

const pricing = {
  tiers: [
    { min: 0, max: 50000, rate: 0.023 }, // First 50 TB
    { min: 50000, max: 450000, rate: 0.022 }, // Next 450 TB
    { min: 450000, max: Infinity, rate: 0.021 }, // Over 500 TB
  ],
}

// 100 TB = $2,250/month
// 1 PB = $21,700/month (vs $23,000 flat rate)

Email Service (SendGrid Style)

const pricing = {
  tiers: [
    { threshold: 0, rate: 0.001 }, // $1 per 1,000
    { threshold: 50000, rate: 0.0008 }, // $0.80 per 1,000 at 50k+
    { threshold: 100000, rate: 0.0006 }, // $0.60 per 1,000 at 100k+
  ],
}

// 75,000 emails = $67.50/month
// 250,000 emails = $182.50/month

API Platform (Stripe Style)

const pricing = {
  tiers: [
    { min: 0, max: 1000000, rate: 0.029 }, // 2.9% + $0.30
    { min: 1000000, max: Infinity, rate: 0.027 }, // 2.7% for high volume
  ],
  fixed: 0.3,
}

// $100k processed = $3,200 in fees
// $10M processed = $272,000 in fees (save $20k vs flat rate)

Next Steps

Resources