Discord Bot File Storage
Permanent File Storage for Discord Bots
Reliable file storage for Discord bots with fast global delivery.
Discord's attachment CDN was built to display chat messages, not to back a bot's data layer. Since Discord added signed expiry parameters (ex, is, hm) to cdn.discordapp.com links in 2024, any attachment URL you saved in a database eventually returns a 404 — the signature times out and the link dies. If your bot stores user avatars, generated images, moderation evidence, or ticket transcripts by stashing the raw Discord attachment URL, those references rot. Re-hosting the bytes on a dedicated store fixes this permanently.
The pattern is straightforward. When your bot receives a message with an attachment, fetch the bytes from message.attachments[0].url immediately (while the signature is still valid), then push them through the files.link three-call upload and persist the returned permanent CDN URL instead. That URL never carries an expiry token, so it can sit in your database for years and still resolve.
A discord.js sketch:
client.on('messageCreate', async (msg) => {
const att = msg.attachments.first();
if (!att) return;
const bytes = Buffer.from(await (await fetch(att.url)).arrayBuffer());
// 1) POST /v1/files/{folderId} -> { urls: [{ url, id }] }
const meta = await api.post(`/v1/files/${FOLDER}`, {
filesMetadata: [{ name: att.name }],
});
const { url, id } = meta.urls[0];
// 2) PUT the bytes to the presigned URL
await fetch(url, { method: 'PUT', body: bytes });
// 3) confirm
await api.post('/v1/files/confirm-upload', { ids: [id] });
msg.reply(`Stored permanently: ${cdnUrlFor(id)}`);
});The Authorization header is your raw API key (no Bearer prefix). Because the result is a plain public CDN URL, you can drop it straight into an embed's image field — Discord fetches it from the nearest edge, so it renders the same in Tokyo as in Frankfurt. Unlike Discord's per-message size ceiling (10 MB on the free tier, up to 100 MB with boosts), there's no per-message wall here: large renders, archived logs, or generated audio all upload fine.
Keep one project and API key per bot so you can revoke a single bot's access without disturbing the rest of your fleet.
Benefits With No Complexity
Global CDN delivery
Edge-cached worldwide
Signed-URL security
What You Get
Unlimited files
Unlimited storage
Public + Private storage
CDN ready links
Prepaid credits
More coming soon
How files.link Works
1. Upload
2. Copy
3. Use Anywhere
Why Developers Choose files.link
A Better Way to Store & Deliver Files
| Discord Attachment CDN | Cloudflare R2 | Firebase Storage | files.link | |
|---|---|---|---|---|
| Permanent URLs (no expiry signature) | ||||
| No per-message size ceiling | ||||
| Global CDN delivery built in | ||||
| Single REST API, no SDK required | ||||
| Drop URL straight into an embed | ||||
| Private files with signed URLs |
Calculate Your Needs
Storage
Egress
CDN Bandwidth
Start Discord Bot Storage
- Global CDN delivery
- Edge-cached worldwide
- Signed-URL security
- Unlimited files
- Unlimited storage
- Public + Private storage
- No subscription — prepaid credits keep spend predictable