Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Where to run it

WasmKeep is a long-lived process that keeps actors, leases, WebSockets and timers in memory, writes many small transactions to local SQLite files, holds three open files per resident actor, and reserves a large virtual address space for its instance pool. That shapes where it runs well.

OptionProsConsUse it for
Dedicated server (bare metal)Best price per performance; local NVMe makes fsync fast and predictable; no noisy neighboursYou handle hardware failure and OS upkeep; slower to resizeProduction on a budget, clusters of three or more, benchmarks you publish
Virtual machineEasy to create, resize and snapshot; private networks built inNoisy neighbours (our shared-VM benchmark runs vary by up to ±30%); network-attached disks add fsync latency: prefer instance-local NVMe or fast volumesThe default, from one VPS to a three-node cluster
Container (Docker, Compose, Kubernetes)Reproducible packaging and rollout; a distroless image and a three-node Compose example in deploy/One more layer; see the rules belowTeams that standardise on containers
Serverless containers (Cloud Run, Fargate, Lambda)No servers to manageScale-to-zero kills resident actors and drops leases; instances are ephemeral, with no stable node identity; CPU may be throttled between requests; WebSockets and alarms fight the modelNot recommended

A container is packaging, not isolation: actors are already sandboxed by WebAssembly. Isolating tenants who may be hostile needs a stronger tier (a process or microVM per tenant), which WasmKeep does not have yet (security model).

Rules that apply everywhere

  • A real disk for --data-dir: local NVMe or a fast volume; never a container’s overlay filesystem or a network file system (SQLite relies on local locking and fsync).
  • Open files: give the process a high limit (LimitNOFILE=65536 with systemd, --ulimit nofile=65536 with Docker). WasmKeep raises its soft limit to the hard one and caps resident actors to fit (monitoring).
  • Virtual memory: no LimitAS or ulimit -v; do not use MemoryDenyWriteExecute (Wasmtime maps compiled code executable). A memory limit on resident memory (cgroups) is fine.
  • Transparent huge pages need nothing: WasmKeep turns them off for its own process on Linux, which halves memory per actor where the kernel sets them to always (monitoring). Leave the system setting alone for other software on the machine.
  • A stable node identity in a cluster: one --node-id per machine (a StatefulSet on Kubernetes).
  • A private network between nodes, in the same region as the bucket; only the load balancer reaches them (front door).
  • Local disk durability: on one node, the local disk is the database, so back it up (one server); in a cluster the bucket is the source of truth and a node’s disk can be lost.

What is measured so far

The numbers in Benchmarks come from one workstation and a shared cloud VM: good for comparing commits, languages and runtimes, not for capacity claims. A three-node soak ran against R2 and OVHcloud Object Storage, from a desktop and from three VPS next to the bucket (results): nothing lost over 36 kills in four runs. Put the nodes in the same region as the bucket: a durable write waits for one PUT (54 ms next to it, 587 ms from a desktop to R2), and a failover for a restore of many GETs. The suite has not yet run on dedicated hardware.