Nextcloud Talk performance - how to troubleshoot or work around

I’m having some performance issues with the Talk app in my Nextcloud instance. I’m new to Nextcloud, I just recently got it running for my small team of 4. I’ve been very happy with it except for these performance issues with Talk. I use several other apps (see below) and they all seem snappy and performant as long as the Talk app is disabled. I’m looking for help digging into what might be causing the performance issues. I’ve tried the obvious things like running top on the host and tailing logs, but I haven’t yet found a likely root cause.

The repro is easy: enable Talk, click back and forth between a couple conversations. Try and click away to another app (e.g. Files) and it could take 20-40 seconds. Eventually page views may speed up. I can also restart the server to get Nextcloud back to normal speed. During the repro I see no noticeable server load, no obvious issues in the logs. So far my workaround is to disable the Talk app.

The next thing I was going to try was switching to the plain old nextcloud image instead of the nextcloud:stable-fpm-alpine and nginx:stable-alpine images. Any other things I should try? I really want to use the Talk app but this performance is a dealbreaker. I also find the duplicate session limitation pretty darn annoying but it sounds like this will be a hard thing to fix.

Looks related:

Can I somehow disable webrtc alone? I don’t want/need to use Talk to make voice or video calls. I really just want the text chat.

I’m using:

  • Talk 9.0.3
  • Nextcloud 19.0.3 - 19.0.3.1 running on Docker using the official docker-compose.yml
    • Webserver: nginx/1.18.0 (fpm-fcgi)
    • Database: mysql 10.5.5 (mariadb)
    • PHP version: 7.4.10
    • Modules loaded: Core, date, libxml, openssl, pcre, sqlite3, zlib, ctype, curl, dom, fileinfo, filter, ftp, hash, iconv, json, mbstring, SPL, PDO, pdo_sqlite, session, posix, readline, Reflection, standard, SimpleXML, Phar, tokenizer, xml, xmlreader, xmlwriter, mysqlnd, cgi-fcgi, apcu, bcmath, exif, gd, gmp, imagick, intl, ldap, memcached, pcntl, pdo_mysql, pdo_pgsql, redis, sodium, zip, Zend OPcache
  • running behind Traefik 2.2.11 reverse proxy / load balancer (it fronts a bunch of other web services too, all of them seem to work fine)
  • Let’s Encrypt
  • Docker host machine runs 64-bit Ubuntu GNU/Linux server
    • Linux 5.4.0-47-generic #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020 x86_64
  • /settings/admin/overview says “All checks passed.”
  • in case this matters: nextcloud.example.com usually resolves to a public IPv4 address, except in my LAN. In my LAN it resolves to a private IPv4 address (e.g. 192.168.1.15).

Enabled:

  • accessibility: 1.5.0
  • activity: 2.12.0
  • admin_audit: 1.9.0
  • audioplayer: 2.11.2
  • audioplayer_editor: 0.2.2
  • bruteforcesettings: 2.0.1
  • calendar: 2.0.4
  • cloud_federation_api: 1.2.0
  • comments: 1.9.0
  • contacts: 3.3.0
  • contactsinteraction: 1.0.0
  • dav: 1.15.0
  • event_update_notification: 1.0.2
  • federatedfilesharing: 1.9.0
  • federation: 1.9.0
  • files: 1.14.0
  • files_external: 1.10.0
  • files_markdown: 2.3.0
  • files_pdfviewer: 1.8.0
  • files_rightclick: 0.16.0
  • files_sharing: 1.11.0
  • files_trashbin: 1.9.0
  • files_versions: 1.12.0
  • files_videoplayer: 1.8.0
  • firstrunwizard: 2.8.0
  • forms: 2.0.4
  • gpxedit: 0.0.13
  • logreader: 2.4.0
  • lookup_server_connector: 1.7.0
  • maps: 0.1.6
  • nextcloud_announcements: 1.8.0
  • notes: 3.6.4
  • notifications: 2.7.0
  • oauth2: 1.7.0
  • password_policy: 1.9.1
  • photos: 1.1.0
  • privacy: 1.3.0
  • provisioning_api: 1.9.0
  • recommendations: 0.7.0
  • richdocuments: 3.7.4
  • serverinfo: 1.9.0
  • settings: 1.1.0
  • sharebymail: 1.9.0
  • spreed: 9.0.3
  • support: 1.2.1
  • systemtags: 1.9.0
  • tasks: 0.13.3
  • text: 3.0.1
  • theming: 1.10.0
  • twofactor_backupcodes: 1.8.0
  • updatenotification: 1.9.0
  • user_ldap: 1.9.0
  • viewer: 1.3.0
  • workflowengine: 2.1.0

Disabled:

  • encryption
  • ojsxc
  • survey_client

Nextcloud config:

{
    "htaccess.RewriteBase": "\/",
    "memcache.local": "\\OC\\Memcache\\APCu",
    "apps_paths": [
        {
            "path": "\/var\/www\/html\/apps",
            "url": "\/apps",
            "writable": false
        },
        {
            "path": "\/var\/www\/html\/custom_apps",
            "url": "\/custom_apps",
            "writable": true
        }
    ],
    "instanceid": "***REMOVED SENSITIVE VALUE***",
    "passwordsalt": "***REMOVED SENSITIVE VALUE***",
    "secret": "***REMOVED SENSITIVE VALUE***",
    "trusted_domains": [
        "nextcloud.example.com"
    ],
    "datadirectory": "***REMOVED SENSITIVE VALUE***",
    "dbtype": "mysql",
    "version": "19.0.3.1",
    "overwrite.cli.url": "http:\/\/nextcloud.example.com",
    "overwriteprotocol": "https",
    "dbname": "***REMOVED SENSITIVE VALUE***",
    "dbhost": "***REMOVED SENSITIVE VALUE***",
    "dbport": "",
    "dbtableprefix": "oc_",
    "mysql.utf8mb4": true,
    "dbuser": "***REMOVED SENSITIVE VALUE***",
    "dbpassword": "***REMOVED SENSITIVE VALUE***",
    "installed": true,
    "mail_smtpmode": "smtp",
    "mail_smtphost": "***REMOVED SENSITIVE VALUE***",
    "mail_sendmailmode": "smtp",
    "mail_smtpport": "25",
    "trusted_proxies": "***REMOVED SENSITIVE VALUE***",
    "forwarded_for_headers": [
        "HTTP_X_FORWARDED_FOR"
    ],
    "maintenance": false,
    "loglevel": 3,
    "ldapIgnoreNamingRules": false,
    "ldapProviderFactory": "OCA\\User_LDAP\\LDAPProviderFactory",
    "has_internet_connection": true,
    "memcache.distributed": "\\OC\\Memcache\\Redis",
    "memcache.locking": "\\OC\\Memcache\\Redis",
    "redis": {
        "host": "***REMOVED SENSITIVE VALUE***",
        "password": "***REMOVED SENSITIVE VALUE***",
        "port": 6379
    }
}

my docker-compose.yml :

version: '3.5'

volumes:
  docroot:
    driver: local
    driver_opts:
      type: 'none'
      o: 'bind'
      device: '/nextcloud'
services:
  app:
    image: nextcloud:stable-fpm-alpine
    environment:
      MYSQL_HOST: db:3306
      MYSQL_USER: nextcloud
      MYSQL_PASSWORD: 'REDACTED'
      MYSQL_DATABASE: nextcloud
      SMTP_HOST: mail
      REDIS_HOST: redis
      REDIS_HOST_PASSWORD: "REDACTED"
    labels:
      - "traefik.enable=false"
    volumes:
      - docroot:/var/www/html:rw
    networks:
      - nextcloud
      - mariadb
      - mail_default
      - traefik_default
    restart: unless-stopped
  redis:
    image: redis:alpine
    restart: unless-stopped
    command: redis-server --requirepass REDACTED
    networks:
      - nextcloud
      - traefik_default
  web:
    build: ./web
    environment:
      - VIRTUAL_HOST=nextcloud.example.com
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_default"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.example.com`)"
      - "traefik.http.routers.nextcloud.tls.certresolver=myresolver"
      - "traefik.http.routers.nextcloud.middlewares=nextcloud_headers,nextcloud_redirect"
      - "traefik.http.middlewares.nextcloud_headers.headers.stsSeconds=155520011"
      - "traefik.http.middlewares.nextcloud_headers.headers.stsIncludeSubdomains=true"
      - "traefik.http.middlewares.nextcloud_headers.headers.stsPreload=true"
      - "traefik.http.middlewares.nextcloud_redirect.redirectregex.regex=/.well-known/(card|cal)dav"
      - "traefik.http.middlewares.nextcloud_redirect.redirectregex.replacement=/remote.php/dav/"
      # watchtower can't auto-update this container because we build it locally
      # see https://containrrr.dev/watchtower/arguments/#without_pulling_new_images
      # and https://containrrr.dev/watchtower/container-selection/
      - "com.centurylinklabs.watchtower.enable=false"
    volumes:
      - docroot:/var/www/html:ro
    networks:
      - nextcloud
      - traefik_default
    restart: unless-stopped
  collabora:
    image: collabora/code
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_default"
      - "traefik.http.routers.collabora.entrypoints=websecure"
      - "traefik.http.routers.collabora.rule=Host(`collabora.example.com`)"
      - "traefik.http.routers.collabora.tls.certresolver=myresolver"
    networks:
      - nextcloud
      - traefik_default
    cap_add:
      - MKNOD
    tty: true
    environment:
      - "extra_params=--o:ssl.enable=false --o:ssl.termination=true"
      - domain=nextcloud\\.example\\.com
      - dictionaries=en
      - username=admin
      - password=REDCATED
    volumes:
      - /collabora/loolwsd.xml:/etc/loolwsd/loolwsd.xml
networks:
  nextcloud:
    name: nextcloud
  mariadb:
    external: true
  mail_default:
    external: true
  traefik_default:
    external: true

web/Dockerfile contains:

FROM nginx:stable-alpine

COPY nginx.conf /etc/nginx/nginx.conf

Thanks!
-Adam

See
https://nextcloud-talk.readthedocs.io/en/latest/system-requirements/#webserver

I switched to Apache. Talk performance seems good now. :ship:

I’m now running my single app container I mentioned earlier from the nextcloud:stable-apache image instead of the combination of app and web containers from the nextcloud:stable-fpm-alpine and nginx:stable-alpine images, respectively. I moved the traefik labels from the web container to the app container, then killed the web container and removed that section.

I did read https://nextcloud-talk.readthedocs.io/en/latest/system-requirements/#webserver , thank you. I was confused because it says “…and Nginx must use…” but I don’t know how to configure mpm for nginx. Maybe those “events” and “prefork” terms only apply to Apache?