eleven / messenger Public
π€ Tier economics β what a space costs us, what a space pays us
This is the public record of how Eleven's space-upgrade prices relate to what spaces actually cost to run. It exists because of a commitment made in #562: the price is the cost plus resilience, and that should be a checkable claim. When the public ledger ships (#550 Part 11), this document is the cost-model half of the books; until then it's the working version, re-derived whenever prices or input rates change.
Living doc: the formulas are the contract; the numbers are a snapshot (dated below). If you're reading this to make a decision, re-derive first.
Principles (decided in #562, held here)
- Self-hosting is no-obligation. The paid thing is our hosting convenience, never the software. A self-hosted space owes nothing β and one that leans on shared glue we run (the push relay, the signed release feed) is warmly invited, never required, to contribute.
- We can only price what ciphertext exposes: storage bytes, member counts, space counts. Never content, never analytics.
- Paying is not anonymous. Checkout runs on Stripe, which collects a name, email, and card β and as the merchant we can see those in Stripe's dashboard. Our own stores still hold only two opaque Stripe ids, a tier key, and a period end per paid space, so a compromise of our systems exposes no billing identity.
- The free tier is first-class. Constraints (storage quotas) ratchet later and only for new spaces; existing spaces keep what they have.
- AI is never bundled β and off by default. Model tokens are the one marginal cost that can dwarf a subscription; bot/AI usage is always opt-in, and when opted into it's a metered add-on (design in #562).
The price book (as of 2026-07-22)
| Tier | Price | Billing | |---|---|---| | Family | β¬5.50/year | annual only | | Community & Friends | β¬0.11 per member per year, β¬11 minimum (first 100 members included) | annual only, per member | | Business | β¬11 per person per year | annual only, per seat |
What paying buys today: the space stops counting toward the account's three-space creation limit, it is never reclaimed as unused, and it carries a larger storage allowance (below).
Per-seat Business (decided 2026-07-22)
Business flipped from flat (β¬99/month / β¬999/year) to β¬11 per person per year β the price scales with the team instead of gating at a size the space has to grow into. The crossover with the old flat price was ~91 people, so a small business pays a fraction of what it used to and a big one continuously becomes the old plan. Mechanics, all held by the provisioner (per_seat in the price book; billing.go, meter.go):
- Seats are counted server-side, never self-declared. A seat is a non-agent member (
peoplein controld's stats) β bots are free. Checkout charges the live count as the Stripe line-item quantity; the ledger mirrors whatever the subscription actually bills (spaces.seats, from Stripe's own item via webhook). - Dropoffs and growth settle at renewal, never mid-cycle. In the week before each annual renewal the meter sweep re-counts and sets the subscription quantity with
proration_behavior=none: shrinkage renews cheaper, growth renews dearer, and nobody sees a mid-year β¬33 refund or surprise top-up. That one Stripe knob is the entire dropoff policy. - Annual only. β¬11/12 β β¬0.92/person/month; Stripe's fixed β¬0.25 per charge makes tiny monthly invoices ~7%-fee territory and 12Γ the dunning surface. Same reasoning as Family's annual-only, now applied where the per-charge ticket is small.
- The allowance is per seat and pooled: 11 GB Γ seats, one shared pot, so a heavy channel never hits an individual wall. Derivation per seat: net β β¬10.82, the 80/20 reserve takes β¬8.80, leaving ~β¬2.00 Γ· β¬0.168/GB-year β 12 GB β published as 11 (the elevens are load-bearing). At ~91 seats the pool crosses 1 TB exactly where revenue crosses the old β¬999 β the tables stay coherent.
- Small teams run thinner, and that's accepted. Under ~10 seats the fixed per-space costs (resident slot, the
streamreplication rung) eat past the 20% line β a 3-person space runs maybe 50β60% margin, not 80%+. Storage is still capped per seat, so no team size is structurally loss-making; tiny businesses grow.
Storage allowances (as of 2026-07-14 β margin-derived)
Space creation is also gated by an account quota (3 free spaces; paid spaces don't count) and, when the home server enables it, a hashcash proof-of-work per creation β the anti-Sybil cost that runs inside the create animation.
Allowances are a function of margin (Paul's 80/20 rule, 2026-07-14): an allowance is the storage a space could fill forever with the tier still keeping β₯80% of gross as profit β
allowance_GB = (net β 0.80 Γ gross β compute_cost) Γ· (storage_rate Γ 12)β computed at the tighter billing case. Two honest exceptions: the Free tier has no revenue (its 1 GB is pure cost containment), and Family at β¬5.50/year buys only ~3 GB at strict 80/20 β we hold it at 5 GB and accept a ~74% worst-case floor rather than shrink the family tier.
| Tier | Allowance | |---|---| | Free | 1 GB | | Family | 5 GB | | Community & Friends | 20 GB | | Business | 11 GB per person (pooled) |
The allowances ARE the enforced caps (LCHAT_CLOUD_STORAGE_CAPS β per-seat entries use the /seat suffix, e.g. business=11GB/seat) β the published table and the config must always match. A large team's pooled allowance deliberately exceeds the shared machine's ~38 GB disk: the promise is honored on demand β a Business space genuinely growing toward its allowance gets a Hetzner volume attached (minutes, up to 10 TB per volume) until attachment storage moves off-box to R2 (#550), which retires that ceremony entirely. Uploads past an allowance are refused (nothing is ever deleted, and messages always keep working).
Input rates (snapshot, 2026-07-11)
| Input | Rate | Source | |---|---|---| | Stripe fee (EU consumer card) | 1.5% + β¬0.25 per charge | Stripe pricing; EUR settlement, no FX | | Attachment storage (R2) | ~β¬0.014/GB-month | $0.015, zero egress | | DB snapshots (S3) | ~β¬0.021/GB-month | $0.023 | | Box (whole cloud plane) | ~β¬35/month | Hetzner + fixed services | | Resident-process slot | ~β¬0.81/month | box Γ· 40-instance capacity |
Hibernation is live in production (the activator, #550 Part 4: running on the box against the real S3 bucket, verified by a hibernating canary instance), and spaces adopt it per-host as the rollout proceeds (routes.hibernate). A flagged space that goes idle is an S3 prefix, not a process β marginal cost while asleep is storage alone, and the slot rate applies only to the fraction of time it's awake. The estimates below model a flagged space; a not-yet-flagged space still carries the full resident slot rate (~β¬9.70/year at full box density), which trims its margin by that amount until its flip. One deliberate permanent exception: a space with a bot sidecar never sleeps (the sidecar's WebSocket holds it awake) β one more reason AI usage carries its own meter instead of hiding in a flat price.
Durability per tier β the replication ladder (decided 2026-07-14)
The fleet's S3 bill is ~100% Tier-1 requests, not data (#836), and the one request stream that scales with activity is litestream's change-driven WAL sync β worth pennies a year on a quiet space and up to ~β¬145/year on a worst-case space that writes every second around the clock. That cost profile is why durability is now a per-plan replication class on the activator's replica (routes.replication; mechanism #866, billing push #869):
| Tier | Class | Awake sync cadence | Hard-crash loss window | Request cost/yr (est.) | |---|---|---|---|---| | Business | stream | change-driven ~1s | seconds | ~β¬2β20 typical; ~β¬145 worst case | | Community & Friends | batched | at most every 5m | minutes | β€ ~β¬0.50 | | Free + Family | daily | at wake + every 24h | up to a day | pennies |
Three things the ladder deliberately does not change:
- Every graceful path flushes in full β idle sleep, deploy, restart, shutdown all checkpoint the space to S3 regardless of class. The class only bounds what a sudden box loss can take, and only while awake.
- Hibernation's parked copy is always exactly current β sleeping on a lower rung is not a weaker backup; the rung applies to awake windows only.
- Nothing about confidentiality β the replica is the same ciphertext the server already holds.
The honest member-facing framing (held in the changelog and any plan copy): backed up every time your space goes quiet, and at least nightly; a catastrophic server failure may cost the most recent hours on Free/Family, minutes on Community, seconds on Business. One caveat priced in above: a space with a bot sidecar never sleeps, so for those the "at least nightly" floor is the real day-to-day cadence on the daily rung.
One Business plan, not a "Business Plus" (decided 2026-07-14). The full resilience stack β streaming replication, the retention ladder behind point-in-time restore, room to tighten the crash-failover window β costs β¬2β20/year on realistic Business spaces against revenue that scales with the team (per-seat since 2026-07-22: β¬330/year at 30 people; the decision was taken against the flat β¬999β1,188/year and holds at per-seat scale). A resilience delta that small can't carry a second paid tier: splitting it would add a Stripe price pair, picker copy, and a matrix cell to explain, to sell something we can afford to include. So Business simply includes best-available durability, and the ladder stays three legible rungs priced by what they actually cost. If a segment ever demands contractual RPO/RTO, multi-region replicas, or compliance-grade restore drills, that's a custom/Enterprise conversation β negotiated, not a checkbox tier β and the books will show its costs separately when it exists.
The model
For a tier with gross annual revenue G across n charges/year:
net = G β (0.25 Γ n) β (0.015 Γ G) # Stripe fees out
cost = GB_stored Γ storage_rate Γ 12 # media, the only real dial
+ slot_rate Γ 12 Γ awake_fraction # compute while awake
+ repl_requests # by replication class (see Durability):
# daily/batched β β¬0; stream β β¬2β20
+ ~β¬0.10 # wakes, other requests, push (noise)
profit = net β cost
break_even_GB = net Γ· (storage_rate Γ 12) # where a space stops covering itselfMessage text is never material: a decade of busy family chat is ~50 MB (~β¬0.01/year). The only way a space outspends its price is stored media.
Estimates per tier (snapshot, 2026-07-27)
Usage profiles are typical-case estimates, not caps. Business is per-seat, so it gets two team sizes β the structure holds at both:
| Tier | Gross/yr | Net/yr | Profile (est.) | Cost/yr (est.) | Profit/yr (est.) | Margin | Break-even storage | |---|---|---|---|---|---|---|---| | Family β¬5.50/y | β¬5.50 | β¬5.17 | 10 members, 5 GB, mostly asleep | ~β¬1.00 | ~β¬4.15 | ~76% | ~31 GB | | Community β¬11 min | β¬11.00 | β¬10.59 | 40 members (first 100 included), 11 GB, awake ~20% | ~β¬5.50 | ~β¬5.10 | ~46% | ~40 GB | | Community β¬0.11/member | β¬55.00 | β¬53.93 | 500 members, 11 GB, awake ~50% | ~β¬12.00 | ~β¬42 | ~76% | ~320 GB | | Business β¬11/p/y | β¬330.00 | β¬324.80 | 30 people, 60 GB pooled, awake ~50% | ~β¬20.00 | ~β¬305 | ~92% | ~1.9 TB | | 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 |
Readings:
- Break-even storage is the number that matters. A Family space must hold ~31 GB of media forever before β¬5.50/year stops covering it. That makes #561's storage quotas easy to set generously: the shipped allowances (5 GB Family, 11 GB Community, 11 GB per seat Business) sit far below every tier's break-even, so no tier can structurally lose money while still feeling roomy in practice.
- Stripe's fixed fee punishes small monthly charges. Family pays ~6% of gross in fees on its single annual charge; a hypothetical β¬0.46/month Family would pay ~11Γ. This is why the whole ladder is annual only β at β¬0.11 a member, a monthly charge would be mostly Stripe fee (and a space is a years-scale commitment anyway).
- The fixed floor is small. The whole plane costs ~β¬420/year; roughly 80 Family spaces, or ~40 Community minimums, or one 40-person Business space cover it outright. Beyond that, margin is contribution toward resilience and the co-operative endgame (#550 Part 10).
- Business margin is deliberately not an infra story. At ~92β94% margin on realistic teams the price is buying priority support, SLAs, and features to come β not bytes. (Small teams run thinner β see Β§ Per-seat.) If that feels wrong when the books go public, that's the conversation the books exist to force.
What could invert these numbers
- AI/bot usage β excluded above by design; metered add-on or BYO key.
- Media hoarding past break-even β bounded by #561 quotas when they land.
- A space that never sleeps β bot-sidecar spaces; today that's a known subsidy, priced into the margins above.
- Rate changes β Stripe, R2/S3, or box pricing move; re-derive.
Re-deriving
Update the two snapshot tables (input rates + estimates) and the date stamps; the formulas don't change. This document publishes: the status site's Economics page (web/status/economics.{html,json}) is the public snapshot of these tables β update it in the same change and copy it to the box (docs/status.md Β§ Keeping the tier-economics page current; the contract test pins the arithmetic). Two numbers stay out of the public copy by design: the per-box instance cap and the box disk size (the status site's capacity privacy rule β band words, never cap values). Current prices live in the provisioner's price book (LCHAT_STRIPE_PRICES on the cloud service; see cloud-provisioner.md Β§ Billing); money truth lives in the Stripe dashboard; entitlement truth in the provisioner ledger. Related: #550 (architecture + public books), #561 (limits/meters), #562 (pricing decisions), #614 (memberβadmin subscriptions β a different product, same Stripe account).