Skip to content
PartyKit Docs
GitHub Discord Twitter

Rate limiting messages

PartyKit is very fast, and can process hundreds of messages per second from a single WebSocket connection, and thousands per second per room.

However, this is not always a desired behavior! For example, a connected client may misbehave (accidentally or on purpose), and spam the room with messages on a loop. If you’re a security expert, you may be thinking of spambots. If you’re a React developer, you may be thinking of a runaway useEffect with a missing memo variable.

You can prevent scenarios like these by applying rate limiting to your connections.

Rate limiting messages from a connection

In order to keep track of how frequently a specific connection sends messages, you can use the connection.state variable to track most recent messages:

onMessage(message: string, sender: Party.Connection<{ lastMessageTime?: number }>) {

  const now = Date.now();
  const prev = sender.state?.lastMessageTime;

  if (prev && now < (prev + 1000)) {
    // if previous message was less than 1 second ago, remove them from the room!
    sender.close();
  } else {
    // otherwise keep track of the previous time
    sender.setState({ lastMessageTime: now });
  }
}

The above example is rather unfriendly. You are welcome to implement a rate-limiting approach that makes sense for you.

Our live reaction counter example contains a simple, incremental back-off rate limiter, which sends the client warnings before terminating the connection.

You can use it as follows:

onMessage(message: string, sender: Party.Connection) {
  // rate limit incoming messages to every 100ms with an incremental back-off
  rateLimit(sender, 100, () => {
    // do things
  });
}

Fine-grained rate limiting

To implement more sophisticated rate-limiting algorithms, you can implement your own, or reach for an open source library like the rate-limiter-flexible package on npm.