Skip to content

Scale

Federated, not infinite.

Capacity grows with each federation. The limits below are the architecture as it is, published continuously. No claim of infinity.

Who holds each federation's keys is on who holds what, computed from the live state.

Capacity now

Each new federation raises the ceiling by the same step. orangecheck provisions them today; public operator sign-up reopens as the program matures.

Live federations13 in all · 2 not yet live
Ceiling, per second100 to 500100 to 500 per federation, times live federations
Receipts, all time0Signed paid-event receipts recorded across the network
Per second, last 5 minutes0.000 events · under 0.01% of one project's cap
Per second, last hour0.000 events
Cap per project1.0k a secondSustained, across every instance

Agents and people

Events fired by an agent are counted apart. An app that wants to gate on real human activity can ask for the human event count; this is the ratio across the network.

No events yet, so there is no ratio to show.

The limit at each layer

Each row is measured or bounded upstream. The pipeline runs at the speed of its slowest step. While the payout rail is in bring-up that is the key-value store; once federations carry settlement it is federation throughput, which more federations raise.

  • Vercel Pro concurrency6.0k to 8.0k a secondfunction concurrency limit (1000) × p99 ≈ 120ms
  • Upstash Pro KV600 to 770 a secondsingle-region Redis through HTTP REST · ~13 commands per event
  • Single Fedimint federation (v0.11)100 to 500 a secondupstream consensus throughput
  • Lightning gateway HTLCs10 to 50 a secondin-flight HTLC limit · per gateway
  • Nostr relay (strfry)10.0k to 50.0k a secondnot the bottleneck
  • OpenTimestamps calendarBatched, no practical limitbatched · effectively unlimited

One app can't crowd out the rest

Each project is capped at 1.0k events a second, sustained.

Above it, requests get a 429 with a Retry-After header, which the SDK's withRateLimitRetry() honors. Firing from many IPs or many servers does not get around it, and other apps are unaffected.

Fake accounts get expensive as a side effect

One identity across every app. Sats earned across many apps over time make a signal that is costly to fake and easy to check. Every app that uses the sign-in gets it.

Four signals, all signed

Depthcross_integrator_lifetime_sats
Sats earned across every app, all time.
Breadthcross_integrator_distinct_count
How many apps have paid for this identity.
Durationcross_integrator_oldest_event_at
When it first did anything. Nobody can earn sats in the past.
Habitcross_integrator_active_days
Distinct days with at least one event. One burst looks nothing like daily use.
Checking it is one call
import { oc } from '@orangecheck/me-client';

const r = await oc.identity.verifyActivityAttestation(bundle);
if (!r.ok) return res.status(401).send(r.reason);

const a = r.attestation!;
if (a.lifetime_sats < 10_000) return reject('low signal');
if (a.distinct_integrator_count < 3) return reject('low breadth');
if (a.active_days < 30) return reject('one-shot history');
// passed: depth, breadth, duration, habit

Five checks underneath: the bundle's shape, its content address, the key by id, the Ed25519 signature, and freshness. It ships in @orangecheck/me-client and runs on Node 20 and up, at the edge, or in a browser.

Where these numbers come from

Each ceiling is a measured or upstream-bounded cap. Under them, the event path reads the store in parallel, writes accruals without waiting, caches anchored receipts at the edge, and limits each project across every instance.