SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Lectores RSS autohospedados para un VPS pequeño

Compare Miniflux, FreshRSS, CommaFeed, yarr y Tiny Tiny RSS: memoria, bases de datos, APIs de Fever y Google Reader y comportamiento al actualizar.

¿Qué lector RSS autohospedado es adecuado para un VPS pequeño?

Miniflux es el lector RSS autohospedado más adecuado para instalar en un VPS pequeño. Consta de un único binario de Go junto a PostgreSQL. Es compatible con las API de Fever y Google Reader, por lo que las aplicaciones de teléfono de terceros pueden conectarse. Además, una actualización consiste en un único docker compose pull. Elija FreshRSS si necesita extensiones y un único contenedor que incluya SQLite.

Cinco lectores justifican el espacio en disco de un VPS: Miniflux, FreshRSS, CommaFeed, yarr y Tiny Tiny RSS. Esta página compara sus diferencias prácticas: la memoria que necesita cada pila, la base de datos que impone cada uno, la API de sincronización que necesita la aplicación del teléfono y lo que ocurre al actualizar. Todas las cifras proceden del proyecto correspondiente o son cálculos directos, y el texto indica cuál de las dos cosas es cada una. Ninguna cifra es una prueba de rendimiento de su hardware. Mida su propio sistema con docker stats.

Los cinco lectores, un párrafo por cada uno

Miniflux está escrito en Go y se distribuye como un único binario compilado estáticamente. Su documentación es clara sobre la única dependencia obligatoria: «funciona únicamente con PostgreSQL». No tiene modo SQLite. Ofrece una API REST, una API compatible con Fever y una API compatible con Google Reader, además de importar y exportar OPML. La búsqueda de texto completo la gestiona PostgreSQL, que es una de las razones por las que la base de datos no es opcional.

FreshRSS está escrito en PHP y se ejecuta como un único contenedor que incluye el servidor web y la aplicación. SQLite es la base de datos predeterminada y no necesita un segundo servicio, mientras que PostgreSQL y MySQL son compatibles con instalaciones grandes. Es compatible con la API de Google Reader y la API de Fever. La instalación ya se explica en nuestro tutorial para instalar FreshRSS en un VPS, por lo que esta página lo compara sin repetir la instalación.

CommaFeed está escrito en Java sobre Quarkus y utiliza un diseño que imita a Google Reader. La base de datos se elige durante la compilación, no durante la ejecución, por lo que el proyecto publica una imagen por base de datos: athou/commafeed:latest-h2 para la base de datos H2 integrada, athou/commafeed:latest-postgresql para PostgreSQL y otras variantes para MySQL y MariaDB. Esas etiquetas corresponden a compilaciones nativas, mientras que el sufijo -jvm identifica las variantes que se ejecutan en una JVM. Expone una API REST y una API compatible con Fever, y desde la versión 7.3.0 (agosto de 2026) también una API compatible con Google Reader.

yarr (yet another rss reader) es un único binario de Go con SQLite integrado y no necesita ningún contenedor. ./yarr sin opciones escucha en 127.0.0.1:7070. Las opciones son breves: -addr 0.0.0.0:7070 -auth alice:secret permite acceder desde la red mediante una contraseña y -db /data/yarr.db coloca la base de datos en la ruta indicada. Tiene una API compatible con Fever. Su versión etiquetada más reciente es v2.9, de septiembre de 2026, comprobada en octubre de 2026, después de v2.7 en junio y v2.8 en julio, por lo que vuelve a desarrollarse activamente.

Tiny Tiny RSS es el más antiguo de los cinco y el más complejo de ejecutar. El proyecto original de tt-rss.org se retiró el 1 de noviembre de 2025, y el desarrollo continúa en un fork comunitario en github.com/tt-rss/tt-rss, cuya documentación es ahora la guía oficial de instalación. Esa instalación consta de cuatro servicios: un contenedor de PostgreSQL, un contenedor de la aplicación PHP-FPM, un contenedor independiente de actualización que obtiene los feeds y un contenedor de nginx delante de ellos. La documentación indica claramente que «esta instalación utiliza PostgreSQL». Tiene su propia API JSON, que utilizan su cliente para Android y varias aplicaciones de terceros. Fever no forma parte de ella.

Cuánta memoria necesita cada stack

Las cifras siguientes son límites presupuestarios, no mediciones: el techo de memoria que cada stack debería respetar en un VPS pequeño. La cifra de CommaFeed es el ejemplo publicado por el propio proyecto, que limita el contenedor a 256 MB. Los demás valores son límites que dejan margen para el recolector de feeds, que es el componente que experimenta picos cuando comienza un ciclo de actualización.

GráficoMemory ceiling per reader stack, in MB
Los datos de este gráfico
[
  {
    "label": "yarr (SQLite)",
    "containers": 1,
    "mem_limit_mb": 128
  },
  {
    "label": "FreshRSS (SQLite)",
    "containers": 1,
    "mem_limit_mb": 256
  },
  {
    "label": "CommaFeed (H2)",
    "containers": 1,
    "mem_limit_mb": 256
  },
  {
    "label": "Miniflux + Postgres",
    "containers": 2,
    "mem_limit_mb": 320
  },
  {
    "label": "Tiny Tiny RSS",
    "containers": 4,
    "mem_limit_mb": 640
  }
]

yarr usa el valor más bajo, 128 MB, porque consta de un binario y un archivo SQLite, sin un servidor de base de datos ni un runtime de lenguaje debajo. Miniflux necesita 320 MB en 2 contenedores, y la mayor parte corresponde a PostgreSQL, no a Miniflux. Tiny Tiny RSS es la excepción, con 640 MB en 4 contenedores, porque la aplicación, el actualizador, la base de datos y el servidor web son cuatro procesos independientes, cada uno con su propio heap.

Establezca estos valores como límites reales, no como simples expectativas. Límites de memoria en Docker Compose explica la sintaxis y el comportamiento de un contenedor cuando alcanza el límite. Un contenedor sin límite no falla de forma controlada cuando el host se queda sin memoria: el kernel selecciona un proceso y lo termina, y a menudo el proceso afectado no pertenece al contenedor que provocó la presión.

Qué base de datos le obliga a usar cada lector

La base de datos es la mayor diferencia operativa entre estos cinco lectores. Es una decisión más importante que cualquier diferencia de interfaz de usuario, porque determina el procedimiento de copia de seguridad y el riesgo de las actualizaciones.

Miniflux y la configuración oficial de Tiny Tiny RSS requieren PostgreSQL. Ofrece búsqueda de texto completo real y escrituras simultáneas seguras. A cambio, necesita un segundo contenedor, un volumen y un problema recurrente: las imágenes oficiales de PostgreSQL no pueden migrar datos entre versiones principales en el mismo lugar. La documentación de Tiny Tiny RSS lo indica directamente y advierte que "los contenedores oficiales de PostgreSQL no admiten la migración de datos entre versiones principales". Para un lector de feeds, las opciones realistas son fijar la versión principal antigua o volcar y restaurar los datos con pg_dump y pg_restore. PostgreSQL también documenta pg_upgrade y las actualizaciones basadas en replicación. Estas opciones justifican su configuración adicional en bases de datos grandes donde el tiempo de inactividad es importante, pero la base de datos de un lector de feeds rara vez pertenece a esa categoría. Planifíquelo una vez cada uno o dos años.

SQLite es la opción predeterminada de FreshRSS y de yarr. Un solo archivo, sin servidor, sin puerto y sin contraseña. Funciona bien para una persona con unos cientos de feeds y se ralentiza cuando varios usuarios escriben al mismo tiempo. En ese momento, la opción PostgreSQL de FreshRSS empieza a resultar útil. yarr añadió compatibilidad opcional con PostgreSQL en v2.7, pero el archivo integrado es la forma normal de ejecutarlo.

H2 es la opción integrada predeterminada de CommaFeed. Conviene pensarlo antes de empezar, porque CommaFeed selecciona la base de datos al crear la imagen. Pasar de H2 a PostgreSQL más adelante no es un cambio de configuración. Requiere otra imagen y una migración de datos que tendrá que realizar usted mismo. Decida antes de acumular un año de historial de lecturas en el servidor.

Compatibilidad con la aplicación del teléfono

Esta cuestión determina más de lo que muchos esperan, porque la interfaz web es sólo la mitad del uso de un lector de feeds.

Miniflux ofrece una API compatible con Fever y una API compatible con Google Reader, por lo que la mayoría de los clientes para iOS y Android pueden conectarse a él. FreshRSS ofrece las mismas dos API y su propia documentación establece una preferencia: la API de Google Reader es la "mejor", con compatibilidad completa con las funciones, mientras que la API de Fever tiene un comportamiento con "funciones limitadas y menos eficiente". FreshRSS también requiere dos pasos antes de que cualquier aplicación pueda iniciar sesión. Active "Allow API access (required for mobile apps)" en Authentication y cree una contraseña de API en el perfil de usuario. Si omite la contraseña de API, la aplicación muestra un error de autenticación mientras el inicio de sesión web sigue funcionando. Esto resulta confuso hasta que se sabe dónde buscar.

CommaFeed también ofrece ahora las dos API: desde hace tiempo incluye una API compatible con Fever y la versión 7.3.0 añadió una API compatible con Google Reader para las aplicaciones que no admiten Fever. Use la versión 7.3.0 o posterior si su aplicación sólo admite Google Reader. yarr expone una API compatible con Fever y ninguna otra, por lo que funciona con clientes compatibles con Fever, pero no con aplicaciones que sólo admiten Google Reader. Tiny Tiny RSS tiene su propia API, así que necesita un cliente desarrollado para ella. Compruebe que su aplicación preferida admita el lector antes de importar 300 feeds.

Un archivo compose funcional para un servidor de 1 GB

Esta es la pila de Miniflux, adaptada del ejemplo de Docker del propio proyecto con fecha de octubre de 2026. El puerto publicado está vinculado a loopback, la dirección de escucha se establece explícitamente y ambos contenedores tienen un límite de memoria.

services:
  miniflux:
    image: miniflux/miniflux:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      db:
        condition: service_healthy
    environment:
      - DATABASE_URL=postgres://miniflux:CHANGE_ME@db/miniflux?sslmode=disable
      - LISTEN_ADDR=0.0.0.0:8080
      - BASE_URL=https://rss.example.com/
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=CHANGE_ME_TOO
      - POLLING_FREQUENCY=60
    healthcheck:
      test: ["CMD", "/usr/bin/miniflux", "-healthcheck", "auto"]
    mem_limit: 128m
  db:
    image: postgres:18
    restart: unless-stopped
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=CHANGE_ME
      - POSTGRES_DB=miniflux
    volumes:
      - miniflux-db:/var/lib/postgresql
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "miniflux"]
      interval: 10s
      start_period: 30s
    mem_limit: 192m
volumes:
  miniflux-db:

Tres líneas de este archivo suelen configurarse mal. LISTEN_ADDR=0.0.0.0:8080 repite lo que la imagen oficial ya establece en su Dockerfile, por lo que, junto con miniflux/miniflux, es una protección inocua y no una corrección. Es importante cuando se crea una imagen propia o se ejecuta un binario empaquetado, porque el valor predeterminado documentado del binario es 127.0.0.1:8080. Además, un proceso vinculado a loopback dentro de un contenedor no puede recibir conexiones a través del puerto publicado. El resultado es un reinicio de la conexión con un contenedor que parece estar funcionando correctamente. La ruta del volumen /var/lib/postgresql coincide con PostgreSQL 18. La versión 17 y las anteriores almacenan los datos en /var/lib/postgresql/data. Montar la ruta incorrecta significa que el directorio de datos no está en el volumen, por lo que todos los datos desaparecen la próxima vez que se recrea el contenedor. 127.0.0.1:8080:8080 mantiene el puerto fuera de Internet pública, porque publicar un puerto sin especificar una dirección escribe una regla en una cadena que ufw no administra. Los puertos de Docker omiten ufw explica ese mecanismo, y un reverse proxy de Traefik permite poner TLS delante del servicio.

docker compose up -d
docker compose ps
docker compose logs -f miniflux
docker stats --no-stream

docker compose ps debería mostrar ambos servicios en ejecución y marcar la base de datos como healthy. El primer inicio de Miniflux registra sus migraciones de esquema, que es lo que activa RUN_MIGRATIONS=1. docker stats --no-stream muestra la columna de memoria en tiempo real. Ese es el valor que debe compararse con los límites del cuadro anterior. Si el contenedor de Miniflux se reinicia continuamente, lea su registro: connect: connection refused significa que se inició antes de que PostgreSQL estuviera listo para aceptar conexiones. Eso es exactamente lo que evita la condición service_healthy, por lo que debe comprobar que la condición se haya conservado después de editar el archivo. Si Compose es nuevo para usted, Conceptos básicos de Docker Compose en un VPS explica primero la estructura del archivo.

Qué no cabe en un servidor de 1 GB

Tiny Tiny RSS es el servicio que conviene descartar. Su pila oficial de cuatro servicios funciona en un VPS de 1 GB cuando ese VPS no hace nada más, pero no funciona junto con otra aplicación que use una base de datos y un reverse proxy. Cuatro servicios implican cuatro conjuntos de sobrecarga, y uno de ellos es PostgreSQL.

CommaFeed cabe, pero sólo con la imagen H2 y el límite de 256 MB que establece el ejemplo del propio proyecto. La combinación que deja sin recursos a un servidor pequeño es CommaFeed junto con un servidor de base de datos independiente. Las variantes de imagen -jvm lo empeoran, porque la documentación del proyecto advierte que una JVM consume memoria de forma predeterminada y no devuelve al sistema operativo la memoria que deja de usar. Las etiquetas latest-h2 y latest-postgresql corresponden a compilaciones nativas, que el proyecto recomienda porque usan menos memoria. Manténgase en ellas salvo que tenga un motivo para ejecutar la JVM.

Cuando un servidor se queda sin memoria, el killer de falta de memoria del kernel selecciona un proceso y lo termina. dmesg -T muestra una línea como Out of memory: Killed process 1234 (java), y el contenedor simplemente desaparece de docker compose ps sin ningún mensaje en el registro de la aplicación, porque la aplicación nunca llegó a escribirlo.

Cómo se comportan las actualizaciones en cada uno

  • Miniflux: docker compose pull && docker compose up -d, con las migraciones del esquema aplicadas al iniciar mientras RUN_MIGRATIONS=1 esté configurado. El riesgo de actualización no está en Miniflux. Está en la versión principal de PostgreSQL subyacente.
  • FreshRSS: descargue la imagen nueva. Con SQLite no hay ningún motor de base de datos que actualizar, por lo que los fallos habituales proceden de extensiones de terceros que no se han mantenido al día.
  • CommaFeed: descargue la variante de imagen que corresponda a su base de datos. Cambiar de latest-h2 a latest-postgresql no transfiere los datos.
  • yarr: sustituya el binario y conserve el archivo de base de datos. Se publicaron versiones en junio, julio y septiembre de 2026, y v2.9 era la más reciente en octubre de 2026, así que revise periódicamente la página de versiones.
  • Tiny Tiny RSS: docker compose pull && docker compose up -d. El contenedor de la aplicación se actualiza al iniciar, y las preguntas frecuentes del proyecto relacionan los errores de actualización del esquema con un volumen o una configuración de overrides defectuosos. Si aparece uno, compruebe primero esos elementos. Si el archivo compose todavía descarga imágenes del proyecto retirado tt-rss.org, cámbielo por las imágenes del fork (supahgreg/tt-rss en Docker Hub o ghcr.io/tt-rss/tt-rss).

Haga un volcado de la base de datos antes de cualquiera de estas operaciones, no después.

docker compose exec -T db pg_dump -U miniflux miniflux | gzip > miniflux-$(date +%F).sql.gz

Cuánto ancho de banda consume un intervalo de actualización

Las cifras siguientes son cálculos, no mediciones. Suponen 100 feeds, una solicitud por feed en cada intervalo y 40 KB por respuesta. El tráfico real suele ser menor cuando un servidor admite solicitudes condicionales, y mayor cuando los feeds incluyen el texto completo de los artículos.

GráficoMonthly fetches and bandwidth for 100 feeds at 40 KB per response
Los datos de este gráfico
[
  {
    "label": "Every 5 minutes",
    "fetches_per_month": "864,000",
    "gb_per_month": 34.6
  },
  {
    "label": "Every 15 minutes",
    "fetches_per_month": "288,000",
    "gb_per_month": 11.5
  },
  {
    "label": "Every 30 minutes",
    "fetches_per_month": "144,000",
    "gb_per_month": 5.8
  },
  {
    "label": "Every 60 minutes",
    "fetches_per_month": "72,000",
    "gb_per_month": 2.9
  }
]

Un intervalo de cinco minutos para 100 feeds supone 864,000 solicitudes y aproximadamente 34.6 GB al mes. La consulta cada hora supone 72,000 solicitudes y unos 2.9 GB. Miniflux incluye POLLING_FREQUENCY configurado en 60 minutos, que corresponde a la última fila de ese gráfico, y ese valor predeterminado es adecuado para casi todos. Un artículo no llega antes porque lo solicite con más frecuencia.

Las solicitudes condicionales son las que mantienen la cifra real por debajo del cálculo. Un lector que almacena las cabeceras ETag y Last-Modified que devuelve un feed las envía de nuevo como If-None-Match y If-Modified-Since, y un servidor sin contenido nuevo responde 304 Not Modified sin cuerpo. La conexión sigue teniendo el coste del handshake, pero no el de la carga útil. Los feeds que ignoran las solicitudes condicionales envían el documento completo en cada consulta, por lo que unos pocos feeds grandes pueden dominar por sí solos el coste de transferencia.

Consultar con demasiada frecuencia también puede hacer que le bloqueen. Un servidor que determina que está generando demasiadas solicitudes responde 429 Too Many Requests, y algunos sitios responden 403 en su lugar. Miniflux registra el último error asociado al propio feed, por lo que la lista de feeds es el primer lugar que debe revisar cuando un feed deja de actualizarse mientras los demás siguen funcionando.

Los feeds caducan, y un archivo OPML no es una copia de seguridad

Los feeds dejan de funcionar antes de lo que espera. Los dominios caducan, los sitios migran a plataformas sin feed y una URL que antes servía XML empieza a devolver una página de error HTML con un estado 200 OK. Este último caso es el más problemático: la descarga se completa, el análisis falla y el lector registra un error de análisis en lugar de un error de red. Una vez al año, ordene la lista de feeds por fecha de última actualización y elimine los que hayan dejado de responder.

Una exportación OPML es la lista de suscripciones. Un archivo OPML estándar contiene las URL de los feeds y los nombres de las carpetas. FreshRSS añade su propio espacio de nombres XML, que también incluye ajustes por feed, como el intervalo de actualización, los selectores XPath para extraer contenido y los filtros de marcado automático como leído. Sin embargo, ninguna exportación OPML conserva el estado de lectura, los artículos destacados ni el texto de los artículos que haya guardado. Si importa ese OPML en una instalación nueva, recuperará los feeds, pero todos los artículos que haya leído volverán a aparecer como no leídos.

La copia de seguridad importante es la base de datos. Para PostgreSQL, el comando pg_dump anterior realiza todo el trabajo. Para un lector basado en SQLite, como FreshRSS o yarr, detenga el proceso que escribe y copie el archivo, o haga una copia coherente mientras está en ejecución con sqlite3 yarr.db ".backup '/tmp/yarr-backup.db'". Un cp simple de una base de datos en la que se está escribiendo puede generar un archivo que después no se pueda abrir, porque la copia captura una escritura incompleta. Después, transfiera esos archivos fuera del servidor según una programación. Para eso sirven las copias de seguridad de restic en un VPS. Restaure una copia en un contenedor temporal al menos una vez para comprobar que el procedimiento funciona.

Un lector de feeds es uno de los servicios más económicos de administrar por cuenta propia. Por eso aparece en todas las listas de servicios que merece la pena alojar por cuenta propia en 2026. Instale junto a él una instancia de SearXNG alojada por cuenta propia para mantener tanto la lectura como las búsquedas en hardware bajo su control.

FAQ

¿Qué lector RSS autohospedado usa menos memoria?

yarr. Es un único binario de Go con SQLite integrado, por lo que no necesita un servidor de base de datos ni un runtime de lenguaje adicional, y un límite de 128 MB es suficiente. La contrapartida son las funciones: sólo admite la API de Fever, y su versión más reciente es la v2.9 de septiembre de 2026. Si necesita compatibilidad con la API de Google Reader y búsqueda de texto completo con un consumo similar, Miniflux con PostgreSQL y 320 MB es una opción más adecuada.

¿Puedo ejecutar un lector RSS autohospedado en un VPS de 1 GB?

Sí. Miniflux con PostgreSQL cabe en unos 320 MB cuando establece mem_limit en ambos contenedores, y FreshRSS con SQLite cabe en un solo contenedor. En un VPS de 1 GB debe evitar la pila oficial de Tiny Tiny RSS, que consta de 4 servicios, incluido su propio PostgreSQL. Establezca siempre límites de memoria, porque un contenedor sin límite en un servidor sin memoria disponible puede hacer que el kernel termine un proceso, y a menudo el proceso elegido es la base de datos en lugar de la aplicación que causa el problema.

¿Cuáles funcionan con aplicaciones RSS para iOS y Android?

Miniflux, FreshRSS y CommaFeed 7.3.0 o posterior admiten tanto una API compatible con Fever como una API compatible con Google Reader, por lo que casi cualquier cliente móvil puede conectarse. yarr sólo ofrece la API de Fever. Tiny Tiny RSS usa su propia API, por lo que necesita un cliente creado para ella. En FreshRSS también debe habilitar el acceso a la API en Authentication y establecer una contraseña de API independiente en el perfil; de lo contrario, la aplicación no podrá iniciar sesión aunque el sitio web siga funcionando.

¿Una exportación OPML es una copia de seguridad de mi lector RSS?

No. OPML reconstruye la lista de suscripciones, y la exportación ampliada de FreshRSS también incluye la configuración y los filtros de cada fuente, pero el estado de lectura, los elementos destacados y el texto de los artículos se almacenan en la base de datos. Haga una copia de seguridad de la propia base de datos con pg_dump para PostgreSQL o con un comando .backup para SQLite, y copie el resultado fuera del servidor.

¿Miniflux admite SQLite?

No. La documentación del proyecto indica que "funciona únicamente con PostgreSQL", y la búsqueda de texto completo se implementa mediante funciones de PostgreSQL, por lo que no existe un modo más ligero al que cambiar. Si quiere un lector de fuentes sin un contenedor de base de datos, ejecute FreshRSS con su backend SQLite predeterminado o yarr con su archivo integrado.