Add low/base/high demand forecasts, service objectives with timestamped observations, and workload operations labor for resource:tenant:coulomb:coulomb-social.
145 lines
6.9 KiB
JSON
145 lines
6.9 KiB
JSON
{
|
||
"schema_version": "0.1",
|
||
"record_kind": "workload_demand_forecast",
|
||
"resource_id": "resource:tenant:coulomb:coulomb-social",
|
||
"service_id": "coulomb-social",
|
||
"workload_id": "coulomb-social",
|
||
"tenant_id": "tenant:coulomb",
|
||
"environment": "production",
|
||
"cost_attribution_key": "resource:tenant:coulomb:coulomb-social",
|
||
"currency": "EUR",
|
||
"forecast_version": "csoc-demand-2026-08-v1",
|
||
"created_at": "2026-08-12T09:03:47Z",
|
||
"horizon_months": 12,
|
||
"planning_period": {
|
||
"start": "2026-09-01",
|
||
"end": "2027-08-31"
|
||
},
|
||
"tenancy_model": {
|
||
"deployment_shape": "instance_per_client",
|
||
"this_record_scope": "single Coulomb reference instance on shared Railiance capacity",
|
||
"current_tenant": "tenant:coulomb",
|
||
"external_client_instances": "each future paying client is a separate deployment and its own resource id — not rolled into these scenarios"
|
||
},
|
||
"declared_capacity_floor": {
|
||
"replicas": 1,
|
||
"cpu_request_millicores": 100,
|
||
"cpu_limit_millicores": 1000,
|
||
"memory_request_mi": 256,
|
||
"memory_limit_mi": 1024,
|
||
"source": "railiance-apps/charts/coulomb-social/values.yaml"
|
||
},
|
||
"proxies": {
|
||
"units": {
|
||
"active_tenants": "count of tenant_id values with activity in period",
|
||
"active_members": "count of Member rows with session activity in period (proxy: monthly active)",
|
||
"http_requests_per_month": "application HTTP requests (ingress to app Service)",
|
||
"oidc_logins_per_month": "successful OIDC/dev login completions",
|
||
"background_jobs_per_month": "async/worker jobs (none in v1 runtime — reserved)",
|
||
"app_database_gb": "logical size of coulomb_social_db on apps-pg",
|
||
"app_database_growth_pct_per_month": "month-over-month logical DB growth",
|
||
"stored_media_gb": "app-owned binary media (PV or object store); Forgejo markdown is NOT counted here",
|
||
"forgejo_content_gb_bound": "markdown/assets bound for spaces of this tenant (shared Forgejo service; attribution only)",
|
||
"ingress_gb_per_month": "bytes into the app Service",
|
||
"egress_gb_per_month": "bytes out of the app pod (HTML + API responses; excludes Forgejo browser edits)",
|
||
"cpu_request_millicores": "declared Kubernetes request",
|
||
"memory_request_mi": "declared Kubernetes request",
|
||
"operator_hours_per_month": "workload-owned ops labor hours (see labor doc)"
|
||
}
|
||
},
|
||
"scenarios": {
|
||
"low": {
|
||
"label": "parallel-host operator use (current posture)",
|
||
"description": "app.coulomb.social live; apex remains Bubble; handful of operator accounts; no bulk member migration.",
|
||
"active_tenants": 1,
|
||
"active_members": 5,
|
||
"http_requests_per_month": 5000,
|
||
"oidc_logins_per_month": 80,
|
||
"background_jobs_per_month": 0,
|
||
"app_database_gb": 0.1,
|
||
"app_database_growth_pct_per_month": 5,
|
||
"stored_media_gb": 0,
|
||
"forgejo_content_gb_bound": 0.01,
|
||
"ingress_gb_per_month": 0.5,
|
||
"egress_gb_per_month": 1,
|
||
"cpu_request_millicores": 100,
|
||
"cpu_limit_millicores": 1000,
|
||
"memory_request_mi": 256,
|
||
"memory_limit_mi": 1024,
|
||
"replicas": 1,
|
||
"operator_hours_per_month": 2,
|
||
"operator_hourly_eur": 60
|
||
},
|
||
"base": {
|
||
"label": "Coulomb community active on rebuild",
|
||
"description": "Members and spaces actively used on app host; Bubble still may exist but primary day-to-day for Coulomb operators/members shifts to rebuild; still single tenant:coulomb instance.",
|
||
"active_tenants": 1,
|
||
"active_members": 50,
|
||
"http_requests_per_month": 150000,
|
||
"oidc_logins_per_month": 1500,
|
||
"background_jobs_per_month": 0,
|
||
"app_database_gb": 1,
|
||
"app_database_growth_pct_per_month": 10,
|
||
"stored_media_gb": 2,
|
||
"forgejo_content_gb_bound": 0.5,
|
||
"ingress_gb_per_month": 5,
|
||
"egress_gb_per_month": 15,
|
||
"cpu_request_millicores": 200,
|
||
"cpu_limit_millicores": 1000,
|
||
"memory_request_mi": 512,
|
||
"memory_limit_mi": 1024,
|
||
"replicas": 1,
|
||
"operator_hours_per_month": 4,
|
||
"operator_hourly_eur": 60
|
||
},
|
||
"high": {
|
||
"label": "full Bubble parity load on this Coulomb instance",
|
||
"description": "All Coulomb spaces/content migrated; peak community concurrency; optional second replica for HA; still NOT multi-client — external clients would be separate instances.",
|
||
"active_tenants": 1,
|
||
"active_members": 500,
|
||
"http_requests_per_month": 2000000,
|
||
"oidc_logins_per_month": 20000,
|
||
"background_jobs_per_month": 5000,
|
||
"app_database_gb": 10,
|
||
"app_database_growth_pct_per_month": 15,
|
||
"stored_media_gb": 50,
|
||
"forgejo_content_gb_bound": 20,
|
||
"ingress_gb_per_month": 40,
|
||
"egress_gb_per_month": 120,
|
||
"cpu_request_millicores": 500,
|
||
"cpu_limit_millicores": 2000,
|
||
"memory_request_mi": 1024,
|
||
"memory_limit_mi": 2048,
|
||
"replicas": 2,
|
||
"operator_hours_per_month": 8,
|
||
"operator_hourly_eur": 60
|
||
}
|
||
},
|
||
"monthly_labor_eur_proxy": {
|
||
"low": 120.0,
|
||
"base": 240.0,
|
||
"high": 480.0,
|
||
"formula": "operator_hours_per_month × operator_hourly_eur",
|
||
"note": "Infrastructure EUR is unknown here (allocated share of cluster/apps-pg/ingress/identity). Leave infrastructure null in cost joins until platform/fin-hub supplies figures."
|
||
},
|
||
"assumptions": [
|
||
"Scenarios are per-instance demand for tenant:coulomb, not fleet-wide multi-tenant aggregation.",
|
||
"Current production posture (2026-08) matches low: parallel host, identity + shell + spaces MVP, Bubble still on apex.",
|
||
"Space page bodies live in Forgejo (ADR-0002); forgejo_content_gb_bound is attribution input for shared Forgejo, not a claim that coulomb-social operates that storage.",
|
||
"App media PV is currently disabled in chart; stored_media_gb remains 0 until object storage or PV is enabled.",
|
||
"No application worker/queue in v1; background_jobs_per_month is 0 until a job system exists (high reserves headroom).",
|
||
"OIDC/identity platform traffic cost is not counted as app infrastructure; only app HTTP path is in http_requests_per_month.",
|
||
"Database is coulomb_social_db on shared apps-pg; logical size ownership is workload, physical volume ownership is railiance-platform.",
|
||
"CPU/memory figures are declared requirements for rightsizing; observed utilization is cluster authority when sampled.",
|
||
"Operator hourly rate €60 matches resource-control backup labor convention for comparability; not a payroll fact.",
|
||
"Falsifiable: after each calendar month, compare active_members, http_requests, app_database_gb, and operator_hours against the chosen scenario band."
|
||
],
|
||
"source_evidence": [
|
||
"docs/resource-evidence/demand-forecast-2026-08.md",
|
||
"docs/adr/ADR-0002-space-content-forgejo-markdown.md",
|
||
"docs/deploy.md",
|
||
"railiance-apps/charts/coulomb-social/values.yaml",
|
||
"resource-control/data/resources/coulomb-social-production.json",
|
||
"workplans/CSOC-WP-0005-resource-demand-and-cost-evidence.md"
|
||
]
|
||
}
|