> ## Documentation Index
> Fetch the complete documentation index at: https://www.chapterjs.org/llms.txt
> Use this file to discover all available pages before exploring further.

# What your bot remembers

> Why reading a server, a member or a channel costs nothing, and how your bot keeps its memory under control by itself

Your bot remembers what Discord tells it, so that reading it never costs a request: `guild.name`, `member.roles` or `message.channel` answer at once, without asking Discord. You have nothing to set up and nothing to clean. It only remembers what your files use, which is what [Discord recommends](https://docs.discord.com/developers/events/gateway#tracking-state): like intents, it is worked out from your project.

Everything lives in the memory of the process that runs your bot. Nothing is written on disk, and there is no database to install.

## What is remembered

| What | How many | Why |
| - | - | - |
| Servers, channels, threads, roles, custom emojis | All of them | Discord announces them when the bot connects, then every change |
| Your bot as a member of each server | Always | `guild.me` is never missing, whatever the limit on members |
| Members | The 100 seen the most recently in each server | A server can have millions of members, and a bot rarely needs the silent ones |
| Users | Every one it met, across every server | They come with members and messages |
| Messages | None | They are by far what a bot receives the most, and most bots never read an old one |
| Who is in a voice channel | Everyone, while they are in it, when a file of a [voice event](https://www.chapterjs.org/events/voice.md) needs it | To tell a join from a move or a mute, and give the channel someone left |

"Seen" means Discord just sent that member: they wrote a message, used a command, joined, or changed. A member seen again becomes the most recent; when the limit is reached, the one seen the longest ago makes room.

> [!NOTE]
>
> The numbers of this table are not a setting: they follow your files. Nothing is kept for what no file uses. Saving a file in `chapterjs dev` applies the change at once.

## What it means for your code

**Nothing depends on a member being remembered.** What comes with an event is always there: the author of a message, who used a command, the member who joined, the channel it happened in. Your function receives them whatever the bot remembers, and keeps them while it runs.

```ts src/events/hello.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { event } from 'chapterjs';

export default event({
  name: 'messageCreate',
  async run({ message }) {
    // Always there, even in a server of a million members.
    await message.channel.send(`Hello ${message.member.displayName}!`);
  },
});
```

**`guild.members` is what the bot knows, not everyone.** To get one precise member, ask for it: `fetchMember()` answers from what the bot remembers when it can, and asks Discord otherwise.

```ts src/commands/joined.ts theme={"theme":{"light":"github-light","dark":"vesper"}}
import { command } from 'chapterjs';

export default command({
  name: 'joined',
  description: 'Says when someone joined',
  options: {
    who: { type: 'user', description: 'Who', required: true },
  },
  async run({ interaction, guild, options }) {
    const member = await guild.fetchMember(options.who);
    await interaction.reply(`${member.displayName} joined on ${member.joinedAt?.toDateString() ?? 'an unknown date'}.`);
  },
});
```

The only thing that depends on what the bot remembers is "as it was": `message.before` in `messageDelete` is `null` since the bot remembers no message.

## How memory is freed

What the bot remembers is bounded per server, but not in total: a bot in many servers can still fill the memory of its process. Before that happens, the bot remembers less by itself. It looks at its memory every 30 seconds:

**1. Memory stays above 80%: the bot remembers half as much**

One high reading is not enough: Node frees memory by itself when it gets full, so only a level that stays high, on two readings in a row, means something has to go. The bot then halves its limits: 50 members per server instead of 100, and half of the users it knows. The ones it had not seen for the longest leave. It tells you:

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
ℹ Memory was getting full (1638 MB of 2048 MB): the bot now remembers 50 members per server at most, and forgot 412000 members and users it had not seen for the longest. Nothing changes for your code.
```

If memory is still high 30 seconds later, it halves again: 25, 12, 6... down to 0. Servers, channels and roles are never touched: they are what keeps everything else true.

**2. Between 50% and 80%: nothing moves**

Limits never go up and down with every reading.

**3. Memory stays under 50%: the bot remembers more again**

After two readings in a row under 50%, members per server go back up step by step (twice as many at each reading, up to what your files need) and users at once. You are told when everything is back:

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
ℹ Memory is fine again: the bot remembers up to 100 members per server again.
```

**4. Nothing is left to give up: the bot asks you**

Only when its limits are already at zero and memory is still above 80% does the bot ask for something. It says so once, until memory is no longer full:

```text theme={"theme":{"light":"github-light","dark":"vesper"}}
⚠ The bot uses 1990 MB of the 2048 MB of memory it can use, and already remembers as little as it can: 1840 servers and 61200 channels, which it needs. Remembering less freed 35 MB. If your own code keeps things that only grow (a list, a Map), that is what fills it: look there first. Otherwise give the bot more memory: set NODE_OPTIONS=--max-old-space-size=4096 (in MB) on a machine that has that much.
```

The first two messages need nothing from you. The last one tells you how much memory remembering less gave back, which says where the memory goes:

* **Little** (like the 35 MB above): the memory is not used by what the bot remembers. Look in your own code for something that only grows, like a list or a `Map` you add to and never empty.
* **A lot**, and memory is still full: your bot is large. `NODE_OPTIONS=--max-old-space-size=4096` lets it use 4 GB, if your machine has them.

> [!NOTE]
>
> Whatever the bot remembers, your code works the same: what comes with an event is always there. Remembering less only means `guild.members` holds fewer members.

## Large bots

A large bot runs on [several processes](https://www.chapterjs.org/run/start.md#large-bots). Each one has its own memory: it remembers the servers it runs, and looks after its memory as described here.

> [card] [Events](https://www.chapterjs.org/events.md)
>
> What your function receives, and what is never missing.

> [card] [chapterjs start](https://www.chapterjs.org/run/start.md)
>
> Run your bot for everyone, on one process or several.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.