Plans and scaling
Plans, prepaid compute credits, autoscaling and usage.
Compute is measured in CU (compute units, 1 CU ≈ 1 vCPU and 4 GB RAM) and billed in CU-hours. A database scales between a minimum and a maximum CU with the load, and down to zero after it has been idle for a while. Time at zero costs nothing.
Plans
/databases/plans| Plan | code | Price | Compute hours | Storage | Max CU |
|---|---|---|---|---|---|
| Free | FREE | Rp 0 | about 100 CU-hours a month | 1 GB | 0.25 |
| Starter | STARTER | Rp 119.000 | 50 | 1 GB | 2 |
| Growth | GROWTH | Rp 249.000 | 100 | 3 GB | 4 |
| Scale | SCALE | Rp 379.000 | 150 | 5 GB | 8 |
Always read the current list from GET /databases/plans; each item has id, code, name, description, price (IDR), computeHours, storageGb, minCu, maxCu and suspendTimeoutSeconds.
- Free is the default for a new database, with fixed compute (0.25 CU).
- Paid plans are prepaid credits, charged once from your wallet. The compute hours don't expire; buying again adds to what is left. When the credits run out, the database is suspended until you top up and resume it.
Buy a plan or top up
/databases/{databaseId}/upgradeProp
Type
Check the price first with ?dryRun=true. Nothing is charged:
curl -X POST "https://api.helipod.io/api/databases/$DB/upgrade?dryRun=true" \
-H "Authorization: Bearer hel_your_key" -H "Content-Type: application/json" \
-d '{ "plan": "STARTER" }'{
"success": true,
"data": {
"dryRun": true,
"plan": { "code": "STARTER", "name": "Starter", "price": 119000, "currency": "IDR", "computeHours": 50, "storageGb": 1, "maxCu": 2, "...": "..." },
"price": 119000, "currency": "IDR",
"walletBalance": 250000, "walletBalanceAfter": 131000, "enoughBalance": true,
"kind": "upgrade"
}
}kind is upgrade (free to paid) or top_up (already paid). Without dryRun the call returns the updated database. Send an Idempotency-Key so a retry never charges twice. Not enough balance answers 402 INSUFFICIENT_BALANCE; top up the wallet in the dashboard.
Compute settings
Paid plans only. They apply to every branch.
/databases/{databaseId}/settings{ "success": true, "data": { "minCu": 0.25, "maxCu": 2, "suspendTimeoutSeconds": 300, "planMaxCu": 2, "branches": 2 } }/databases/{databaseId}/settingsProp
Type
Idle compute uses credits
Raising minCu, or setting suspendTimeoutSeconds to 0, keeps compute running when nobody uses the database. Try the change with ?dryRun=true first: the answer shows valid, any problems, and idleComputeHoursPerMonth, the CU-hours that floor would use in 30 days across all branches.
curl -X PATCH "https://api.helipod.io/api/databases/$DB/settings?dryRun=true" \
-H "Authorization: Bearer hel_your_key" -H "Content-Type: application/json" \
-d '{ "minCu": 0.5, "maxCu": 2 }'{ "success": true, "data": { "dryRun": true, "valid": true, "problems": [], "current": { "minCu": 0.25, "maxCu": 2, "...": "..." }, "next": { "minCu": 0.5, "maxCu": 2, "suspendTimeoutSeconds": 300 }, "idleComputeHoursPerMonth": 720 } }On the free plan these calls answer 403 PLAN_REQUIRED; a maxCu above the plan answers 422 PLAN_LIMIT.
Usage
/databases/{databaseId}/usage{
"success": true,
"data": {
"period": { "start": "2026-10-01T00:00:00Z", "end": "2026-10-16T08:00:00Z" },
"computeCuHours": 12.4, "storageGb": 0.31, "historyGb": 0.05, "networkGb": 0.8,
"lastActiveAt": "2026-10-16T07:58:00Z",
"plan": { "code": "STARTER", "name": "Starter", "tier": "paid", "computeHoursIncluded": 50, "computeHoursRemaining": 37.6, "storageGbIncluded": 1, "storageGbRemaining": 0.69 }
}
}Credit balance
/databases/{databaseId}/balance{
"success": true,
"data": {
"plan": "STARTER",
"computeSecondsRemaining": 135360,
"computeCuHoursRemaining": 37.6,
"storageBytesMonthRemaining": 740881858,
"storageGbMonthRemaining": 0.69
}
}Compute credit is counted in CU-hours (one compute unit running for an hour); storage credit in GB-months. Everything is 0 on the free plan. When the compute credit reaches zero the database is suspended until you top up.
Live stats
/databases/{databaseId}/statsProp
Type
curl "https://api.helipod.io/api/databases/$DB/stats?hours=6&grouping=hour" \
-H "Authorization: Bearer hel_your_key"{
"success": true,
"data": {
"available": true,
"reason": null,
"grouping": "hour",
"from": "2026-10-16T02:00:00.000Z",
"to": "2026-10-16T08:00:00.000Z",
"series": [
{ "metric": "cpu_consumed_cores", "points": [ { "t": 1760580000000, "v": 0.04 }, { "t": 1760583600000, "v": 0.11 } ] },
{ "metric": "connection_counts_active", "points": [ { "t": 1760580000000, "v": 2 }, { "t": 1760583600000, "v": 3 } ] }
],
"latest": { "cpu_consumed_cores": 0.11, "connection_counts_active": 3 }
}
}latest holds the last value of each series. When there is nothing to show (the environment has no branch yet, or the database has no compute yet), available is false and reason says why. Stats are read live and are not billed.