Every SpawnWeaver limit, its value, the error you get when you hit it, and the fix. Nothing here is a silent cap — every limit answers with a named error code.

The table

Limit Value Error raised What to do
Message size (any realtime message) 16 KB payload-too-large Shrink the payload; move big data to storage
Message rate per connection 20/s sustained, burst 40 rate-limited (retryable) Back off briefly and retry; batch sends
State updates per client 10/s sustained, burst 20 rate-limited (retryable) Send at ≤10/s; SpawnSync's default send_rate of 8 is safe
Entities per room 50 state-limit-exceeded Delete finished entities; pool projectiles into events
State per entity 4 KB state-too-large Keep entities small (transform + a few fields)
Room state size 16 KB state-too-large Trim room state; remove keys with null patches
Storage value size 64 KB per key storage-value-too-large (HTTP 413) Split or compress the value
Storage keys per player 100 storage-quota-exceeded (HTTP 409) Delete unused keys; consolidate into fewer dictionaries
Storage key length 128 chars, non-empty storage-invalid-key (HTTP 400) Use short, stable key names
Matchmaking size 2–64 players invalid-payload Pick a size in range
Matchmaking wait 30 s per ticket match-timeout (retryable) Offer "search again"; see Matchmaking
Connections per project generous per-tier cap Handshake rejected with HTTP 429 Retry with backoff; contact us if your launch needs more
Disconnect grace 60 s after expiry: player_left with reason disconnected; entities removed (owner-left) Design reconnect UX around ~1 minute
Empty-room TTL 60 s room expires: joiners get room-not-found; in-grace members get room_left("expired") Rejoin/recreate; don't park empty rooms
Room metadata no dedicated cap bounded by the 16 KB message limit Keep metadata to a handful of small strings
Auth endpoint rate (sign-in/up) per-IP throttle HTTP 429 Wait a minute; don't loop sign-in attempts

How limit errors behave

  • Retryable errors (rate-limited, match-timeout, plus the SDK-local timeout and disconnected) carry retryable: true on the SWError — the same call may succeed after a short backoff.
  • Hard errors (payload-too-large, state-too-large, state-limit-exceeded, storage quota errors) are not retryable: the same call will fail again until you change what you send.
  • Rate and size rejections still echo your request id, so an awaited call resolves with the error rather than timing out:
var result := await SpawnWeaver.set_entity("boss", huge_dictionary)
if not result.ok and result.error.code == "state-too-large":
    push_warning("Entity too big: %s" % result.error.message)
  • send_event() has no await; its limit errors arrive on the error signal instead.

Budgeting within the rate limits

The 20 messages/s connection budget covers everything you send: events, state updates, storage calls, and the SDK's heartbeat (one ping every 15 s — negligible). A practical split for an action game:

Traffic Budget
SpawnSync transform updates 8/s (the default send_rate)
Gameplay events ≤ 5/s sustained
Manual state patches (host, room state) ≤ 2/s
Storage saves occasional (on change, not on a timer)

Bursts up to 40 messages are absorbed by the token bucket, so a spiky moment (three events in one frame) is fine — sustained overrun is what triggers rate-limited.

Timing windows at a glance

Window Default Meaning
Disconnect grace 60 s A dropped player's seat and entities are kept; reconnect resumes them
Empty-room TTL 60 s A room with no connected members is removed
Matchmaking timeout 30 s A ticket that finds no match resolves with match-timeout
SDK request timeout 10 s An awaited call with no reply fails with local timeout (retryable)
SDK matchmaking guard 120 s Client-side ceiling on find_match() awaits
Heartbeat 15 s interval Connection declared dead after ~45 s of silence; auto-reconnect kicks in
Reconnect backoff 0.5 s → 30 s cap Exponential with jitter, forever until stop()

Need a higher limit?

The values above are tuned so a normal game never meets them; they exist to keep one project's bug from degrading everyone else's service. If your game legitimately needs more — a big playtest, a launch spike, bigger rooms — contact us and we'll raise the right knob for your project.