Documentation Index
Fetch the complete documentation index at: https://mintlify.com/disgoorg/disgo/llms.txt
Use this file to discover all available pages before exploring further.
The sharding package manages multiple gateway connections for bots in many guilds. Discord requires sharding for bots in 2,500+ guilds.
Overview
Sharding distributes guilds across multiple gateway connections, each identified by a shard ID. The shard manager handles:
- Opening and closing shards
- Distributing guilds to shards using Discord’s formula
- Rate limiting IDENTIFY requests
- Automatic re-sharding when required
- Resuming shards with saved session state
Core types
ShardManager
Manages multiple gateway connections.
type ShardManager interface {
Open(ctx context.Context)
Close(ctx context.Context)
OpenShard(ctx context.Context, shardID int) error
ResumeShard(ctx context.Context, shardID int, state ShardState) error
CloseShard(ctx context.Context, shardID int)
ShardByGuildID(guildID snowflake.ID) gateway.Gateway
Shard(shardID int) gateway.Gateway
Shards() iter.Seq[gateway.Gateway]
}
Methods
Opens all configured shards concurrently
Closes all shards concurrently
Opens a specific shard by ID
ResumeShard(ctx, shardID, state)
Resumes a specific shard with saved session state
Closes a specific shard by ID
Returns the shard that manages the specified guild
Returns the gateway for the specified shard ID
Shards()
iter.Seq[gateway.Gateway]
Returns an iterator over all active shards
ShardState
Session state for resuming a shard.
type ShardState struct {
SessionID string
Sequence int
ResumeURL string
}
The session ID from the gateway READY event
The last sequence number received from the gateway
The resume URL from the gateway READY event
Creating a shard manager
New
Creates a new shard manager.
func New(
token string,
eventHandlerFunc gateway.EventHandlerFunc,
opts ...ConfigOpt,
) ShardManager
The function to handle gateway events from all shards
Configuration options
WithLogger
Sets the logger for the shard manager.
func WithLogger(logger *slog.Logger) ConfigOpt
WithShardIDs
Specifies which shard IDs to manage.
func WithShardIDs(shardIDs ...int) ConfigOpt
The shard IDs to manage (e.g., 0, 1, 2 for managing shards 0-2)
Note: Use this for stateless sharding or when managing a subset of shards.
WithShardIDsWithStates
Specifies shard IDs with session states for resuming.
func WithShardIDsWithStates(shards map[int]ShardState) ConfigOpt
Map of shard ID to session state for resuming
WithShardCount
Sets the total number of shards.
func WithShardCount(shardCount int) ConfigOpt
Total number of shards. Leave at 0 to let Discord determine the count
WithShardSplitCount
Sets how many shards a shard should split into when auto-scaling.
func WithShardSplitCount(shardSplitCount int) ConfigOpt
Number of new shards to create from one shard. Default is 2
WithAutoScaling
Enables automatic re-sharding when Discord requires it.
func WithAutoScaling(autoScaling bool) ConfigOpt
Whether to automatically re-shard when required. Default is false
Note: When enabled and Discord sends a “sharding required” close code, the manager automatically splits the shard according to ShardSplitCount.
WithGatewayCreateFunc
Sets a custom gateway creation function.
func WithGatewayCreateFunc(gatewayCreateFunc gateway.CreateFunc) ConfigOpt
WithGatewayConfigOpts
Applies configuration options to all created gateways.
func WithGatewayConfigOpts(opts ...gateway.ConfigOpt) ConfigOpt
Gateway configuration options applied to all shards
WithIdentifyRateLimiter
Sets a custom rate limiter for IDENTIFY requests.
func WithIdentifyRateLimiter(rateLimiter gateway.IdentifyRateLimiter) ConfigOpt
WithIdentifyRateLimiterConfigOpt
Configures the default identify rate limiter.
func WithIdentifyRateLimiterConfigOpt(opts ...gateway.IdentifyRateLimiterConfigOpt) ConfigOpt
WithCloseHandler
Sets a handler called when a shard closes.
func WithCloseHandler(closeHandler gateway.CloseHandlerFunc) ConfigOpt
Function called when a shard closes and cannot reconnect
Note: Not called when auto-scaling triggers a re-shard.
Utility functions
ShardIDByGuild
Calculates which shard manages a specific guild.
func ShardIDByGuild(guildID snowflake.ID, shardCount int) int
The total number of shards
Returns: The shard ID that should manage this guild.
Formula: (guildID >> 22) % shardCount
Usage examples
Basic sharding
package main
import (
"context"
"github.com/disgoorg/disgo/sharding"
"github.com/disgoorg/disgo/gateway"
)
func main() {
// Create shard manager
manager := sharding.New(
token,
func(event gateway.EventData) {
// Handle events from all shards
},
sharding.WithShardCount(4), // 4 shards
sharding.WithShardIDs(0, 1, 2, 3), // Manage all 4
)
// Open all shards
manager.Open(context.Background())
defer manager.Close(context.Background())
// Get shard for a specific guild
shard := manager.ShardByGuildID(guildID)
latency := shard.Latency()
}
Auto-scaling
manager := sharding.New(
token,
eventHandler,
sharding.WithAutoScaling(true),
sharding.WithShardSplitCount(2), // Split into 2 when needed
sharding.WithShardCount(2), // Start with 2 shards
)
// When Discord requires more shards:
// - Shard 0 will automatically split into shards 0 and 2
// - Shard 1 will automatically split into shards 1 and 3
// - New total: 4 shards
Resuming shards
// Save shard states when shutting down
states := make(map[int]sharding.ShardState)
for shard := range manager.Shards() {
states[shard.ShardID()] = sharding.ShardState{
SessionID: shard.SessionID(),
Sequence: shard.Sequence(),
ResumeURL: shard.ResumeURL(),
}
}
// Save states to database/file
// Resume with saved states
manager := sharding.New(
token,
eventHandler,
sharding.WithShardIDsWithStates(states),
sharding.WithShardCount(len(states)),
)
manager.Open(context.Background())
Stateless sharding
For distributed setups where different processes handle different shards:
// Process 1: Handles shards 0-1
manager1 := sharding.New(
token,
eventHandler,
sharding.WithShardIDs(0, 1),
sharding.WithShardCount(4), // Total across all processes
)
// Process 2: Handles shards 2-3
manager2 := sharding.New(
token,
eventHandler,
sharding.WithShardIDs(2, 3),
sharding.WithShardCount(4),
)
Custom gateway configuration
manager := sharding.New(
token,
eventHandler,
sharding.WithGatewayConfigOpts(
gateway.WithCompress(true),
gateway.WithIntents(
gateway.IntentGuilds,
gateway.IntentGuildMessages,
),
gateway.WithPresenceOpts(
gateway.WithWatchingActivity("the shards"),
gateway.WithOnlineStatus(discord.OnlineStatusDND),
),
),
)
Monitoring shards
// Iterate over all shards
for shard := range manager.Shards() {
fmt.Printf("Shard %d: Latency=%v, Status=%s\n",
shard.ShardID(),
shard.Latency(),
shard.Status(),
)
}
// Get specific shard
if shard := manager.Shard(0); shard != nil {
latency := shard.Latency()
}
// Find shard for a guild
shard := manager.ShardByGuildID(guildID)
Close handler
manager := sharding.New(
token,
eventHandler,
sharding.WithCloseHandler(func(
shard gateway.Gateway,
err error,
reconnect bool,
) {
log.Printf("Shard %d closed: %v (reconnect=%v)",
shard.ShardID(),
err,
reconnect,
)
// Save shard state for resuming
if reconnect {
saveShardState(sharding.ShardState{
SessionID: shard.SessionID(),
Sequence: shard.Sequence(),
ResumeURL: shard.ResumeURL(),
})
}
}),
)
Best practices
- Start with auto-determined shard count: Let Discord determine the optimal shard count initially
- Enable auto-scaling: For large bots that may grow, enable auto-scaling to handle re-sharding automatically
- Save session states: Always save session IDs, sequences, and resume URLs to resume shards after restarts
- Monitor shard health: Track latency and connection status for each shard
- Use stateless sharding for scale: Distribute shards across multiple processes/servers for horizontal scaling
- Configure rate limiting: Adjust identify rate limiter settings based on your bot’s verification status