Cloud and regions
What MainSDK Cloud stores, in which of three regions, how a project joins it, and why a Cloud limit never breaks your app.
Status Status is where the work is: Planned (in a milestone, not started), Building (tickets in progress), Preview (usable, may change), then the stability it ships at.
Stability The promise an interface ships with.
- Stable Follows semantic versioning; breaking changes need a new major, 12 months of overlap and a codemod.
- Beta Usable in production; may change before it becomes stable.
- Experimental May change or go away; needs an explicit opt-in in main.yaml.
MainSDK Cloud is optional. Your app and every check work without it. When you do log in, your project's data stays in the region you chose: US, EU or India. Cloud arrives in phase 2 (milestone 0.6).
Three regions
flowchart TB
app["Your app<br/>project: { id, region: eu }"] -- "events, traces, decisions" --> eui
subgraph usr["US region"]
usi["Ingest"] --> uss[("Store")]
end
subgraph eur["EU region"]
eui["Ingest"] --> eus[("Store")]
end
subgraph india["India region"]
ini["Ingest"] --> ins[("Store")]
end
wrong["Call reaches the wrong region"] --> usi
usi -. "forward or refuse with RFC 9457,<br/>store nothing" .-> eui- Each project's events, traces and decisions are kept in its chosen region. A call that reaches another region's endpoint is forwarded or refused, and nothing is stored there.
- Every region is included on every plan at no extra cost. There is no data region add-on.
- Still open: the default region when you don't choose one (taken from
main.yamlor asked at login).
Your app's own data follows the same three regions (ADR-0006): db keeps one store per region and writes each record to its owner's region, check refuses queries that join across regions, analytics combine regions only as totals, and moving a user between regions is an audited job.
What Cloud stores
| Stored | Notes |
|---|---|
| Projects, environments and keys | Keys shown masked in the console |
| Events: trace spans, log lines, errors, policy decisions, gate runs, action calls | Redacted in your app before they are sent |
| History | 7 days on Free, 30 days on Teams |
What Cloud never needs: your request path. See request lifecycle.
Joining Cloud
sequenceDiagram participant D as You participant C as mainsdk CLI participant B as Browser participant M as MainSDK Cloud D->>C: mainsdk init (no account, no network) C->>C: write project id (UUIDv7) to main.yaml D->>C: mainsdk login --region eu C->>M: device authorization (RFC 8628) M-->>C: short code D->>B: approve the code M-->>C: project claimed, same prj_ id C->>M: optional: upload the last 7 days of local events
- The project id is not a credential. It is a UUIDv7 in
main.yaml, shown asprj_01JC8Q…. A public repo shows it, so only an ingest key or a platform OIDC token can send data. - No copying keys. Login uses the device flow; you approve a code in the browser.
- Ingest keys: one per environment.
msk_live_…for prod,msk_test_…for dev and stage, so secret scanners catch leaks. In CI and on Vercel, the platform's OIDC token replaces the key. - Forks get a new id. If an id is already claimed under a different git remote, login offers a new one;
mainsdk init --new-iddoes it by hand. - Logout stops sending at once. The app and every check keep working locally.
Every call carries the wire contract version in a mainsdk-protocol header. The Cloud supports the current and two previous SDK majors.
The 402 rule
Only what reaches our Cloud is metered. Your machine is never metered, and security is never metered.
flowchart LR
a["0–80%<br/>free allowance"] --> w["80%<br/>warning in CLI and email"]
w --> g["100% to 120%, or 7 days<br/>grace"]
g --> c{"Card on file?"}
c -- yes --> p["Pay per 100,000 events<br/>up to your monthly cap"]
c -- no --> e["HTTP 402 from Cloud only"]
p -- cap reached --> e{ "type": "https://mainsdk.dev/errors/MAIN-CLOUD-0402", "title": "Free allowance used",
"status": 402, "detail": "50,000 events used this month. Add a card or move to Teams." }After a 402, events stop going online and hosted reviewers stop. Your app keeps running, every check, gate, guarantee and runtime enforcement keeps working, and logs stay in your terminal (ADR-0003, ADR-0007).
The allowance of 50,000 events a month is a proposal. The price per 100,000 events and per hosted reviewer run is not set yet.
Production access
Any access to production data in Cloud needs SSO or a passkey with phishing-resistant MFA (ADR-0008). Production live tail and debug sessions ask for a fresh passkey no older than 5 minutes. MainSDK staff follow the same rules and appear in the same project audit view. There is no remote shell into production.
Later
| What | Phase |
|---|---|
| Organisations, project transfer, SSO and SCIM for the console (Teams) | 2 |
| Self-hosted and air-gapped control planes with PKI-signed licences | 4 (Fleet) |
Next
- Telemetry and signals: what is redacted before it is sent.
- Free in the app, paid in the Cloud: the plans and their limits.
- Data and regions: how your app's own data stays in its region.
Was this page helpful?