Skip to Content
Server SDKMetadata

Server: Metadata

Mesh supports two types of metadata:

  • Connection metadata — data attached to individual WebSocket connections
  • Room metadata — data associated with named rooms

All metadata is stored in Redis and accessible across all server instances.

Connection metadata

Useful for identifying users, storing roles, or tracking per-connection session info.

Set metadata

await server.connectionManager.setMetadata(connection, { userId: "user123", role: "admin", lastActive: Date.now(), });

Get metadata

One connection

const metadata = await server.connectionManager.getMetadata("conn123");

All connections

Returns an array of { [connectionId]: metadata } objects:

const all = await server.connectionManager.getAllMetadata(); // [ // { "conn1": { userId: "user123", ... } }, // { "conn2": { userId: "user456", ... } }, // ... // ]

Filtered connections

You can filter connections based on their metadata using an optional filter function:

const filtered = await server.connectionManager.getAllMetadata( (connectionId, metadata) => metadata.userId > 100 && metadata.userId < 300 ); // [ // { "conn123": { userId: 123, ... } }, // { "conn234": { userId: 234, ... } }, // ]

This reduces boilerplate when you need to select specific connections based on metadata criteria.

All connections in a room

Also returns an array of { [connectionId]: metadata } objects:

const members = await server.connectionManager.getAllMetadataForRoom("lobby");

Both methods return an array of objects rather than a single merged object.

Update metadata

Call setMetadata(...) again to completely replace the previous value:

const existing = await server.connectionManager.getMetadata("conn123"); await server.connectionManager.setMetadata("conn123", { ...existing, lastActive: Date.now(), });

Cleanup

Connection metadata is automatically removed when the connection disconnects.

Room metadata

Useful for storing room-level settings, topic info, or ownership metadata.

Set metadata

await server.roomManager.setMetadata("lobby", { topic: "General", createdBy: "user123", maxUsers: 10, });

This replaces any existing metadata for the room.

Update metadata (partial)

await server.roomManager.updateMetadata("lobby", { topic: "New Topic", });

This merges the new fields into the existing record.

Get metadata

One room

const metadata = await server.roomManager.getMetadata("lobby");

All rooms

Returns an object mapping room names to metadata:

const all = await server.roomManager.getAllMetadata(); // { // "lobby": { topic: "General", ... }, // "dev": { topic: "Dev Chat", ... } // }

Filtered rooms

You can filter rooms based on their metadata using an optional filter function:

const publicRooms = await server.roomManager.getAllMetadata( (roomName, metadata) => metadata.type === "public" ); // { // "lobby": { type: "public", topic: "General", ... }, // "help": { type: "public", topic: "Support", ... } // }

This makes it easy to select specific rooms based on metadata criteria.

Delete metadata

await server.roomManager.setMetadata("lobby", null);

Room metadata is also removed automatically if you call server.clearRoom(...).

Exposing metadata to clients

You don’t need to define your own commands for basic metadata reads — Mesh provides built-in support.

Connection metadata

// Client const metadata = await client.getConnectionMetadata("conn123");

The client can request their own metadata by omitting the connection ID:

// Client const metadata = await client.getConnectionMetadata();

Room metadata

// Client const metadata = await client.getRoomMetadata("lobby");

Best practices

  • Keep metadata small — avoid bloated objects, especially with many connections
  • Don’t store sensitive data — metadata may be exposed to clients if not filtered
  • Use updateMetadata for partial writes — safer and more efficient
  • Use consistent ID patterns — e.g. "lobby", "dev", "user:123"
Last updated on
© 2025