Lesson 37 — Plans & tiers: what the cloud grants each account
Goal: by the end of this lesson you can tell which tier an org is on, predict what its graphs may and may not do, read the quota badge in the editor, and know where the operator-side levers — changing a tier, freezing an abuser, handing out a demo — are documented.
Concepts introduced: the :plan slug, the access tiers
(anonymous / free / network / dedicated) and the suspended
kill-switch, per-tier effects, the egress rate cap, ephemeral demo
orgs.
The model in one paragraph
On the cloud, every org carries a :plan slug. A plan resolves to
two things: the side effects its submitted graphs may use (from
Lesson 16) and its quota ceilings (fns, list items, outbound
calls/min). That's the whole tier system — a tier is just a named
bundle of "what effects" + "how much". The single source of truth is
graphden.tenancy.plan; the human-readable table lives in
PLANS.md.
The tiers
| Tier | Network? | Own DB? | Fns | Calls/min | Notes |
|---|---|---|---|---|---|
anonymous |
✗ | ✗ | 200 | 0 | locked demo, ephemeral, the fail-safe default |
free (registered) |
✓ metered | ✓ | 500 | 120 | a signed-up account |
network (paid) |
✓ | ✓ | 5,000 | 6,000 | higher ceilings |
dedicated (paid) |
✓ | ✓ | 5,000 | ∞ | its own pod + always-on services (lesson 35) |
suspended |
✗ | ✗ | 0 | 0 | operator freeze — no effects, no writes |
The key line is anonymous → free. Anonymous is what a landing
visitor gets: no outbound network, small ceilings, and the org is
reaped after a TTL — you can try graphs with nothing to lose. It is
also the fail-safe default: an org with no slug resolves here, so
a mis-provisioned account is locked, never accidentally opened.
Free (registered) is what signing up gives you (lesson 36),
and it is genuinely useful: base effects PLUS metered :network. It
is kept as long as it is used: after 60 days with no sign-in, no API
call, no run and no edit, the org is scheduled for deletion two weeks out and everyone in
it gets an email saying so, plus a last reminder two days before —
one sign-in, one call, one run or one edit keeps it. In
practice that means you can build a personal Telegram bot, keep a few
hundred records, and connect to your own external database — the
external :sql-query / :sql-exec base-fns count as network, not
raw-sql (arbitrary SQL on the platform DB stays forbidden for
everyone; see lesson 16 + SECURITY_MODEL.md).
Outbound is bounded, not blocked: every external call goes through the SSRF egress guard (no internal / platform targets) and a per-tier calls-per-minute cap, so a free bot works but can't be turned into a DDoS.
Seeing your quota
The editor shows a small badge above the Explorer's entity list —
fns: N / max, the current org's fn count against its ceiling
(fetched from GET /api/orgs/quota); hover it and the tooltip names
the plan. It is hidden on an uncapped plan. When you approach the
ceiling it's a nudge to upgrade; if the tooltip ever names
anonymous on an account you thought was registered, that's the
fail-safe default telling you the org's :plan was never set.
Changing a tier (operator)
:org is a tenant-forbidden entity (lesson 27), so tiers are an
operator activity: one platform-only route sets any org's plan,
and suspended is the freeze — PLANS.md § Suspending an
org and
OPERATIONS.md § Suspending an abusive
org have the route and
the runbook.
Operators also get an extra surface, Platform (its account-menu entry appears
only for platform-tier principals): the cross-org registry of
organizations and the platform-access delegation panel — the
UI counterpart to the operator routes above, and the place where
platform capabilities (like :view-all-stats) are handed to
delegates.
Run your own executor (BYO)
Paid tiers (network / dedicated) can also opt out of executing on
the cloud entirely: the org's graph stays on the hub (editing,
branches, review — everything you've learned), while a bring-your-own
executor on the customer's hardware runs the org's app. The flip is
per-ORG and operator-side; the customer's half is one container with a
minted API token. If you want one app self-run and the rest hosted,
that app gets its own org (you can belong to several — lesson 33) and
only that org flips. As the org's owner you can watch it from
Organization → Executor: the current mode, whether your executor is
connected to the hub right now, and a ready-to-run snippet with your org
prefilled. The full recipe — both halves, verification, troubleshooting —
is BYO_RUNBOOK.md.
Handing out a demo
A landing page mints a throwaway anonymous org for a visitor
through an opt-in, rate-limited endpoint — PLANS.md § Starting an
anonymous demo.
Try it
(A tenancy-addon instance; steps 2–3 need an operator account.)
- Sign up a new account (lesson 36) — its org lands on
free. Hover the quota badge: the tooltip names thefreeplan. - As the operator, freeze that org with the route from
OPERATIONS.md
(
plan=suspended). As the account, try to run any fn — the effect gate now refuses even:db; a create is rejected by the zero row-cap. - Set it back to
free; the account works again on its next request (the resolver isn't memoised). A typo likeplan=premiumis rejected (:plan/unknown) and the tier stays put.
What we glossed over
- The two-layer effect gate — how a tier's effect set actually gates a submitted graph vs a trusted request (TENANCY_SEAM.md § Effect gate).
- The egress guard internals — SSRF classification + the per-org rate/size caps (SECURITY_MODEL.md).
- Fleet placement — how an org is sharded to a pod, which is why the per-pod rate cap behaves per-org (SCALING.md).
Next
Lesson 38 — Services talking to services: one service names another and calls it over HTTP, with the contract shared in the graph.