SSD Nodes Learn Hosting plans →
Guide Matt ConnorDi Matt Connor

Confronto lettori RSS self-hosted per un piccolo VPS

Confronto tra Miniflux, FreshRSS, CommaFeed, yarr e Tiny Tiny RSS: memoria, database, API Fever e Google Reader, oltre agli aggiornamenti su VPS.

Quale lettore RSS self-hosted è adatto a un piccolo VPS

Miniflux è il lettore RSS self-hosted più adatto a un piccolo VPS. È composto da un singolo binario Go e da PostgreSQL. Supporta le API Fever e Google Reader, quindi le app per telefoni di terze parti possono connettersi. Un aggiornamento richiede un solo docker compose pull. Scegli FreshRSS se ti servono le estensioni e vuoi un unico container con SQLite al suo interno.

Su un VPS vale la pena considerare cinque lettori: Miniflux, FreshRSS, CommaFeed, yarr e Tiny Tiny RSS. Questa pagina confronta le differenze effettive: la memoria richiesta da ogni stack, il database imposto da ciascuno, l'API di sincronizzazione richiesta dall'app per telefono e cosa accade durante un aggiornamento. Ogni dato riportato proviene dal progetto oppure è il risultato di un semplice calcolo; il testo specifica quale dei due casi si applica. Nessun dato costituisce un benchmark del tuo hardware, quindi misura il tuo server con docker stats.

I cinque lettori, un paragrafo ciascuno

Miniflux è scritto in Go e viene distribuito come un singolo binario compilato staticamente. La documentazione è chiara sull'unica dipendenza obbligatoria: "funziona solo con PostgreSQL". Non esiste una modalità SQLite. Offre un'API REST, un'API compatibile con Fever e un'API compatibile con Google Reader, oltre all'importazione e all'esportazione OPML. La ricerca nel testo completo è affidata a PostgreSQL, motivo per cui il database non è opzionale.

FreshRSS è scritto in PHP ed è eseguito come un unico container che contiene sia il server web sia l'applicazione. SQLite è il database predefinito e non richiede un secondo servizio, mentre PostgreSQL e MySQL sono supportati per le installazioni più grandi. Supporta l'API Google Reader e l'API Fever. La sua installazione è già descritta nella nostra guida a FreshRSS su un VPS, quindi questa pagina lo confronta senza ripetere la procedura di installazione.

CommaFeed è scritto in Java su Quarkus e usa un'interfaccia che riproduce quella di Google Reader. Il database viene scelto in fase di build, non a runtime, quindi il progetto pubblica un'immagine per ogni database: athou/commafeed:latest-h2 per il database H2 incorporato, athou/commafeed:latest-postgresql per PostgreSQL e altre varianti per MySQL e MariaDB. Questi tag indicano build compilate nativamente, mentre un suffisso -jvm identifica le varianti eseguite su una JVM. Espone un'API REST e un'API compatibile con Fever; dalla versione 7.3.0 (agosto 2026) offre anche un'API compatibile con Google Reader.

yarr (yet another rss reader) è un singolo binario Go con SQLite incorporato e non richiede alcun container. Il comando ./yarr, senza opzioni, resta in ascolto su 127.0.0.1:7070. I flag sono brevi: -addr 0.0.0.0:7070 -auth alice:secret lo rende raggiungibile dalla rete dietro una password, mentre -db /data/yarr.db consente di specificare la posizione del database. Offre un'API compatibile con Fever. La release con il tag più recente è la v2.9, di settembre 2026, verificata nell'ottobre 2026, dopo la v2.7 di giugno e la v2.8 di luglio; il progetto è quindi tornato a essere sviluppato attivamente.

Tiny Tiny RSS è il più vecchio dei cinque e quello più impegnativo da eseguire. Il progetto originale su tt-rss.org è stato ritirato il 1 novembre 2025, mentre lo sviluppo continua in un fork della community disponibile all'indirizzo github.com/tt-rss/tt-rss, la cui documentazione costituisce ora la procedura ufficiale di configurazione. La configurazione comprende quattro servizi: un container PostgreSQL, un container applicativo PHP-FPM, un container updater separato che recupera i feed e un container nginx davanti agli altri servizi. La documentazione dichiara esplicitamente che "questa configurazione usa PostgreSQL". Dispone di una propria API JSON, utilizzata dal client Android e da diverse applicazioni di terze parti. Fever non è supportato.

Quanta memoria richiede ogni stack

I valori riportati di seguito sono budget, non misurazioni: indicano il limite di memoria che ogni stack dovrebbe rispettare su un piccolo VPS. Il valore di CommaFeed corrisponde all'esempio pubblicato dal progetto, che limita il container a 256 MB. Gli altri valori sono limiti che lasciano margine al fetcher dei feed, cioè al componente che può aumentare bruscamente il consumo quando inizia un ciclo di aggiornamento.

GraficoMemory ceiling per reader stack, in MB
I dati alla base di questo grafico
[
  {
    "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 richiede meno memoria, con 128 MB, perché è composto da un solo binario e da un file SQLite, senza un server database né un runtime linguistico sottostante. Miniflux richiede 320 MB distribuiti su 2 container; la maggior parte è utilizzata da PostgreSQL, non da Miniflux. Tiny Tiny RSS è l'eccezione, con 640 MB distribuiti su 4 container, perché l'applicazione, l'updater, il database e il web server sono quattro processi distinti con quattro heap distinti.

Impostate questi valori come limiti effettivi, non come semplici obiettivi. Limiti di memoria in Docker Compose illustra la sintassi e il comportamento di un container quando raggiunge il limite. Un container senza limite non si arresta in modo controllato quando il sistema esaurisce la memoria: il kernel seleziona un processo e lo termina, e spesso il processo terminato non appartiene al container che ha causato la pressione sulla memoria.

Quale database impone ciascuna scelta

Il database è la principale differenza operativa tra queste cinque soluzioni. È una decisione più importante di qualsiasi differenza nell'interfaccia utente, perché determina la procedura di backup e il rischio associato agli aggiornamenti.

Miniflux e la configurazione ufficiale di Tiny Tiny RSS richiedono PostgreSQL. Offre una ricerca full-text completa e scritture concorrenti sicure. Richiede però un secondo container, un volume e la gestione di un problema ricorrente: le immagini ufficiali di PostgreSQL non possono migrare i dati tra versioni principali direttamente. La documentazione di Tiny Tiny RSS lo afferma esplicitamente e avverte che "i container ufficiali di PostgreSQL non supportano la migrazione dei dati tra versioni principali". Per un lettore di feed, le opzioni realistiche sono mantenere la versione principale precedente oppure eseguire un dump e un ripristino con pg_dump e pg_restore. PostgreSQL documenta anche pg_upgrade e gli aggiornamenti basati sulla replica. Queste procedure aggiungono complessità, ma possono essere giustificate per database di grandi dimensioni in cui il downtime è un fattore importante. Il database di un lettore di feed rientra raramente in questa categoria. Pianifica questa attività una volta ogni uno o due anni.

SQLite è il database predefinito di FreshRSS e yarr. Un solo file, nessun server, nessuna porta e nessuna password. Funziona bene per una persona con alcune centinaia di feed. Diventa più lento quando più utenti eseguono scritture contemporaneamente. In questo scenario, l'opzione PostgreSQL di FreshRSS inizia a essere vantaggiosa. yarr ha aggiunto il supporto opzionale a PostgreSQL nella v2.7, ma il file incorporato è il metodo normale per eseguirlo.

H2 è il database incorporato predefinito di CommaFeed. Prima di iniziare, valuta questa scelta con attenzione, perché CommaFeed seleziona il database durante la build dell'immagine. Passare in seguito da H2 a PostgreSQL non è una modifica della configurazione. Richiede un'immagine diversa e una migrazione dei dati che devi eseguire autonomamente. Decidi quindi prima di accumulare un anno di cronologia di lettura nel sistema.

Funzionerà la tua app per smartphone

Questa domanda è più importante di quanto molti pensino, perché l'interfaccia web rappresenta solo una parte dell'utilizzo di un lettore di feed.

Miniflux espone un'API compatibile con Fever e un'API compatibile con Google Reader, quindi la maggior parte dei client iOS e Android riesce a connettersi. FreshRSS espone le stesse due API e la relativa documentazione ne indica la priorità: l'API di Google Reader è la "migliore", con supporto completo delle funzionalità, mentre l'API di Fever offre "funzionalità limitate e un comportamento meno efficiente". FreshRSS richiede inoltre due passaggi prima che un'app possa autenticarsi. In Authentication, abilita "Allow API access (required for mobile apps)", quindi crea una password API nel profilo utente. Se non crei la password API, l'app restituisce un errore di autenticazione mentre l'accesso web continua a funzionare. Il comportamento è confuso finché non sai dove cercare.

Anche CommaFeed ora espone entrambe le API: da tempo supporta un'API compatibile con Fever e la versione 7.3.0 ha aggiunto un'API compatibile con Google Reader per le app che non supportano Fever. Usa quindi la versione 7.3.0 o una versione successiva se la tua app supporta soltanto Google Reader. yarr espone un'API compatibile con Fever e nessun'altra API, quindi funziona con i client compatibili con Fever, ma non con le app che supportano soltanto Google Reader. Tiny Tiny RSS usa invece una propria API, quindi ti serve un client sviluppato per Tiny Tiny RSS. Verifica che l'app che preferisci supporti il lettore prima di importarvi 300 feed.

Un file Compose funzionante per un server da 1 GB

Questo è lo stack Miniflux, adattato dall'esempio Docker ufficiale del progetto aggiornato a ottobre 2026. La porta pubblicata è associata all'interfaccia loopback, l'indirizzo di ascolto è impostato esplicitamente ed entrambi i container hanno un limite di 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:

Tre righe di questo file causano più spesso errori. LISTEN_ADDR=0.0.0.0:8080 ripete un'impostazione già presente nel Dockerfile dell'immagine ufficiale, quindi insieme a miniflux/miniflux è una protezione innocua, non una correzione. Diventa importante quando si crea una propria immagine o si esegue un binario pacchettizzato, perché il valore predefinito documentato del binario è 127.0.0.1:8080. Un processo associato all'interfaccia loopback all'interno di un container non può essere raggiunto tramite la porta pubblicata. Il risultato è un reset della connessione, anche se il container risulta integro. Il percorso del volume /var/lib/postgresql corrisponde a PostgreSQL 18. La versione 17 e quelle precedenti archiviano i dati in /var/lib/postgresql/data. Se si monta il percorso sbagliato, la directory dei dati non si trova affatto sul volume. Al successivo ricreare del container, quindi, tutti i dati scompaiono. 127.0.0.1:8080:8080 mantiene la porta non esposta a Internet, perché pubblicare una porta senza specificare un indirizzo aggiunge una regola a una chain che ufw non gestisce. Le porte Docker bypassano ufw spiega questo meccanismo. Un reverse proxy Traefik permette di anteporre TLS al servizio.

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

docker compose ps dovrebbe mostrare entrambi i servizi in esecuzione, con il database contrassegnato come healthy. Al primo avvio, Miniflux registra nel log le migrazioni dello schema. È questo che attiva RUN_MIGRATIONS=1. docker stats --no-stream visualizza la colonna della memoria utilizzata in tempo reale. Questo è il valore da confrontare con i limiti riportati nella tabella precedente. Se il container Miniflux si riavvia continuamente, leggere il relativo log: connect: connection refused indica che il servizio è stato avviato prima che PostgreSQL fosse pronto ad accettare connessioni. È esattamente il problema che la condizione service_healthy impedisce. Verificare quindi che la condizione sia rimasta invariata dopo le modifiche. Se Compose è una novità, Le basi di Docker Compose su un VPS descrive prima la struttura del file.

Cosa non può entrare in un server da 1 GB

Tiny Tiny RSS è l'unico da evitare. Il suo stack ufficiale composto da quattro servizi funziona su un VPS da 1 GB quando il VPS non esegue altro, ma non funziona insieme a un'altra applicazione che usa un database e a un reverse proxy. Quattro servizi significano quattro serie di overhead, e uno di questi è PostgreSQL.

CommaFeed può funzionare, ma solo con l'immagine H2 e il limite di 256 MB impostato dall'esempio ufficiale del progetto. La combinazione che mette in difficoltà un server di piccole dimensioni è CommaFeed insieme a un server di database separato. Le varianti di immagine -jvm peggiorano la situazione, perché la documentazione del progetto avverte che una JVM utilizza la memoria in modo aggressivo per impostazione predefinita e non restituisce al sistema operativo quella non più utilizzata. I tag latest-h2 e latest-postgresql identificano build native, che il progetto consiglia per il consumo ridotto di memoria. Usate quindi queste build, salvo che abbiate un motivo per eseguire la JVM.

Quando il server esaurisce la memoria, l'out-of-memory killer del kernel seleziona un processo e lo termina. dmesg -T mostra una riga simile a Out of memory: Killed process 1234 (java) e il container scompare semplicemente da docker compose ps senza messaggi nel log dell'applicazione, perché l'applicazione non ha avuto il tempo di scriverne uno.

Come si comportano gli aggiornamenti per ciascuno

  • Miniflux: docker compose pull && docker compose up -d, con le migrazioni dello schema applicate all'avvio mentre RUN_MIGRATIONS=1 è impostato. Il rischio dell'aggiornamento non riguarda Miniflux, ma la versione principale di PostgreSQL sottostante.
  • FreshRSS: scaricare la nuova immagine. Con SQLite non è necessario aggiornare alcun motore di database; i problemi più comuni derivano quindi da estensioni di terze parti non aggiornate.
  • CommaFeed: scaricare la variante dell'immagine compatibile con il database in uso. Il passaggio da latest-h2 a latest-postgresql non trasferisce i dati.
  • yarr: sostituire il binario e mantenere il file del database. Nel 2026 sono state pubblicate release a giugno, luglio e settembre; a ottobre 2026, la più recente era la v2.9. Controllare periodicamente la pagina delle release.
  • Tiny Tiny RSS: docker compose pull && docker compose up -d. Il container dell'applicazione si aggiorna all'avvio. Le FAQ del progetto associano gli errori di aggiornamento dello schema a un volume o a una configurazione di override non corretti. Se compare un errore di questo tipo, controllare prima questi elementi. Se il file compose utilizza ancora immagini del progetto ritirato tt-rss.org, sostituirle con le immagini del fork (supahgreg/tt-rss su Docker Hub oppure ghcr.io/tt-rss/tt-rss).

Eseguire un dump del database prima di ciascuna di queste operazioni, non dopo.

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

Quanto costa in banda un intervallo di aggiornamento

I numeri riportati di seguito sono calcoli aritmetici, non misurazioni. Presuppongono 100 feed, una richiesta per feed a ogni intervallo e 40 KB per risposta. Il traffico reale è inferiore quando un server gestisce le richieste condizionali e superiore quando i feed contengono il testo completo degli articoli.

GraficoMonthly fetches and bandwidth for 100 feeds at 40 KB per response
I dati alla base di questo grafico
[
  {
    "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 intervallo di cinque minuti su 100 feed genera 864,000 richieste e circa 34.6 GB al mese. Il polling ogni ora genera 72,000 richieste e circa 2.9 GB. Miniflux viene distribuito con POLLING_FREQUENCY impostato su 60 minuti, che corrisponde all'ultima riga del grafico. Questa impostazione predefinita è corretta per quasi tutti. Un articolo non arriva prima perché lo si richiede più spesso.

Le richieste condizionali mantengono il valore reale al di sotto del calcolo aritmetico. Un lettore che memorizza gli header ETag e Last-Modified restituiti da un feed li invia nuovamente come If-None-Match e If-Modified-Since. Un server che non ha nuovi contenuti risponde con 304 Not Modified senza corpo. La connessione comporta comunque il costo di un handshake, ma non quello del payload. I feed che ignorano le richieste condizionali inviano l'intero documento a ogni richiesta. Di conseguenza, pochi feed di grandi dimensioni possono incidere da soli in modo rilevante sul traffico trasferito.

Anche un polling troppo frequente può causare un blocco. Un server che rileva richieste eccessive risponde con 429 Too Many Requests, mentre alcuni siti rispondono invece con 403. Miniflux registra l'ultimo errore associato al feed. Per questo, l'elenco dei feed è il primo punto da controllare quando un feed smette di aggiornarsi mentre gli altri continuano a funzionare.

I feed cessano di funzionare e un file OPML non è un backup

I feed diventano inattivi più rapidamente del previsto. I domini scadono, i siti migrano su piattaforme senza feed e un URL che prima restituiva XML inizia a restituire una pagina di errore HTML con stato 200 OK. Quest'ultimo caso è il più problematico: il recupero riesce, l'analisi fallisce e il lettore registra un errore di parsing anziché un errore di rete. Una volta all'anno, ordina l'elenco dei feed in base all'ultimo aggiornamento ed elimina quelli che non mostrano più attività.

Un'esportazione OPML contiene l'elenco delle sottoscrizioni. Un file OPML standard contiene gli URL dei feed e i nomi delle cartelle. FreshRSS aggiunge un proprio namespace XML che contiene anche impostazioni specifiche per feed, come l'intervallo di aggiornamento, i selettori XPath per lo scraping e i filtri di lettura automatica, ma nessuna esportazione OPML conserva lo stato di lettura, gli articoli contrassegnati o il testo degli articoli salvato. Se importi quell'OPML in una nuova installazione, recuperi i feed, ma tutti gli articoli già letti risulteranno di nuovo non letti.

Il backup importante è quello del database. Per PostgreSQL, il comando pg_dump riportato sopra è tutto ciò che serve. Per un lettore SQLite come FreshRSS o yarr, arresta il processo che scrive e copia il file, oppure crea una copia coerente mentre è in esecuzione con sqlite3 yarr.db ".backup '/tmp/yarr-backup.db'". Un semplice cp di un database durante una scrittura può produrre un file che in seguito non si apre, perché la copia acquisisce una scrittura incompleta. Trasferisci quindi quei file fuori dal server secondo una pianificazione. È questo lo scopo dei backup restic su un VPS. Ripristinane almeno uno in un container temporaneo, così verifichi che la procedura funzioni.

Un lettore di feed è uno dei servizi più economici da gestire autonomamente. Per questo compare in ogni elenco delle soluzioni che vale la pena gestire autonomamente nel 2026. Affiancagli un'istanza SearXNG gestita autonomamente: sia la lettura sia le ricerche resteranno sull'hardware sotto il tuo controllo.

FAQ

Quale lettore RSS self-hosted usa meno memoria?

yarr. È un singolo binario Go con SQLite integrato, quindi non richiede un server database né un runtime aggiuntivo, e un limite di 128 MB è sufficiente. Il compromesso riguarda le funzionalità: supporta soltanto l'API Fever e la versione più recente è la v2.9 di settembre 2026. Se vuoi il supporto all'API Google Reader e la ricerca nel testo completo con un ingombro simile, Miniflux con PostgreSQL a 320 MB è la scelta migliore.

Posso eseguire un lettore RSS self-hosted su un VPS da 1 GB?

Sì. Miniflux con PostgreSQL rientra in circa 320 MB quando imposti mem_limit su entrambi i container, mentre FreshRSS con SQLite rientra in un solo container. Su un VPS da 1 GB va evitato lo stack ufficiale di Tiny Tiny RSS, che comprende 4 servizi, incluso il proprio PostgreSQL. Imposta sempre i limiti di memoria, perché un container senza limiti su un host con memoria esaurita può causare l'intervento del kernel, che termina un processo. Spesso viene terminato il database anziché l'applicazione che ha causato il problema.

Quali di questi funzionano con le app RSS per iOS e Android?

Miniflux, FreshRSS e CommaFeed 7.3.0 o versioni successive supportano sia un'API compatibile con Fever sia un'API compatibile con Google Reader, quindi quasi ogni client mobile può connettersi. yarr offre soltanto l'API Fever. Tiny Tiny RSS usa una propria API, quindi serve un client progettato per questo sistema. In FreshRSS devi inoltre abilitare l'accesso all'API in Authentication e impostare una password API separata nel profilo. In caso contrario, l'app non riesce ad autenticarsi mentre il sito web continua a funzionare.

Un'esportazione OPML è un backup del mio lettore RSS?

No. OPML ricrea l'elenco delle iscrizioni. L'esportazione estesa di FreshRSS include anche le impostazioni e i filtri specifici dei feed, ma lo stato di lettura, gli elementi contrassegnati e il testo degli articoli sono tutti memorizzati nel database. Esegui il backup del database con pg_dump per PostgreSQL oppure con un comando .backup per SQLite, quindi copia il risultato fuori dal server.

Miniflux supporta SQLite?

No. La documentazione del progetto specifica che "funziona solo con PostgreSQL". Inoltre, la ricerca nel testo completo è implementata tramite funzionalità di PostgreSQL, quindi non esiste una modalità più leggera a cui passare. Se vuoi un lettore di feed che non richieda alcun container per il database, esegui FreshRSS con il backend SQLite predefinito oppure yarr con il proprio file incorporato.

Questo articolo ti è stato utile?