Gateway and sharding
Shard is one websocket connection; ShardManager coordinates the shards in a process. Below roughly 2,500 guilds you can rely on defaults.
Shard is one websocket connection; ShardManager coordinates the shards in a process. Below roughly 2,500 guilds you can rely on defaults.
Startup sequence
connect()reads the recommended shard count and session limits from Discord.- With
maxShards: 'auto'that count is used;shardConcurrency: 'auto'uses Discord'smax_concurrency. - Each shard opens its socket, gets
HELLO, sendsIDENTIFY, then receivesREADYand a burst ofGUILD_CREATE. - After
guildCreateTimeout, the shard firesshardReady. When all shards are ready, the client emitsready.
Sharding modes
Single process, auto:
new Client(token, { maxShards: 'auto', shardConcurrency: 'auto' });Multi-process, contiguous ranges (total must match across processes, since Discord routes by guild_id % total):
new Client(token, { maxShards: 16, firstShardID: 0, lastShardID: 7 }); // process A
new Client(token, { maxShards: 16, firstShardID: 8, lastShardID: 15 }); // process BExplicit IDs:
new Client(token, { maxShards: 16, shards: [0, 2, 4, 6, 8, 10, 12, 14] });Connection concurrency
Shards sharing id % max_concurrency are in the same identify bucket. Athena waits for a free bucket, then enforces a 5 second cooldown before the next identify in that bucket (skipped for resumes). max_concurrency comes from Discord and rises with scale; very large bots request elevated access.
Heartbeats, reconnect, resume
Athena heartbeats at Discord's interval and tears the socket down if an ACK is missed (zombie connection). On disconnect, if a session ID is held it issues RESUME to replay missed events; if the session expired or maxResumeAttempts is exceeded it re-identifies. Reconnect delay follows reconnectDelay(lastDelay, attempts).
Member chunking
For many members on one guild, Discord requires the gateway, not REST:
const members = await shard.requestGuildMembers({ guild_id: guildID, query: '', limit: 0 });This now waits the configured request timeout for the chunks (rather than returning early). getAllUsers: true chunks every guild at startup and significantly delays ready on large bots.
Presence and voice
shard.setPresence(PresenceUpdateStatus.DoNotDisturb, [{ name: 'with code', type: ActivityType.Playing }]);
shard.sendWS(GatewayOpcodes.VoiceStateUpdate, { guild_id, channel_id, self_mute: false, self_deaf: false });Athena does not bundle a voice-connection (audio) implementation; pair it with a dedicated voice library if you need audio.
Useful shard surface
shard.status; // 'disconnected' | 'connecting' | 'handshaking' | 'ready' | ...
shard.latency; // ms
shard.sessionID;
shard.connect(); shard.disconnect({ reconnect: true });
shard.requestGuildMembers(options);Tuning
- Default to
maxShards: 'auto'. - Keep
compresson (zlib-stream cuts gateway bandwidth a lot). - Use
disableEventsfor noisy events you ignore. - Stagger reconnects with a randomised
reconnectDelayto avoid thundering herds after an outage.
For the cluster + cache picture at the very top end, see Scaling to millions.