Skip to content

App Runtime Metering v1

Goal

Define the first implementation slice for metering app-runtime usage so platform apps can produce billable usage without inventing a parallel billing system.

This document is about metering primitives and reconciliation shape, not final pricing.

Current Gap

Today, usage_records is allocation-centric: 1. allocation_id is required 2. billing service lists and exports usage by allocation only 3. there is no app-runtime usage anchor such as app_instance_id

That is sufficient for bare allocation billing, but it will break as soon as scheduler, model-serving, or other platform-app runtimes need billable usage independent of a single allocation row.

Decision Summary

  1. Keep one billing system.
  2. Evolve usage_records into a generic billable usage record model.
  3. Preserve project as the primary attribution anchor.
  4. Support both allocation-based and app-runtime-based usage in the same ledger pipeline.

Required Attribution Fields

App runtime usage must be attributable by: 1. org_id 2. project_id 3. requested_by_user_id 4. app_instance_id 5. usage_source 6. usage_unit 7. operating_mode 8. control_plane_scope 9. runtime_backend 10. correlation_id

Optional links may include: 1. allocation_id 2. reference_id or runtime-native job/request identifier

Schema Direction

usage_records should evolve to support both allocation and app-runtime rows.

Proposed additions

  1. usage_source text not null
  2. initial values:
    • allocation
    • app_runtime
  3. usage_unit text not null
  4. examples:
    • gpu_hour
    • runtime_uptime_hour
    • request
    • job_hour
  5. app_instance_id uuid null references app_instances(id)
  6. control_plane_component boolean not null default false
  7. operating_mode text null
  8. control_plane_scope text null
  9. runtime_backend text null
  10. correlation_id text null
  11. metadata jsonb not null default '{}'::jsonb

Constraint direction

  1. allocation rows:
  2. usage_source = allocation
  3. allocation_id required
  4. app-runtime rows:
  5. usage_source = app_runtime
  6. app_instance_id required
  7. a row may reference both allocation_id and app_instance_id when app-runtime usage is ultimately executed on a specific allocation, but that should be explicit rather than assumed

Service Direction

Billing service should evolve from: 1. allocation-only usage listing and CSV export

to: 1. usage listing/export across usage_source 2. filtering by: - allocation_id - app_instance_id - usage_source 3. preserving backward compatibility for current allocation billing consumers

Ledger Direction

No separate app-runtime ledger is allowed.

Rules: 1. all usage debits still become ledger_entries 2. reference_type and reference_id must be able to identify app-runtime usage provenance 3. immutable-ledger rules remain unchanged

Control-Plane Overhead

App-runtime metering must distinguish: 1. workload consumption 2. control-plane overhead

Use control_plane_component for this distinction.

That is required because: 1. tenant_dedicated + project may attribute control-plane cost directly to the owning project 2. tenant_dedicated + tenant may distribute control-plane cost across projects by policy 3. platform_managed may allocate shared-service overhead by tier or policy

Initial Runtime Targets

The first metering-capable platform apps should be: 1. scheduler reference app 2. model serving

The first billable shapes to support are: 1. control-plane runtime uptime 2. project-attributed job or request usage

Reconciliation Requirements

Metering implementation must preserve: 1. deterministic linkage from usage record to ledger entry 2. deterministic linkage from usage record to app_instance_id 3. timeline reconstruction by correlation_id 4. compatibility with current billing diagnostics and reconciliation paths

Backward Compatibility

Allocation billing remains valid.

Required compatibility rules: 1. existing allocation rows and APIs keep working 2. existing usage CSV remains valid, but may gain additive columns later 3. current billing confidence behavior for allocation release boundaries must not regress

Execution Slices

  1. schema + service primitive extension
  2. billing API filter/export extension
  3. one reference app producing metered usage
  4. ops/runbook and diagnostics support for mixed allocation/app-runtime billing
  1. doc/architecture/App_Runtime_Billing_Model_v1.md
  2. doc/architecture/App_Control_Plane_v1.md
  3. doc/architecture/db_schema_v1.sql
  4. doc/governance/Billing_Contract_Freeze_and_Roadmap_v1.md