Skip to main content

Agent Cloud Billing

Billing service for cloud agent resource consumption. Extends the EndpointCredits credit system with per-agent, per-customer metering across six resource types.

Refs #1981, #1983


Overview

Agent Cloud Billing tracks every resource an agent consumes on behalf of a customer. Each usage event is recorded in the agent_resource_usage table with a calculated credit cost. Credits are deducted from the customer's balance in credit_transactions.

Agent performs work
|
v
record_usage() called with resource_type + quantity
|
v
Credit cost calculated (quantity * credits_per_unit)
|
v
AgentResourceUsage row inserted
|
v
deduct_credits() removes credits from customer balance

Resource Types and Pricing

Six resource types are metered. Each has a fixed credit-per-unit rate.

Resource TypeCredits per UnitUnitDescription
compute2secondsAgent CPU execution time
memory_ops5operationsZeroMemory read/write operations
vector_search8queriesVector similarity search queries
storage0.001bytesObject/file storage consumption
a2a3messagesAgent-to-agent communication messages
postgresql20queriesDedicated PostgreSQL queries

Cost Examples

OperationQuantityCalculationCredit Cost
60 seconds of compute6060 * 2120.000
10 memory operations1010 * 550.000
5 vector searches55 * 840.000
1 MB storage (1,048,576 bytes)10485761048576 * 0.0011048.576
25 agent-to-agent messages2525 * 375.000
3 PostgreSQL queries33 * 2060.000

All credit costs are calculated as Decimal values and quantized to 3 decimal places.


AgentResourceUsage Model

The agent_resource_usage table stores every metered event.

ColumnTypeDescription
idUUIDPrimary key
agent_idVARCHAR(255)Agent identifier (indexed)
customer_idUUIDForeign key to users.id (indexed)
resource_typeVARCHAR(32)One of the six resource types
quantityNUMERICAmount of resource consumed
unitVARCHAR(32)Unit of measurement (seconds, operations, etc.)
credit_costNUMERICCalculated credit cost for this usage
period_startDATETIMEStart of the metering period
period_endDATETIMEEnd of the metering period
metadataJSONOptional additional context
created_atDATETIMERecord creation timestamp

Service API

AgentCloudBillingService

Instantiated with a SQLAlchemy Session. All methods operate within the caller's transaction.

from app.services.agent_cloud_billing_service import AgentCloudBillingService

service = AgentCloudBillingService(db=session)

calculate_credit_cost(resource_type, quantity)

Calculate the credit cost for a given resource type and quantity without recording usage.

Parameters:

  • resource_type (str) -- One of: compute, memory_ops, vector_search, storage, a2a, postgresql
  • quantity (Decimal) -- Amount of resource consumed

Returns: Decimal -- credit cost quantized to 3 decimal places

Raises: ValueError if the resource type is unknown

cost = service.calculate_credit_cost("vector_search", Decimal("15"))
# cost = Decimal("120.000")

record_usage(agent_id, customer_id, resource_type, quantity, period_start, period_end, metadata=None)

Record a resource usage event and calculate its credit cost. Inserts a row into agent_resource_usage and flushes (but does not commit -- the caller controls the transaction).

Parameters:

  • agent_id (str) -- Agent identifier
  • customer_id (str) -- Customer UUID as string
  • resource_type (str) -- One of the six valid resource types
  • quantity (float) -- Amount consumed (must be positive)
  • period_start (datetime) -- Start of metering period
  • period_end (datetime) -- End of metering period (must be after start)
  • metadata (dict, optional) -- Additional context

Returns: Dictionary with the recorded usage details:

{
"id": "uuid-string",
"agent_id": "aurora",
"customer_id": "customer-uuid",
"resource_type": "compute",
"quantity": 120.0,
"unit": "seconds",
"credit_cost": 240.0,
"period_start": "2026-06-01T00:00:00",
"period_end": "2026-06-01T01:00:00"
}

Raises:

  • ValueError if resource_type is unknown
  • ValueError if period_end is not after period_start
  • ValueError if quantity is not positive

deduct_credits(customer_id, credits, description)

Deduct credits from a customer's balance via the credit_transactions table. Checks the current balance before deducting and returns False if insufficient.

Parameters:

  • customer_id (str) -- Customer UUID as string
  • credits (float) -- Number of credits to deduct (positive value)
  • description (str) -- Reason for the deduction

Returns: True if deduction succeeded, False if insufficient balance

Raises: ValueError if credits is not positive

success = service.deduct_credits(
customer_id="customer-uuid",
credits=240.0,
description="Agent aurora compute: 120s execution"
)

get_agent_usage_summary(agent_id, period_start, period_end)

Retrieve aggregated usage for a specific agent over a time period, grouped by resource type.

Parameters:

  • agent_id (str) -- Agent identifier
  • period_start (datetime) -- Start of query period
  • period_end (datetime) -- End of query period

Returns:

{
"agent_id": "aurora",
"period_start": "2026-06-01T00:00:00",
"period_end": "2026-06-01T23:59:59",
"total_credit_cost": 510.0,
"total_records": 42,
"by_resource_type": {
"compute": {
"total_quantity": 300.0,
"total_credit_cost": 600.0,
"unit": "seconds",
"record_count": 15
},
"vector_search": {
"total_quantity": 50.0,
"total_credit_cost": 400.0,
"unit": "queries",
"record_count": 12
}
}
}

get_customer_cloud_spend(customer_id, period_start, period_end)

Retrieve total cloud spend for a customer across all agents, grouped by agent and resource type.

Parameters:

  • customer_id (str) -- Customer UUID as string
  • period_start (datetime) -- Start of query period
  • period_end (datetime) -- End of query period

Returns:

{
"customer_id": "customer-uuid",
"period_start": "2026-06-01T00:00:00",
"period_end": "2026-06-30T23:59:59",
"total_credit_cost": 1250.0,
"total_records": 87,
"by_agent": {
"aurora": {
"total_credit_cost": 800.0,
"record_count": 52,
"by_resource_type": {
"compute": {
"total_quantity": 200.0,
"total_credit_cost": 400.0,
"unit": "seconds",
"record_count": 20
}
}
},
"sage": {
"total_credit_cost": 450.0,
"record_count": 35,
"by_resource_type": {}
}
}
}

Budget Alerts and Cost Management

Monitoring Spend

Use get_customer_cloud_spend to monitor a customer's total spend across all agents. Compare against budget thresholds to trigger alerts:

spend = service.get_customer_cloud_spend(
customer_id="customer-uuid",
period_start=month_start,
period_end=month_end,
)

if spend["total_credit_cost"] > budget_threshold:
# Trigger budget alert notification
pass

Pre-flight Balance Checks

Before executing expensive operations, check whether the customer has sufficient credits:

estimated_cost = service.calculate_credit_cost("postgresql", Decimal("10"))
# Check balance before proceeding
can_deduct = service.deduct_credits(
customer_id="customer-uuid",
credits=float(estimated_cost),
description="Agent sage: 10 PostgreSQL queries"
)
if not can_deduct:
# Reject the operation or notify the customer
pass

Per-Agent Cost Attribution

Use get_agent_usage_summary to attribute costs to individual agents. This enables:

  • Identifying which agents consume the most resources
  • Optimizing expensive agents (e.g., reducing unnecessary vector searches)
  • Billing breakdowns for customers running multiple agents

Data Lake Integration

Agent resource usage is exported to the data lake as the platform/agent_resource_usage partition. This enables historical analysis and trend detection via the lake query endpoint:

SELECT agent_id, resource_type, SUM(credit_cost) as total_cost
FROM platform_agent_resource_usage
GROUP BY agent_id, resource_type
ORDER BY total_cost DESC

See docs/api/DATA_LAKE_API.md for lake query details.


Pydantic Schemas

AgentResourceUsageCreate

Request schema for creating a usage record.

FieldTypeRequiredConstraints
agent_idstryes1-255 chars
customer_idUUIDyes
resource_typeenumyesOne of the 6 resource types
quantityDecimalyesMust be > 0
unitenumyesMatching unit for type
credit_costDecimalyesMust be >= 0
period_startdatetimeyes
period_enddatetimeyesMust be after period_start
metadatadictnoDefault: empty dict

AgentResourceUsageResponse

Response schema returned by API endpoints.

Includes all fields from AgentResourceUsageCreate plus:

FieldTypeDescription
idUUIDRecord primary key
created_atdatetimeCreation timestamp

AgentResourceUsageSummary

Aggregated summary schema.

FieldTypeDescription
agent_idstrAgent identifier
resource_typeenumResource type
total_quantityDecimalSum of quantity
total_credit_costDecimalSum of credit cost
unitenumUnit of measurement
period_startdatetimeSummary period start
period_enddatetimeSummary period end
record_countintNumber of usage records

Key Source Files

FilePurpose
src/backend/app/services/agent_cloud_billing_service.pyCore billing service with pricing and metering
src/backend/app/models/agent_resource_usage.pySQLAlchemy model for agent_resource_usage table
src/backend/app/schemas/agent_resource_usage.pyPydantic schemas (ResourceType, ResourceUnit, Create/Response/Summary)