Nextcloud Talk performance - how to troubleshoot or work around

I鈥檓 having some performance issues with the Talk app in my Nextcloud instance. I鈥檓 new to Nextcloud, I just recently got it running for my small team of 4. I鈥檝e 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鈥檓 looking for help digging into what might be causing the performance issues. I鈥檝e tried the obvious things like running top on the host and tailing logs, but I haven鈥檛 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鈥檛 want/need to use Talk to make voice or video calls. I really just want the text chat.

I鈥檓 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鈥檚 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 鈥淎ll 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鈥檓 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 鈥溾nd Nginx must use鈥︹ but I don鈥檛 know how to configure mpm for nginx. Maybe those 鈥渆vents鈥 and 鈥減refork鈥 terms only apply to Apache?