| 1 | # π€ Tier economics β what a space costs us, what a space pays us |
| 2 | |
| 3 | This is the public record of how Eleven's space-upgrade prices relate to what |
| 4 | spaces actually cost to run. It exists because of a commitment made in #562: |
| 5 | **the price is the cost plus resilience, and that should be a checkable |
| 6 | claim.** When the public ledger ships (#550 Part 11), this document is the |
| 7 | cost-model half of the books; until then it's the working version, re-derived |
| 8 | whenever prices or input rates change. |
| 9 | |
| 10 | Living doc: the *formulas* are the contract; the *numbers* are a snapshot |
| 11 | (dated below). If you're reading this to make a decision, re-derive first. |
| 12 | |
| 13 | ## Principles (decided in #562, held here) |
| 14 | |
| 15 | - **Self-hosting is no-obligation.** The paid thing is our hosting |
| 16 | convenience, never the software. A self-hosted space owes nothing β and one |
| 17 | that leans on shared glue we run (the push relay, the signed release feed) |
| 18 | is warmly invited, never required, to contribute. |
| 19 | - **We can only price what ciphertext exposes**: storage bytes, member counts, |
| 20 | space counts. Never content, never analytics. |
| 21 | - **Paying is not anonymous.** Checkout runs on Stripe, which collects a |
| 22 | name, email, and card β and as the merchant we can see those in Stripe's |
| 23 | dashboard. Our own stores still hold only two opaque Stripe ids, a tier |
| 24 | key, and a period end per paid space, so a compromise of our systems |
| 25 | exposes no billing identity. |
| 26 | - **The free tier is first-class.** Constraints (storage quotas) ratchet later |
| 27 | and only for *new* spaces; existing spaces keep what they have. |
| 28 | - **AI is never bundled β and off by default.** Model tokens are the one |
| 29 | marginal cost that can dwarf a subscription; bot/AI usage is always opt-in, |
| 30 | and when opted into it's a metered add-on (design in #562). |
| 31 | |
| 32 | ## The price book (as of 2026-07-22) |
| 33 | |
| 34 | | Tier | Price | Billing | |
| 35 | |---|---|---| |
| 36 | | Family | β¬5.50/year | annual only | |
| 37 | | Community & Friends | β¬0.11 per member per year, β¬11 minimum (first 100 members included) | annual only, per member | |
| 38 | | Business | β¬11 per person per year | annual only, per seat | |
| 39 | |
| 40 | What paying buys today: the space stops counting toward the account's |
| 41 | three-space creation limit, it is never reclaimed as unused, and it carries a |
| 42 | larger storage allowance (below). |
| 43 | |
| 44 | ## Per-seat Business (decided 2026-07-22) |
| 45 | |
| 46 | Business flipped from flat (β¬99/month / β¬999/year) to **β¬11 per person per |
| 47 | year** β the price scales with the team instead of gating at a size the |
| 48 | space has to grow into. The crossover with the old flat price was ~91 people, |
| 49 | so a small business pays a fraction of what it used to and a big one |
| 50 | continuously *becomes* the old plan. Mechanics, all held by the provisioner |
| 51 | (`per_seat` in the price book; billing.go, meter.go): |
| 52 | |
| 53 | - **Seats are counted server-side, never self-declared.** A seat is a |
| 54 | non-agent member (`people` in controld's stats) β bots are free. Checkout |
| 55 | charges the live count as the Stripe line-item quantity; the ledger mirrors |
| 56 | whatever the subscription actually bills (`spaces.seats`, from Stripe's own |
| 57 | item via webhook). |
| 58 | - **Dropoffs and growth settle at renewal, never mid-cycle.** In the week |
| 59 | before each annual renewal the meter sweep re-counts and sets the |
| 60 | subscription quantity with `proration_behavior=none`: shrinkage renews |
| 61 | cheaper, growth renews dearer, and nobody sees a mid-year β¬33 refund or |
| 62 | surprise top-up. That one Stripe knob is the entire dropoff policy. |
| 63 | - **Annual only.** β¬11/12 β β¬0.92/person/month; Stripe's fixed β¬0.25 per |
| 64 | charge makes tiny monthly invoices ~7%-fee territory and 12Γ the dunning |
| 65 | surface. Same reasoning as Family's annual-only, now applied where the |
| 66 | per-charge ticket is small. |
| 67 | - **The allowance is per seat and pooled**: 11 GB Γ seats, one shared pot, |
| 68 | so a heavy channel never hits an individual wall. Derivation per seat: |
| 69 | net β β¬10.82, the 80/20 reserve takes β¬8.80, leaving ~β¬2.00 Γ· |
| 70 | β¬0.168/GB-year β 12 GB β published as 11 (the elevens are load-bearing). |
| 71 | At ~91 seats the pool crosses 1 TB exactly where revenue crosses the old |
| 72 | β¬999 β the tables stay coherent. |
| 73 | - **Small teams run thinner, and that's accepted.** Under ~10 seats the |
| 74 | fixed per-space costs (resident slot, the `stream` replication rung) eat |
| 75 | past the 20% line β a 3-person space runs maybe 50β60% margin, not 80%+. |
| 76 | Storage is still capped per seat, so no team size is structurally |
| 77 | loss-making; tiny businesses grow. |
| 78 | |
| 79 | ## Storage allowances (as of 2026-07-14 β margin-derived) |
| 80 | |
| 81 | Space creation is also gated by an account quota (3 free spaces; paid spaces |
| 82 | don't count) and, when the home server enables it, a hashcash proof-of-work |
| 83 | per creation β the anti-Sybil cost that runs inside the create animation. |
| 84 | |
| 85 | Allowances are **a function of margin** (Paul's 80/20 rule, 2026-07-14): an |
| 86 | allowance is the storage a space could fill *forever* with the tier still |
| 87 | keeping β₯80% of gross as profit β |
| 88 | |
| 89 | ``` |
| 90 | allowance_GB = (net β 0.80 Γ gross β compute_cost) Γ· (storage_rate Γ 12) |
| 91 | ``` |
| 92 | |
| 93 | β computed at the tighter billing case. Two honest exceptions: the Free tier |
| 94 | has no revenue (its 1 GB is pure cost containment), and Family at β¬5.50/year |
| 95 | buys only ~3 GB at strict 80/20 β we hold it at 5 GB and accept a ~74% |
| 96 | worst-case floor rather than shrink the family tier. |
| 97 | |
| 98 | | Tier | Allowance | |
| 99 | |---|---| |
| 100 | | Free | 1 GB | |
| 101 | | Family | 5 GB | |
| 102 | | Community & Friends | 20 GB | |
| 103 | | Business | 11 GB per person (pooled) | |
| 104 | |
| 105 | The allowances ARE the enforced caps (`LCHAT_CLOUD_STORAGE_CAPS` β per-seat |
| 106 | entries use the `/seat` suffix, e.g. `business=11GB/seat`) β the published |
| 107 | table and the config must always match. A large team's pooled allowance |
| 108 | deliberately exceeds the shared machine's ~38 GB disk: the promise is |
| 109 | honored **on demand** β a Business space genuinely growing toward its |
| 110 | allowance gets a Hetzner volume attached (minutes, up to 10 TB per volume) |
| 111 | until attachment storage moves off-box to R2 (#550), which retires that |
| 112 | ceremony entirely. Uploads past an allowance are refused (nothing is ever |
| 113 | deleted, and messages always keep working). |
| 114 | |
| 115 | ## Input rates (snapshot, 2026-07-11) |
| 116 | |
| 117 | | Input | Rate | Source | |
| 118 | |---|---|---| |
| 119 | | Stripe fee (EU consumer card) | 1.5% + β¬0.25 per charge | Stripe pricing; EUR settlement, no FX | |
| 120 | | Attachment storage (R2) | ~β¬0.014/GB-month | $0.015, zero egress | |
| 121 | | DB snapshots (S3) | ~β¬0.021/GB-month | $0.023 | |
| 122 | | Box (whole cloud plane) | ~β¬35/month | Hetzner + fixed services | |
| 123 | | Resident-process slot | ~β¬0.81/month | box Γ· 40-instance capacity | |
| 124 | |
| 125 | **Hibernation is live in production** (the activator, #550 Part 4: running on |
| 126 | the box against the real S3 bucket, verified by a hibernating canary |
| 127 | instance), and spaces adopt it **per-host** as the rollout proceeds |
| 128 | (`routes.hibernate`). A flagged space that goes idle is an S3 prefix, not a |
| 129 | process β marginal cost while asleep is storage alone, and the slot rate |
| 130 | applies only to the fraction of time it's awake. The estimates below model a |
| 131 | flagged space; a not-yet-flagged space still carries the full resident slot |
| 132 | rate (~β¬9.70/year at full box density), which trims its margin by that amount |
| 133 | until its flip. One deliberate permanent exception: **a space with a bot |
| 134 | sidecar never sleeps** (the sidecar's WebSocket holds it awake) β one more |
| 135 | reason AI usage carries its own meter instead of hiding in a flat price. |
| 136 | |
| 137 | ## Durability per tier β the replication ladder (decided 2026-07-14) |
| 138 | |
| 139 | The fleet's S3 bill is ~100% Tier-1 *requests*, not data (#836), and the one |
| 140 | request stream that scales with activity is litestream's change-driven WAL |
| 141 | sync β worth pennies a year on a quiet space and up to ~β¬145/year on a |
| 142 | worst-case space that writes every second around the clock. That cost profile |
| 143 | is why durability is now a **per-plan replication class** on the activator's |
| 144 | replica (`routes.replication`; mechanism #866, billing push #869): |
| 145 | |
| 146 | | Tier | Class | Awake sync cadence | Hard-crash loss window | Request cost/yr (est.) | |
| 147 | |---|---|---|---|---| |
| 148 | | Business | `stream` | change-driven ~1s | seconds | ~β¬2β20 typical; ~β¬145 worst case | |
| 149 | | Community & Friends | `batched` | at most every 5m | minutes | β€ ~β¬0.50 | |
| 150 | | Free + Family | `daily` | at wake + every 24h | up to a day | pennies | |
| 151 | |
| 152 | Three things the ladder deliberately does **not** change: |
| 153 | |
| 154 | - **Every graceful path flushes in full** β idle sleep, deploy, restart, |
| 155 | shutdown all checkpoint the space to S3 regardless of class. The class only |
| 156 | bounds what a *sudden* box loss can take, and only while awake. |
| 157 | - **Hibernation's parked copy is always exactly current** β sleeping on a |
| 158 | lower rung is not a weaker backup; the rung applies to awake windows only. |
| 159 | - **Nothing about confidentiality** β the replica is the same ciphertext the |
| 160 | server already holds. |
| 161 | |
| 162 | The honest member-facing framing (held in the changelog and any plan copy): |
| 163 | *backed up every time your space goes quiet, and at least nightly; a |
| 164 | catastrophic server failure may cost the most recent hours on Free/Family, |
| 165 | minutes on Community, seconds on Business.* One caveat priced in above: a |
| 166 | space with a bot sidecar never sleeps, so for those the "at least nightly" |
| 167 | floor is the real day-to-day cadence on the daily rung. |
| 168 | |
| 169 | **One Business plan, not a "Business Plus" (decided 2026-07-14).** The full |
| 170 | resilience stack β streaming replication, the retention ladder behind |
| 171 | point-in-time restore, room to tighten the crash-failover window β costs |
| 172 | β¬2β20/year on realistic Business spaces against revenue that scales with the |
| 173 | team (per-seat since 2026-07-22: β¬330/year at 30 people; the decision was |
| 174 | taken against the flat β¬999β1,188/year and holds at per-seat scale). |
| 175 | A resilience delta that small can't carry a second paid tier: splitting it |
| 176 | would add a Stripe price pair, picker copy, and a matrix cell to explain, |
| 177 | to sell something we can afford to include. So Business simply *includes* |
| 178 | best-available durability, and the ladder stays three legible rungs priced |
| 179 | by what they actually cost. If a segment ever demands contractual RPO/RTO, |
| 180 | multi-region replicas, or compliance-grade restore drills, that's a |
| 181 | custom/Enterprise conversation β negotiated, not a checkbox tier β and the |
| 182 | books will show its costs separately when it exists. |
| 183 | |
| 184 | ## The model |
| 185 | |
| 186 | For a tier with gross annual revenue `G` across `n` charges/year: |
| 187 | |
| 188 | ``` |
| 189 | net = G β (0.25 Γ n) β (0.015 Γ G) # Stripe fees out |
| 190 | cost = GB_stored Γ storage_rate Γ 12 # media, the only real dial |
| 191 | + slot_rate Γ 12 Γ awake_fraction # compute while awake |
| 192 | + repl_requests # by replication class (see Durability): |
| 193 | # daily/batched β β¬0; stream β β¬2β20 |
| 194 | + ~β¬0.10 # wakes, other requests, push (noise) |
| 195 | profit = net β cost |
| 196 | break_even_GB = net Γ· (storage_rate Γ 12) # where a space stops covering itself |
| 197 | ``` |
| 198 | |
| 199 | Message *text* is never material: a decade of busy family chat is ~50 MB |
| 200 | (~β¬0.01/year). The only way a space outspends its price is stored media. |
| 201 | |
| 202 | ## Estimates per tier (snapshot, 2026-07-27) |
| 203 | |
| 204 | Usage profiles are typical-case estimates, not caps. Business is per-seat, so |
| 205 | it gets two team sizes β the structure holds at both: |
| 206 | |
| 207 | | Tier | Gross/yr | Net/yr | Profile (est.) | Cost/yr (est.) | Profit/yr (est.) | Margin | Break-even storage | |
| 208 | |---|---|---|---|---|---|---|---| |
| 209 | | Family β¬5.50/y | β¬5.50 | β¬5.17 | 10 members, 5 GB, mostly asleep | ~β¬1.00 | ~β¬4.15 | ~76% | ~31 GB | |
| 210 | | Community β¬11 min | β¬11.00 | β¬10.59 | 40 members (first 100 included), 11 GB, awake ~20% | ~β¬5.50 | ~β¬5.10 | ~46% | ~40 GB | |
| 211 | | Community β¬0.11/member | β¬55.00 | β¬53.93 | 500 members, 11 GB, awake ~50% | ~β¬12.00 | ~β¬42 | ~76% | ~320 GB | |
| 212 | | Business β¬11/p/y | β¬330.00 | β¬324.80 | 30 people, 60 GB pooled, awake ~50% | ~β¬20.00 | ~β¬305 | ~92% | ~1.9 TB | |
| 213 | | Business β¬11/p/y | β¬1,650.00 | β¬1,625.00 | 150 people, 300 GB pooled, awake ~50% | ~β¬75.00 | ~β¬1,550 | ~94% | ~9.7 TB | |
| 214 | |
| 215 | Readings: |
| 216 | |
| 217 | - **Break-even storage is the number that matters.** A Family space must hold |
| 218 | ~31 GB of media *forever* before β¬5.50/year stops covering it. That makes |
| 219 | #561's storage quotas easy to set generously: the shipped allowances |
| 220 | (5 GB Family, 11 GB Community, 11 GB per seat Business) sit far below |
| 221 | every tier's break-even, so no tier can structurally lose money while |
| 222 | still feeling roomy in practice. |
| 223 | - **Stripe's fixed fee punishes small monthly charges.** Family pays ~6% of |
| 224 | gross in fees on its single annual charge; a hypothetical β¬0.46/month |
| 225 | Family would pay ~11Γ. This is why the whole ladder is annual only β at |
| 226 | β¬0.11 a member, a monthly charge would be mostly Stripe fee (and a space |
| 227 | is a years-scale commitment anyway). |
| 228 | - **The fixed floor is small.** The whole plane costs ~β¬420/year; roughly 80 |
| 229 | Family spaces, or ~40 Community minimums, or one 40-person Business space |
| 230 | cover it outright. Beyond that, margin is contribution toward resilience and the |
| 231 | co-operative endgame (#550 Part 10). |
| 232 | - **Business margin is deliberately not an infra story.** At ~92β94% margin |
| 233 | on realistic teams the price is buying priority support, SLAs, and features |
| 234 | to come β not bytes. (Small teams run thinner β see Β§ Per-seat.) If that |
| 235 | feels wrong when the books go public, that's the conversation the books |
| 236 | exist to force. |
| 237 | |
| 238 | ## What could invert these numbers |
| 239 | |
| 240 | 1. **AI/bot usage** β excluded above by design; metered add-on or BYO key. |
| 241 | 2. **Media hoarding past break-even** β bounded by #561 quotas when they land. |
| 242 | 3. **A space that never sleeps** β bot-sidecar spaces; today that's a known |
| 243 | subsidy, priced into the margins above. |
| 244 | 4. **Rate changes** β Stripe, R2/S3, or box pricing move; re-derive. |
| 245 | |
| 246 | ## Re-deriving |
| 247 | |
| 248 | Update the two snapshot tables (input rates + estimates) and the date stamps; |
| 249 | the formulas don't change. **This document publishes:** the status site's |
| 250 | Economics page (`web/status/economics.{html,json}`) is the public snapshot of |
| 251 | these tables β update it in the same change and copy it to the box |
| 252 | (`docs/status.md Β§ Keeping the tier-economics page current`; the contract |
| 253 | test pins the arithmetic). Two numbers stay out of the public copy by |
| 254 | design: the per-box instance cap and the box disk size (the status site's |
| 255 | capacity privacy rule β band words, never cap values). Current prices live in the provisioner's price book |
| 256 | (`LCHAT_STRIPE_PRICES` on the cloud service; see |
| 257 | `cloud-provisioner.md Β§ Billing`); money truth lives in the Stripe dashboard; |
| 258 | entitlement truth in the provisioner ledger. Related: #550 (architecture + |
| 259 | public books), #561 (limits/meters), #562 (pricing decisions), #614 |
| 260 | (memberβadmin subscriptions β a different product, same Stripe account). |
| 261 | |