Limits
Everything on this page is a number or a rule you can plan around. Where a value is a network parameter or can be changed by an owner, the call that returns the live figure is named.
Sessions
Section titled “Sessions”| Limit | Value | Where it comes from |
|---|---|---|
| Credential lifetime | 4 hours | sessionLifetime, a network parameter |
| Concurrent sessions per Orbit | one per slot, 1–5 | the Orbit’s slots, chosen at purchase; capped by maxSessionsPerSub, a network parameter |
| Sources per session | 1 | protocol constant |
| Checks over the source limit before a session ends | 3 in a row | protocol constant |
| Closing silent sessions | checked every 2 min, after 5 min without a checkpoint | Control Plane settings |
SessionCredentials.expires_at is the real deadline. When it passes, the node removes the account and the tunnel stops. A client keeps the session going with RenewSession before then: each renewal moves the deadline forward by another credential lifetime. See renewing a session.
An Orbit holds as many sessions as it has slots, counted across the whole federation, not per operator: before admitting another session, each Control Plane adds what its peers report holding for the same Orbit. An Orbit has 1 to 5 slots, chosen when it is bought, each costing one price.
In the wallet tier the Control Plane does the counting. An anonymous proof does not say which Orbit it came from, so there permissions hold the same rule: one per slot.
One source per session means one device. A router sharing its connection with several machines is still one source, because the router is what goes out. Three readings in a row over the limit end the session, and a single clean reading resets the count. Sources are counted, never logged: the node asks Xray for a number and keeps its access log off.
Anonymous access
Section titled “Anonymous access”| Limit | Default | Network parameter |
|---|---|---|
| Session openings per epoch, per Control Plane | 25 | accessQuotaPerEpoch |
| Node time one slot may spend | 2 hours | accessBudgetPerSlot, in seconds |
| Permissions per identity per window | 1 | permissionsPerWindow |
These are the network’s numbers, not an operator’s. They are set through ProtocolGovernor, within bounds, and every Control Plane reads them from SingulaProtocol.param(name), with the name as ASCII in a bytes32, re-reads them every ten minutes, and uses the default while the directory sets none. A new quota or budget applies as soon as a Control Plane has read it. A new permission count applies from the first window whose issuer key is published after the change, because each window keeps the count committed with its key.
A slot is spent when a session opens and then metered in time served, so a short session costs little. Quota times budget is what one Orbit can use at one Control Plane in an epoch.
Permissions are the other half: one per identity per window, and an Orbit has one identity per slot. Each permission is issued once across the network and holds one session at a time anywhere in the network. The Control Plane running the session keeps its permission held and tells every peer; when the session ends the reports stop, and within a minute the permission is free everywhere. Every anonymous session is bound by both: the quota counts openings at each Control Plane, the permission counts sessions held at once.
The count is part of the issuer key’s on-chain commitment, so an issuer cannot describe one key as worth different numbers to different clients. Read it with VoucherKeyRegistry.getEpochKey(issuerStarId, epoch), which returns (keyHash, denominationGB, setAt, issuerActive); the count is the second value.
What counts as work
Section titled “What counts as work”Time is what is paid for, not bytes. Three rules decide whether time counts at all:
- Time is held back until 64 KiB has moved since the last credited checkpoint, and then counts in full, quiet stretches included. An idle tunnel earns nothing.
- Time is held back for at most 10 minutes. A checkpoint that comes later than that after the last credited one moves the cursor on without credit, and what was held back is dropped. Sending checkpoints more often does not help; Wanderer sends one every 30 seconds either way.
- A checkpoint claiming more than 10 Gbps for its interval is refused outright.
All three are network parameters, read the same way as the limits above: minCheckpointBytes, maxCheckpointGap in seconds, and maxBytesPerSecPerSession.
Orbits
Section titled “Orbits”An Orbit is a subscription, held as a SubscriptionNFT token.
| Limit | Value |
|---|---|
| Price | 10 sUSDC — SubscriptionNFT.priceUSDC() |
| Duration | 30 days from activation |
| Unactivated tokens per address | 10 |
| Transferable | before activation only |
While the protocol is paused, service time stands still and the end of a subscription moves later by the pause’s length, so downtime does not eat into paid time.
An Orbit is not extended. A holder who activates another while one is running gets it queued: it starts when the current one ends. A returning subscriber can register the same anonymous commitment as before, since it stays reserved to their address.
Payouts
Section titled “Payouts”A node earns a fixed rate, nodeRate(), for every second credited, however many nodes are working. A Control Plane earns a fixed seatPay() for every epoch of its seat.
A fast node and a slow node earn the same for the same time: the network measures availability, not throughput.
The network credits no more seconds than paid time has run: if an epoch is credited more, its rate falls by the same factor for every node.
Unclaimed node rewards have no deadline and count as the pool’s debt. A CP seat’s pay must be claimed within 7 epochs after the seat’s term ends.
What the network does not do
Section titled “What the network does not do”It does not carry your traffic through a Control Plane. Sessions are issued there; the bytes go straight to the node.
It does not bill by traffic. You pay for time. Byte counts only decide whether an interval counts at all, against the floor and the cap above, and nothing looks at the traffic itself.
It does not hide you from the first node. Whichever server you connect to sees the address you connect from, at any number of hops.
It does not build routes for you. A Control Plane hands out one node. Chaining two is the client’s job, and so is making sure they belong to different operators: ListNodes returns each candidate’s on-chain identity, and the client looks up the owners itself. Two hops through one operator protect like one. Wanderer keeps its hops on different operators by default.
It does not filter content, apart from one list. DomainBlocklist is on chain, where anyone can read it, and nodes send matching traffic nowhere. Nothing else is inspected.
It does not recover accounts. There are none. A lost wallet is a lost Orbit.
It does not run a help desk. If no Control Plane answers, a client moves on to the next one in the registry.
It does not check a node’s way out. A node reports how it reaches the internet — warp, direct or custom — and that report is its own.
Alpha status
Section titled “Alpha status”Arbitrum Sepolia, chain id 421614, with a test token. Contracts have been redeployed during the alpha and will be again, so a client should read every address from SingulaProtocol rather than build in its own list.
The CP role is granted by the founder for now; later it will come with a stake, see becoming a Control Plane.
Orbits are bought and Stars are paid in USDC for now; ECHO joins both at a later stage, see economics.
