Skip to content

Session resumption

Lavalink can keep a session alive for a configurable window after your bot disconnects. If you reconnect within that window and present the original session ID, Lavalink resumes — queues keep playing, no interruption.

discolink doesn’t implement this automatically. The right approach depends on your scale and persistence layer.

On a fresh connection, tell Lavalink to keep the session alive and store the session ID:

player.on("nodeReady", async (node, resumed) => {
if (!resumed) {
// Enable resumption with a 60-second window
await node.rest.updateSession({ resuming: true, timeout: 60 });
// Persist the session ID — use your preferred storage
await db.set(`session:${node.name}`, node.sessionId);
}
});

Pass the stored session ID via the node’s sessionId option — discolink sends it as the Session-Id WebSocket header during the handshake:

const storedSessionId = await db.get("session:main");
const player = new Player({
nodes: [
{
name: "main",
origin: "http://localhost:2333",
password: "youshallnotpass",
sessionId: storedSessionId ?? undefined,
},
],
// Disable automatic recovery — must be set at construction, not after
autoSync: false,
relocateQueues: false,
// ...
});

When resuming, you don’t want discolink overwriting Lavalink’s state (autoSync: false) or migrating queues to other nodes (relocateQueues: false).

3. Sync local state after a successful resume

Section titled “3. Sync local state after a successful resume”

After a successful resume, pull Lavalink’s player state into your local queues:

player.on("nodeReady", async (node, resumed) => {
if (resumed) {
// Pull Lavalink's player state into local queues
await player.queues.sync(node.name, "local");
}
});
player.on("nodeReady", async (node, resumed) => {
if (resumed) {
await player.queues.sync(node.name, "local");
} else {
await node.rest.updateSession({ resuming: true, timeout: 60 });
await db.set(`session:${node.name}`, node.sessionId);
}
});