Skip to content

Billing & Credits Architecture

Satusky uses a prepaid credit system. Credits are consumed by measured resource usage and machine usage records, then written into an immutable transaction history.

runtime usage
├── deployment / pod metrics
└── machine usage records
credit_usage_job
pricing lookup + deduction
credit_transactions ledger

The platform uses PostgreSQL records such as credits, credit_transactions, pricing_configs, and machine_usages to calculate and persist billing state.

The current implementation has two related measurement streams:

  • deployment/resource observations from Kubernetes metrics and related services,
  • machine usage records for rented/allocated machine time.

The architecture should keep those distinct: “how much a workload consumed” and “which machine capacity was rented” are related, but not the same accounting primitive.

JobRole
credit_usage_jobProcesses due usage and writes deductions.
balance_alert_jobSends low-balance notifications.
auto_topup_jobCharges configured payment methods when enabled.
grace_period_jobEnforces insufficient-credit lifecycle.
monthly_invoice_jobProduces invoice records / invoices.
sla_credit_jobApplies SLA-related credit adjustments.

The current backend behavior is stricter than “pause but preserve everything.” When a deployment enters grace period:

  1. routing is disabled so traffic no longer reaches the workload,
  2. the system may evaluate whether the deployment should be deleted early based on low resource usage,
  3. once the grace period expires, cleanup deletes the deployment and associated resources through either the unified cleanup path or a legacy fallback path.

That means the user-facing contract must not promise that all data is preserved after grace expiry unless the deletion semantics are intentionally changed first. The cleanup logic can include PVC deletion.

A mature billing system should make these states explicit:

StateUser-visible meaning
Healthy balanceNormal operation
Low balanceWarn only
Grace periodWorkload impaired/suspended with a clear deadline
ExpiredExplicit destruction semantics, including exactly what happens to persistent data

If the desired product behavior is “preserve volumes after compute suspension,” that is a future product decision and must be implemented before the docs claim it.

Transactions are append-only. Current balance is derivable from the ledger. SLA credits and manual/admin adjustments are additional transaction types rather than mutable edits to history.

GapTarget
User expectation around grace expiry is easy to misstate.Document exact deletion/preservation semantics and surface them in CLI output.
Usage language can blur deployment metrics with machine rental records.Keep both models visible and reconcile them in one billing explanation.
Billing interacts with cleanup, domains, and storage.Treat billing as a lifecycle driver, not merely a calculator.