Skip to content

Multi-cluster

If you run your bot across multiple processes or machines, set clusterId on each one so Dicolytics can separate and aggregate data correctly.

Note

If your bot runs in a single process (even with multiple shards via ShardingManager), you do not need to set clusterId. The SDK automatically includes shardId in every event.

Setting Up clusterId

When running multiple clusters across separate processes or machines, set clusterId on each instance so the dashboard can group data correctly.

ts
const analytics = createDicolytics(client, {
  apiKey: process.env.DICOLYTICS_KEY!,
  clusterId: 0,
});
ts
const analytics = createDicolytics(client, {
  apiKey: process.env.DICOLYTICS_KEY!,
  clusterId: 1,
});
python
analytics = create_dicolytics(bot, api_key=os.environ["DICOLYTICS_KEY"], cluster_id=0)
python
analytics = create_dicolytics(bot, api_key=os.environ["DICOLYTICS_KEY"], cluster_id=1)

The clusterId must be an integer between 0 and 32767. It is stamped into every event's data.clusterId field, alongside the auto-detected shardId.

Using Environment Variables

In most multi-cluster setups, the cluster ID comes from the process environment:

ts
const analytics = createDicolytics(client, {
  apiKey: process.env.DICOLYTICS_KEY!,
  clusterId: Number(process.env.CLUSTER_ID),
});
python
analytics = create_dicolytics(bot,
    api_key=os.environ["DICOLYTICS_KEY"],
    cluster_id=int(os.environ["CLUSTER_ID"]),
)

INFO

If clusterId is not a valid integer in the range 0--32767, it is silently ignored (logged with debug: true). The SDK does not throw.

How Data Is Separated

  • Events (interactions, actions, gateway events, custom): aggregated across all clusters by project_id. Dashboard reports always show combined totals. Each event record retains its shardId and clusterId fields, so you can filter by cluster in Explore.
  • Snapshots (heartbeat, guild_snapshot): separated by (project_id, cluster_id, shard_id). Each cluster reports its own guildCount, wsPingMs, memoryMb, and other metrics independently.

Status Page with Clusters

When clusterId is set, the Status page organizes the shard grid into a cluster > shard hierarchy. Without clusterId, all shards appear in a flat list.

One SDK Instance Per Process

Note

Create exactly one createDicolytics call per discord.js Client instance. The SDK throws if you try to attach twice to the same client without calling shutdown() first.

Each shard process (created by ShardingManager) gets its own Client instance, so each process creates its own SDK instance. The SDK automatically detects the shardId from client.shard.ids.

ts
// bot.ts -- executed once per shard process
import { Client, GatewayIntentBits } from 'discord.js';
import { createDicolytics } from '@dicolytics/discord.js';

const client = new Client({
  intents: [GatewayIntentBits.Guilds],
});

const analytics = createDicolytics(client, {
  apiKey: process.env.DICOLYTICS_KEY!,
  clusterId: Number(process.env.CLUSTER_ID ?? 0),
});

client.login(process.env.DISCORD_TOKEN);
python
# bot.py -- executed once per shard process
import os
import discord
from dicolytics import create_dicolytics

bot = discord.Bot()

analytics = create_dicolytics(bot,
    api_key=os.environ["DICOLYTICS_KEY"],
    cluster_id=int(os.environ.get("CLUSTER_ID", 0)),
)

bot.run(os.environ["DISCORD_TOKEN"])

Filtering by Cluster in Explore

Use the Explore tool to filter data by cluster:

clusterId = 0
event_type = interaction_slash

This lets you compare command usage, error rates, or latency across clusters.

Dicolytics — Discord bot analytics