Run Miniflux if you want a fast, opinionated reader with exactly one way of doing things; run FreshRSS if you want multi-user support, themes, and an extension ecosystem. Both are a single small container plus a database, both idle under 100MB of RAM, and both speak the Google Reader API — which means the genuinely good mobile apps work with either. Thirteen years after Google Reader was shut down, a self-hosted reader is better than Reader ever was, and it costs you nothing per month to run.

Two readers, two philosophies

MinifluxFreshRSS
StackGo binary, PostgreSQL requiredPHP, SQLite/MySQL/PostgreSQL
UIDeliberately minimal, keyboard-firstThree-pane, themeable, denser
ExtensionsNone, by designDozens (YouTube embeds, reading time, etc.)
Multi-userYes, admin-managedYes, with per-user quotas
FiltersRegex block/keep rulesSearch-based filter actions
Idle RAM (measured on mine)~25MB + ~90MB Postgres~70MB with SQLite
APIsGoogle Reader, Fever, own REST APIGoogle Reader, Fever

Miniflux's author maintains a short list of features he will never add, and the project is better for it — nothing to configure means nothing to break. FreshRSS is the right call when more than one person reads on the instance or when you want behaviour the Miniflux maintainer has already declined to ship. I've run both for years; Miniflux is the one I'd rebuild first.

Running Miniflux in five minutes

services:
  miniflux:
    image: miniflux/miniflux:latest
    ports:
      - "8085:8080"
    environment:
      - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=admin
      - ADMIN_PASSWORD=change-me-immediately
    depends_on:
      - db
  db:
    image: postgres:17-alpine
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=secret
    volumes:
      - ./pg:/var/lib/postgresql/data
    restart: unless-stopped

docker compose up -d, import your OPML file, done. FreshRSS is the same shape with one container and SQLite if you prefer. Default polling of every feed once an hour is polite and plenty; there is no reason to hammer small blogs every five minutes.

Filters turn 300 unread items into 30

An unfiltered subscription list is why people quit RSS. Both readers fix this at the server, so every client benefits.

Miniflux takes regex rules, either globally (Settings → Filters) or per-feed. Real examples from my instance:

EntryTitle=(?i)^sponsor
EntryTitle=(?i)(black friday|giveaway|deal alert)
EntryURL=(?i)/(tag|category)/press-release/

Matching entries are removed before you ever see them. FreshRSS does the same job through per-feed filter actions: a search query like intitle:sponsored with the action "mark as read", which keeps the item searchable but out of your unread count — a distinction I've come to prefer for borderline cases.

The move that pays best on top: subscribe to high-volume sources (Reddit subs, Hacker News, release feeds) only through filters, never raw. HN via hnrss.org with a points threshold in the URL (?points=150) turns 800 items a day into a dozen. The full rule grammar for Miniflux's side is in the official docs.

Full-text extraction fixes truncated feeds

Publishers truncate feeds to force click-throughs. Both readers can fetch the original page and extract the article body. In Miniflux it's the per-feed "Fetch original content" toggle, with an optional scraper rule (a CSS selector like div.article-body) when the automatic extraction guesses wrong. FreshRSS does it via the per-feed "Article CSS selector" field. Extraction runs server-side on refresh, so your phone gets full articles even on bad connections. Be a good citizen: enable it per-feed where needed rather than globally, since every fetch is a full page load against someone else's server. It won't defeat paywalls — extraction sees what an anonymous visitor sees — and a few sites block datacentre IPs outright, in which case the truncated feed is what you get.

Mobile: the Reader API did the hard work

You don't read in the web UI on a phone; you point a native client at your server. Because both servers implement the Google Reader API, the client list is shared: on Android, ReadYou (open source, modern) or FeedMe; on iOS/macOS, NetNewsWire (free, open source) or Reeder. All of them sync read/starred state properly through the API — offline reading on the train, state reconciled when you're back. Older clients that only speak the Fever API also work with both, but the Reader API handles starring and folders more completely; prefer it where a client offers the choice. All of the named clients cache article content for offline reading too, which is where the server-side full-text extraction pays off a second time.

Your subscriptions are one portable file

Everything you build here — the folder structure, every subscription — exports as a single OPML file from either reader, and imports into any reader ever written. That's the quiet argument for RSS in 2026: it is the last widely-deployed content protocol with no platform in the middle. The export-everything habit applies here too; mine backs up OPML weekly, and moving between Miniflux and FreshRSS while writing this post took under ten minutes in each direction.

What I'd do

Miniflux plus Postgres from the compose file above, an hour spent adding block rules the first week, hnrss.org with a points threshold instead of raw firehoses, and ReadYou or NetNewsWire on the phone via the Reader API. Choose FreshRSS instead when the instance serves your household rather than just you, or when you want the extension ecosystem. Either way the feed you scroll each morning is one you composed — no ranking, no ads, no engagement bait — and after a month of that, algorithmic timelines feel like someone else picking your reading for you. Which they were.