Slices and scale
One line carries a wisp in any number of servers: it follows one group and keeps one cursor, whether the wisp is in 3 servers or 5,000. Most wisps never need more. Slices are for the wisp that one process can no longer keep up with.
When to use slices
Section titled “When to use slices”Split when one process cannot handle what its line hears: a wisp that reads every line of many busy servers, or one whose work per event is heavy. Each slice is its own line, usually its own process, hearing only the servers in that slice. One slice is the default, and costs nothing to keep.
Set the number when you make the wisp, or change it later:
PATCH /api/wisps/d2b6f4a8-3e1c-4b7d-9a05-6c8e0f2a4b19Authorization: Bearer <your token>Content-Type: application/json
{ "slices": 4 }From 1 to 64. A change counts at once: from then on, each server’s events go to its slice under
the new number. Lines already open stay open and keep their slice, and their ready still
names the old number. So open a line for each new slice, close any line whose slice is past the
new number, and since servers moved between slices, catch each slice up with reads on the line
(The line). Every line counts against the cap (below), so going down,
close the extra lines first.
Which slice a server is in
Section titled “Which slice a server is in”The first eight hex digits of the server’s id, read as a number, mod the number of slices. Work it out like this:
function sliceOf(server, slices) { return Number.parseInt(server.slice(0, 8), 16) % slices;}
sliceOf("5c3b1a2d-8e4f-4a6b-9c7d-0e1f2a3b4c55", 4); // 0x5c3b1a2d is 1547377197: slice 1sliceOf("5c3b1a2d-8e4f-4a6b-9c7d-0e1f2a3b4c55", 8); // slice 5Each line names its slice in its hello:
{"t":"hello","v":2,"a":"eyJhbGciOiJIUzI1NiJ9.eyJuYW1laWQiOiJkMmI2ZjRhOCIsIndpc3AiOiIxIn0.c2ln","f":1,"slice":3}Left out, it is slice 0. A slice that is not one of your wisp’s (3 when it has 2) is closed with
1011. Everything about a server, its command and act events and its server grants
included, arrives on that server’s slice. Make the calls about a server from the same line, so
your own order of calls for a channel holds.
The budgets are your wisp’s, not a slice’s: serverCalls, channelLines and edits are shared
by all its lines, while each line has its own calls (Budgets and limits).
Two lines a slice
Section titled “Two lines a slice”A wisp may hold two lines for each slice: at most twice as many lines as it has slices, counted
across the whole wisp. One past that is closed with 4429, retry=30. The second line is for
hand-overs: while both are open, both hear the slice’s group, and at the new one’s ready the
old one says moved and goes.
Deploying without a gap
Section titled “Deploying without a gap”Woosh deploys itself without anyone going offline, and your wisp can too:
- Start the new version beside the old one.
- For each slice, the new process opens a line with the cursor the old one saved.
- At each new line’s
ready, the old process sendsmovedon its line for that slice, finishes the answers it owes, and lets go. - Once every slice has moved, stop the old process.
Nothing is missed and nothing is answered twice: Woosh never lets a run take two answers. Decide
which process answers during the overlap (the new one, from its ready), so the two do not race
for each run.
What scale costs
Section titled “What scale costs”| Shape | What it costs your wisp |
|---|---|
| A wisp in 5,000 servers | one group, one cursor and one line per slice |
| A busy server’s lines | one event each |
| A command or a press | one event in, one answer out |
| A tally pressed 5,000 times | nothing: Woosh counts it |
| A countdown, pages, an animation | nothing after the card is sent |
Your wisp pays its own distance twice for every command: once hearing it, once answering. Run it close to Woosh, and answer from memory rather than a slow database call where you can.
© 2026 Woosh AS. All rights reserved.