Objetivos de aprendizaje
Después de leer este artículo podrás:
- Elegir entre SQLite, PostgreSQL, MongoDB y Redis para tu bot
- Ver el código de conexión de cada opción en Node.js
- Evitar los errores que hacen que un bot pierda datos
En esta página
- ¿Qué criterios importan al elegir?
- ¿Cuándo SQLite es la mejor opción?
- ¿Cuándo PostgreSQL es la mejor opción?
- ¿Cuándo tiene sentido MongoDB?
- ¿Redis sirve como base de datos del bot?
- ¿Qué base de datos elegir en cada escenario?
- ¿Qué errores hacen que un bot pierda datos?
- Cómo hacerlo en Square Cloud
- Preguntas frecuentes
Casi todo bot termina necesitando guardar algo: el prefijo de cada servidor, el saldo de una economía, las advertencias de moderación, el canal de bienvenida. Lo que guardas en una variable desaparece en el próximo reinicio, así que necesitas una base de datos.
La lista parece larga, pero en la práctica hay cuatro candidatos: SQLite, PostgreSQL, MongoDB y Redis. Lo que decide entre ellos es cómo tu bot escribe y relaciona sus datos.
¿Qué criterios importan al elegir?#
Cuatro preguntas resuelven casi todos los casos:
- ¿Cuántos procesos escriben en la base de datos? Un bot de un solo proceso es distinto de un bot con shards en procesos separados, o de un bot y un panel web que escriben juntos.
- ¿Tus datos tienen relaciones? Usuarios con ítems, ítems con intercambios, intercambios con historial: eso pide tablas y
JOIN. Configuraciones sueltas por servidor no lo piden. - ¿Qué pasa con los datos en un deploy? Si la base de datos es un archivo dentro de la carpeta del bot, un deploy que reemplaza la carpeta puede llevarse el archivo. Una base de datos en un servidor separado no tiene ese riesgo.
- ¿Cuánta operación estás dispuesto a asumir? Un archivo no necesita servidor. Una base cliente-servidor necesita host, credenciales y conexión.
¿Cuándo SQLite es la mejor opción?#
SQLite es una base de datos en un único archivo, sin servidor. En Node.js, la biblioteca better-sqlite3 es síncrona y simple. Los ejemplos de este artículo usan ES modules ("type": "module" en el package.json) y una versión reciente de Node.js, como pide la versión actual de better-sqlite3:
import Database from 'better-sqlite3';
const db = new Database('bot.db');
db.pragma('journal_mode = WAL');
db.exec(`
CREATE TABLE IF NOT EXISTS guild_settings (
guild_id TEXT PRIMARY KEY,
prefix TEXT NOT NULL DEFAULT '!'
)
`);
const setPrefix = db.prepare(`
INSERT INTO guild_settings (guild_id, prefix) VALUES (?, ?)
ON CONFLICT(guild_id) DO UPDATE SET prefix = excluded.prefix
`);
const getPrefix = db.prepare('SELECT prefix FROM guild_settings WHERE guild_id = ?');
setPrefix.run('123456789012345678', '?');
console.log(getPrefix.get('123456789012345678')?.prefix); // "?"Pros: cero configuración, rápido, ideal para empezar, no depende de la red.
Contras: la documentación de SQLite dice que acepta solo un escritor a la vez por archivo de base de datos, y que no está indicado cuando muchas computadoras acceden a la misma base por la red. Si el archivo vive en un disco que desaparece o se reemplaza en cada deploy, pierdes los datos.
Úsalo cuando: es un único proceso, los datos caben en un archivo y sabes dónde se guarda ese archivo de forma duradera.
¿Cuándo PostgreSQL es la mejor opción?#
PostgreSQL es una base de datos relacional cliente-servidor. Está hecha para muchas conexiones y escrituras simultáneas (con control de concurrencia MVCC), tiene transacciones y permite consultas con relaciones. Es la opción más segura para economía, ranking, tickets y cualquier cosa en la que perder o duplicar un registro duele. Mira más en qué es PostgreSQL.
Con la biblioteca pg, usa un Pool y crea solo uno para todo el bot:
import pg from 'pg';
const pool = new pg.Pool({ connectionString: process.env.DATABASE_URL });
// sin este listener, un error en una conexión inactiva tumba el proceso
pool.on('error', (err) => console.error('error en el pool de PostgreSQL', err));
await pool.query(`
CREATE TABLE IF NOT EXISTS balances (
user_id TEXT PRIMARY KEY,
coins BIGINT NOT NULL DEFAULT 0
)
`);
// $1, $2: los parámetros evitan la inyección SQL
await pool.query(
`INSERT INTO balances (user_id, coins) VALUES ($1, $2)
ON CONFLICT (user_id) DO UPDATE SET coins = balances.coins + excluded.coins`,
['123456789012345678', 50],
);
const { rows } = await pool.query('SELECT coins FROM balances WHERE user_id = $1', ['123456789012345678']);
console.log(rows[0].coins);Pros: transacciones, integridad, escala con varios procesos, el dato queda fuera de la carpeta del bot.
Contras: exige un servidor de base de datos y una cadena de conexión. Para un bot de cinco comandos, es más de lo necesario.
¿Cuándo tiene sentido MongoDB?#
MongoDB guarda documentos parecidos a JSON, sin esquema fijo. Es cómodo cuando cada registro tiene campos distintos o el formato cambia con cada versión del bot, como un perfil de jugador con ítems variados. Más detalles en qué es MongoDB y cuándo usarlo.
import { MongoClient } from 'mongodb';
const client = new MongoClient(process.env.MONGODB_URI);
await client.connect();
const profiles = client.db('bot').collection('profiles');
await profiles.updateOne(
{ _id: '123456789012345678' },
{ $inc: { xp: 10 }, $setOnInsert: { createdAt: new Date() } },
{ upsert: true },
);
console.log(await profiles.findOne({ _id: '123456789012345678' }));Pros: modelado flexible, upsert y $inc atómicos.
Contras: sin esquema, es fácil guardar campos inconsistentes, y las relaciones entre colecciones quedan por tu cuenta. Si usas el clúster gratuito de MongoDB Atlas, ten en cuenta que tiene un límite de almacenamiento (los índices cuentan) y pausa los clústeres que pasan mucho tiempo sin conexiones. Consulta los valores actuales en la documentación de límites de Atlas.
¿Redis sirve como base de datos del bot?#
Redis guarda los datos en memoria (la escritura en disco es opcional y configurable) y es muy rápido. Es ideal para cooldowns, contadores, colas y caché, pero los datos que no pueden perderse deben quedar en una base de datos principal. Entiende la diferencia en Redis como caché o como base de datos. Antes de agregar Redis, pregúntate si un Map en memoria ya lo resuelve: para un solo proceso, normalmente sí.
¿Qué base de datos elegir en cada escenario?#
| Escenario | Recomendación |
|---|---|
| Bot pequeño, un proceso, configuraciones por servidor | SQLite |
| Economía, ranking, tickets, transacciones | PostgreSQL |
| Perfiles con campos variables, prototipo rápido | MongoDB |
| Bot con shards en procesos separados | PostgreSQL o MongoDB |
| Bot y panel web escribiendo en los mismos datos | PostgreSQL o MongoDB |
| Cooldowns y contadores temporales | Map en memoria o Redis |
| Datos de prueba | JSON o SQLite |
Si dudas, empieza con SQLite si el bot es pequeño y sabes dónde se guarda el archivo, o con PostgreSQL si ya sabes que el bot va a crecer. Cambiar después es posible, pero da trabajo de migración.
¿Qué errores hacen que un bot pierda datos?#
- Base de datos dentro de la carpeta que el deploy reemplaza. Confirma que el archivo sobrevive a un nuevo envío, o usa una base de datos externa.
- Una conexión nueva en cada comando. Crea el cliente o el
Pooluna vez, al iniciar, y reutilízalo. - Concatenar texto en SQL. Usa siempre parámetros (
?,$1). - Credenciales en el código. Pon la cadena de conexión en una variable de entorno, como en el caso del token del bot.
- Ninguna copia de los datos. Prueba restaurar una copia antes de necesitarla.
Cuánto pesa la base de datos en la factura mensual del bot lo ves en cuánto cuesta hospedar un bot.
Cómo hacerlo en Square Cloud#
Después de elegir la base de datos, falta decidir dónde corre. En Square Cloud, el Hobby (desde R$12,49 al mes) hospeda el bot, pero no incluye hospedaje de bases de datos. El hospedaje de MongoDB, PostgreSQL, MySQL y Redis empieza en el plan Standard.
Creas la base de datos en el panel (nombre, memoria y motor), en el mismo datacenter que las aplicaciones, con una latencia media de cerca de 1 ms. El panel te entrega la URL de conexión completa y el certificado para descargar. El TLS es obligatorio, así que el cliente tiene que confiar en la CA descargada (en PostgreSQL y MongoDB también presenta el certificado .pem). Pon la URL en la variable de entorno del bot (DATABASE_URL o MONGODB_URI, como en los ejemplos de arriba).
Cada base de datos es un nodo único, con hasta 512 conexiones. El mínimo es de 512 MB para Redis y 1024 MB para los demás motores. Puedes tomar snapshots manuales cuando quieras, y todo plan que incluye bases de datos tiene también un snapshot automático diario. Un snapshot se restaura en la misma base de datos o en una nueva.
Si tu bot es pequeño, SQLite en el Hobby sigue siendo una opción válida: el disco de la aplicación persiste entre reinicios y deploys, y un nuevo commit sobrescribe solo los archivos que están en el ZIP, así que deja el archivo de la base fuera de él. Mira el hospedaje de bots de Discord y los planes.
Hosting de bots
Tu bot en línea 24/7, con reinicio automático
Preguntas frecuentes
¿Puedo guardar los datos del bot en un archivo JSON?
Para pruebas, sí. En producción no: dos escrituras al mismo tiempo o una caída a mitad de la grabación pueden corromper el archivo, y reescribes todo en cada cambio. SQLite resuelve eso con la misma simplicidad.
¿SQLite aguanta un bot grande?
Aguanta muchas lecturas, pero solo permite un escritor a la vez por archivo. Para un único proceso eso rara vez es un problema. Con shards en procesos separados o varios procesos escribiendo, prefiere una base cliente-servidor.
¿MongoDB o PostgreSQL para un bot de Discord?
Los dos funcionan. PostgreSQL es mejor cuando los datos tienen relaciones (usuarios, ítems, transacciones). MongoDB es cómodo cuando cada documento tiene un formato distinto o cambia con frecuencia.
¿Necesito Redis en mi bot?
Solo si necesitas caché o contadores muy rápidos, como cooldowns y colas. Redis no reemplaza la base de datos principal. Para la mayoría de los bots, un Map en memoria o la propia base de datos alcanzan.
Más en Bots
Ver los 33 artículos- ¿Cuánto cuesta hospedar un bot de Discord?El costo de hospedar un bot de Discord depende de la RAM, el tiempo en línea, la base de datos y los servicios externos. Aprende a estimar el tuyo.
- Correr un bot en el celular (Termux) o en tu PC vs hospedarloUn bot en tu PC o celular (Termux) se cae cuando el equipo se apaga, se suspende o pierde la red. Compara las tres opciones y cuándo sirve cada una.
- Cómo mantener tu bot de Discord en línea 24/7Para mantener un bot de Discord en línea 24/7, ejecuta el proceso en una máquina siempre encendida con reinicio automático. Compara PC, VPS con pm2 o systemd.
- Por qué tu bot de Discord se apaga o aparece offlineUn bot de Discord aparece offline cuando el proceso se cae, el token es inválido, falta una intent o se acaba la memoria. Diagnostica y corrige cada causa.