Discourse vs Lemmy: Which Forum to Self-Host?

Quick Verdict

Discourse and Lemmy solve fundamentally different problems. Discourse is a traditional threaded forum built for long-form discussion, support communities, and knowledge bases. Lemmy is a federated link aggregator modeled after Reddit, built for voting on links and short-form commentary across the fediverse. If you want a support forum or community discussion board, pick Discourse. If you want a Reddit-style experience that federates with other instances via ActivityPub, pick Lemmy.

Choosing between them is less about which is “better” and more about which interaction model fits your community.

Overview

Discourse launched in 2013 as a modernization of the classic forum format. Built on Ruby on Rails by Jeff Atwood (co-founder of Stack Overflow), it has become the de facto standard for self-hosted community forums. Companies like Mozilla, Docker, and Netlify run their communities on Discourse. It is polished, mature, and heavy on resources.

Lemmy appeared in 2019 as part of the fediverse movement. Written in Rust with an Actix-web backend, it implements the ActivityPub protocol so communities on one Lemmy instance can interact with communities on other instances — and with Mastodon, Kbin, and other fediverse platforms. It gained significant traction during the 2023 Reddit API pricing controversy. It is lightweight, opinionated, and federation-first.

Feature Comparison

FeatureDiscourseLemmy
ArchitectureRuby on Rails, PostgreSQL, Redis, SidekiqRust (Actix-web), PostgreSQL, pictrs (images)
Content modelThreaded discussion topics in categoriesLink posts and text posts in communities, upvote/downvote
FederationNo (single-instance only)Yes, ActivityPub — federate with other Lemmy/Kbin/Mastodon instances
Plugin ecosystemExtensive — 200+ official and community pluginsMinimal — no plugin system, features are built into core
SearchFull-text search built in, with advanced filtersBasic built-in search, improving with each release
Moderation toolsMature — trust levels, auto-moderation, flagging, review queues, slow modeSolid — per-community mods, site-wide admins, report system, slur filters
SSO / AuthenticationDiscourseConnect SSO, OAuth2, SAML, LDAP via pluginOAuth2, basic username/password, no SAML/LDAP
Mobile appsOfficial progressive web app, community iOS/Android appsJerboa (official Android), Voyager, Thunder, Eternity (community apps)
APIFull REST API, well-documentedFull REST API, auto-generated OpenAPI docs
Themes & customizationTheme system with CSS/HTML overrides, component themesLimited — basic color theming, no layout customization
Email integrationReply via email, mailing list mode, digest emailsNotifications only, no email reply
Real-time updatesYes, via MessageBus (WebSocket-like)Yes, via WebSocket
Internationalization50+ languages40+ languages
LicenseGPL-2.0AGPL-3.0
Minimum RAM2 GB (3+ GB recommended)200-300 MB

Installation Complexity

Discourse

Discourse has an opinionated installation process. The official method uses a custom Docker launcher (launcher) rather than standard Docker Compose. However, you can run it with Docker Compose if you manage the services yourself. The setup requires PostgreSQL, Redis, and Sidekiq workers. Initial configuration happens through a discourse.conf or environment variables, followed by a web-based setup wizard.

The biggest complexity is resource overhead. Discourse genuinely needs 2+ GB of RAM to run comfortably. On a 1 GB VPS, it will swap constantly and become unusable. Budget for a 4 GB machine if you want headroom.

Create a docker-compose.yml:

services:
  discourse-db:
    image: postgres:16.2-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: discourse
      POSTGRES_PASSWORD: change-this-strong-password
      POSTGRES_DB: discourse
    volumes:
      - discourse-db-data:/var/lib/postgresql/data
    networks:
      - discourse-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U discourse"]
      interval: 10s
      timeout: 5s
      retries: 5

  discourse-redis:
    image: redis:7.2-alpine
    restart: unless-stopped
    volumes:
      - discourse-redis-data:/data
    networks:
      - discourse-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  discourse:
    image: discourse/discourse:3.4.5
    restart: unless-stopped
    depends_on:
      discourse-db:
        condition: service_healthy
      discourse-redis:
        condition: service_healthy
    environment:
      # Database connection
      DISCOURSE_DB_HOST: discourse-db
      DISCOURSE_DB_PORT: "5432"
      DISCOURSE_DB_NAME: discourse
      DISCOURSE_DB_USERNAME: discourse
      DISCOURSE_DB_PASSWORD: change-this-strong-password
      # Redis connection
      DISCOURSE_REDIS_HOST: discourse-redis
      DISCOURSE_REDIS_PORT: "6379"
      # Site settings — CHANGE THESE
      DISCOURSE_HOSTNAME: forum.example.com
      DISCOURSE_DEVELOPER_EMAILS: [email protected]
      # SMTP — required for account creation
      DISCOURSE_SMTP_ADDRESS: smtp.example.com
      DISCOURSE_SMTP_PORT: "587"
      DISCOURSE_SMTP_USER_NAME: your-smtp-user
      DISCOURSE_SMTP_PASSWORD: your-smtp-password
      DISCOURSE_SMTP_ENABLE_START_TLS: "true"
    volumes:
      - discourse-data:/var/www/discourse/public
      - discourse-logs:/var/www/discourse/log
    ports:
      - "8080:80"
    networks:
      - discourse-net

volumes:
  discourse-db-data:
  discourse-redis-data:
  discourse-data:
  discourse-logs:

networks:
  discourse-net:

Note: The official Discourse team recommends their own discourse_docker launcher over plain Docker Compose. This Compose setup works but may require additional tweaks for plugin installation and upgrades. SMTP is mandatory — Discourse will not let you create accounts without working email.

Start the stack:

docker compose up -d

Access the setup wizard at http://your-server:8080.

Lemmy

Lemmy is far simpler to deploy. The stack is a Rust backend, a separate frontend (lemmy-ui), PostgreSQL, and pictrs for image hosting. Total memory footprint is under 500 MB for everything combined.

Create a docker-compose.yml:

services:
  lemmy-db:
    image: postgres:16.2-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: lemmy
      POSTGRES_PASSWORD: change-this-strong-password
      POSTGRES_DB: lemmy
    volumes:
      - lemmy-db-data:/var/lib/postgresql/data
    networks:
      - lemmy-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U lemmy"]
      interval: 10s
      timeout: 5s
      retries: 5

  pictrs:
    image: asonix/pictrs:0.5.16
    restart: unless-stopped
    environment:
      PICTRS__SERVER__API_KEY: change-this-pictrs-api-key
      PICTRS__MEDIA__VIDEO_CODEC: vp9
      PICTRS__MEDIA__GIF__MAX_WIDTH: "256"
      PICTRS__MEDIA__GIF__MAX_HEIGHT: "256"
      PICTRS__MEDIA__GIF__MAX_AREA: "65536"
      PICTRS__MEDIA__GIF__MAX_FRAME_COUNT: "400"
    volumes:
      - pictrs-data:/mnt/sled-repo
      - pictrs-files:/mnt/files
    networks:
      - lemmy-net

  lemmy:
    image: dessalines/lemmy:0.19.8
    restart: unless-stopped
    depends_on:
      lemmy-db:
        condition: service_healthy
    environment:
      LEMMY_DATABASE_URL: postgres://lemmy:change-this-strong-password@lemmy-db:5432/lemmy
      # Lemmy reads config from this file
      LEMMY_CONFIG_LOCATION: /etc/lemmy/lemmy.hjson
    volumes:
      - ./lemmy.hjson:/etc/lemmy/lemmy.hjson:ro
    networks:
      - lemmy-net

  lemmy-ui:
    image: dessalines/lemmy-ui:0.19.8
    restart: unless-stopped
    depends_on:
      - lemmy
    environment:
      # Internal API URL — the UI talks to the backend over the Docker network
      LEMMY_UI_LEMMY_INTERNAL_HOST: lemmy:8536
      # External URL — what users see in their browser
      LEMMY_UI_LEMMY_EXTERNAL_HOST: lemmy.example.com
      LEMMY_UI_HTTPS: "true"
    ports:
      - "1234:1234"
    networks:
      - lemmy-net

volumes:
  lemmy-db-data:
  pictrs-data:
  pictrs-files:

networks:
  lemmy-net:

Create a lemmy.hjson configuration file alongside the Compose file:

{
  # The domain of your instance — CHANGE THIS
  hostname: "lemmy.example.com"
  # Bind address for the API
  bind: "0.0.0.0"
  port: 8536
  # Whether to enable TLS (handle this at the reverse proxy)
  tls_enabled: false
  # pictrs image hosting config
  pictrs: {
    url: "http://pictrs:8080/"
    api_key: "change-this-pictrs-api-key"
  }
  # Database connection
  database: {
    uri: "postgres://lemmy:change-this-strong-password@lemmy-db:5432/lemmy"
  }
  # Email — optional but recommended
  email: {
    smtp_server: "smtp.example.com:587"
    smtp_login: "your-smtp-user"
    smtp_password: "your-smtp-password"
    smtp_from_address: "[email protected]"
    tls_type: "starttls"
  }
  # Federation — set to true to enable ActivityPub
  federation: {
    enabled: true
  }
}

Start the stack:

docker compose up -d

Access the UI at http://your-server:1234. The first user you register becomes the site administrator.

Lemmy is dramatically easier to set up. Fewer services, lower resource requirements, and a simpler configuration surface. Discourse requires more planning, especially around SMTP (which is mandatory, not optional).

Performance and Resource Usage

This is where the difference is stark.

ResourceDiscourseLemmy (full stack)
Minimum RAM2 GB200-300 MB
Recommended RAM4 GB512 MB - 1 GB
CPU (idle)Moderate — Ruby/Sidekiq background jobs run constantlyLow — Rust binary is extremely efficient
CPU (under load)High — Rails is not known for performanceLow to moderate — Rust handles concurrency well
Disk (application)~3 GB (app + plugins + precompiled assets)~200 MB
Disk (database)Grows with content; 1 GB+ for active communitiesGrows with content; smaller footprint per post
PostgreSQLRequiredRequired
RedisRequiredNot needed
Additional servicesSidekiq (background jobs, bundled in container)pictrs (image hosting), lemmy-ui (frontend)

The takeaway: You can run Lemmy comfortably on a $5/month VPS. Discourse needs at minimum a $10-15/month server, and a $20/month server for a community with any real activity. For resource-constrained home labs, Lemmy is the clear winner.

Community and Ecosystem

Discourse has a 10+ year head start. The ecosystem reflects that:

  • 200+ plugins covering everything from chat integration to gamification to custom layouts
  • Active Meta forum (meta.discourse.org) with years of accumulated knowledge
  • Commercial hosting available from the Discourse team (for those who don’t want to self-host)
  • Large corporate user base means issues get fixed quickly
  • Well-documented API with extensive community-built integrations
  • Professional support available through paid plans

Lemmy is younger but growing fast:

  • Part of the broader fediverse ecosystem — interoperates with Mastodon, Kbin, and other ActivityPub platforms
  • Active development with frequent releases
  • Growing mobile app ecosystem (Jerboa, Voyager, Thunder, and others)
  • Community-driven — no commercial entity behind it
  • Smaller but passionate contributor base
  • Federation means your instance is never isolated — users can interact with communities across the fediverse

For plugin-dependent workflows, Discourse wins decisively. If you need SSO with your existing identity provider, Akismet spam filtering, custom user fields, or chat integration, Discourse has plugins for all of it. Lemmy has no plugin system — you get what ships in the release.

For network effects, Lemmy’s federation is a killer feature. A new Discourse instance starts with zero users and zero content. A new Lemmy instance can immediately subscribe to communities on other instances, giving your users content from day one.

Use Cases

Choose Discourse If…

  • You are building a support community for a product or open-source project
  • You want a traditional forum with categories, topics, and threaded replies
  • Long-form discussion is the primary content format
  • You need mature moderation tools including trust levels and auto-moderation
  • You require SSO integration with an existing identity provider (SAML, LDAP, OAuth)
  • Plugin extensibility is important — you need chat, gamification, custom fields, or API integrations
  • You have the server resources to run it (4+ GB RAM recommended)
  • You want email integration — users replying to topics via email, digest emails, mailing list mode
  • Search is critical — Discourse’s full-text search with filters is substantially better

Choose Lemmy If…

  • You want a Reddit-like experience with link posts, upvotes/downvotes, and communities
  • Federation matters — you want your instance to be part of the broader fediverse
  • You are running on limited hardware (a Raspberry Pi 4 can handle Lemmy; it cannot handle Discourse)
  • You want a link aggregator, not a discussion forum
  • You care about AGPL licensing and full copyleft
  • You want your community to have content from day one by federating with existing instances
  • You prefer a simpler operational footprint — fewer services, less memory, easier upgrades
  • You are building for a privacy-focused or decentralization-minded audience

Final Verdict

These are not competitors — they are different tools for different jobs.

If someone asks “should I run Discourse or Lemmy?” the right follow-up question is “what kind of community are you building?” A product support forum, a knowledge-sharing community, or a membership organization should run Discourse. It is more polished, more extensible, and better suited for structured, long-form discussion. The resource cost is worth it for the feature set.

A link-sharing community, a local interest group, or anyone who wants to participate in the fediverse should run Lemmy. It is lightweight, federated, and purpose-built for the Reddit-style interaction model. The lack of plugins is a real limitation, but federation is a genuine advantage that Discourse cannot match.

If you are still unsure: Discourse is the safer, more mature choice for most community-building use cases. Lemmy is the right choice specifically when you want Reddit-style mechanics or federation. Pick based on the interaction model your users expect, not on which platform is “better” in the abstract.

Comments