GET /users.json is 100x slower than GET /resources.json (Passbolt CE 4.12.1)

Hello.

I have deployed Passbolt in a GCE virtual machine using Docker Compose (YAML is at the bottom of this post).

When I open the Passbolt app in a browser and go to /app/users, the app tries to list the users in our Passbolt instance by doing a GET request to the /users.json endpoint. This request takes about 50 seconds to complete, even though loading resources/passwords via a GET /resources.json endpoint request (when browsing the app/passwords page) takes about 0.5 seconds to complete. I see no high CPU/RAM usage when the VM is processing the GET /users.json request (the CPU usage is about 10 % and RAM usage is about 20 % - the VM has 2 vCPUs and 4 GB of RAM - e2-medium GCE instance).

I see no obvious reason that the GET /users.json endpoint should be 100x slower than the GET /resources.json endpoint. Can anyone help me fix this problem? I am using the latest Community edition Passbolt release (4.12.1), and the latest MariaDB release (11.7.2) as you can see in the Docker Compose YAML.

This is the exact slow request with all GET parameters:

GET /users.json?api-version=v2&contain%5Bprofile%5D=1&contain%5Bgpgkey%5D=0&contain%5Bgroups_users%5D=0&contain%5Bpending_account_recovery_request%5D=1&contain%5Baccount_recovery_user_setting%5D=1&contain%5BLastLoggedIn%5D=1

Sometimes the GET /users.json endpoint is not only slow, but returns a 504 (Gateway Time-out) status code:

passbolt  | 2025/04/09 11:18:13 [error] 124#124: *3525 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 172.19.0.2, server: _, request: "GET /users.json?api-version=v2&contain%5Bprofile%5D=1&contain%5Bgpgkey%5D=0&contain%5Bgroups_users%5D=0&contain%5Bpending_account_recovery_request%5D=1&contain%5Baccount_recovery_user_setting%5D=1&contain%5BLastLoggedIn%5D=1 HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.2-fpm.sock", host: "CENSORED"
passbolt  | 172.19.0.2 - - [09/Apr/2025:11:18:13 +0000] "GET /users.json?api-version=v2&contain%5Bprofile%5D=1&contain%5Bgpgkey%5D=0&contain%5Bgroups_users%5D=0&contain%5Bpending_account_recovery_request%5D=1&contain%5Baccount_recovery_user_setting%5D=1&contain%5BLastLoggedIn%5D=1 HTTP/1.1" 504 562 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/135.0.0.0 Safari/537.36"

docker-compose.yml:

services:
  db:
    container_name: passbolt_db
    image: mariadb@sha256:310d29fbb58169dcddb384b0ff138edb081e2773d6e2eceb976b3668089f2f84 # tag 11.7.2
    env_file:
      - env/mysql.env
    volumes:
      - passbolt_database_volume:/var/lib/mysql
    # ports:
    #   - "127.0.0.1:3306:3306" # Uncomment for direct DB access from the host system
    networks:
      - database
    restart: always

  passbolt:
    container_name: passbolt
    image: passbolt/passbolt@sha256:2de4f7ce60fe05dd77b5d0e03fe7ef5e35fc2dd08b78f578d1064e019f0bc585 # tag latest-ce/4.12.1-1-ce
    tty: true
    depends_on:
      - db
    env_file:
      - env/passbolt.env
      - env/passbolt.secret.env
    volumes:
      - passbolt_gpg_volume:/etc/passbolt/gpg
      - passbolt_images_volume:/usr/share/php/passbolt/webroot/img/public
    command:
      [
        "/usr/bin/wait-for.sh",
        "-t",
        "0",
        "db:3306",
        "--",
        "/docker-entrypoint.sh"
      ]
    networks:
      - reverse_proxy
      - database
    restart: always

  caddy:
    container_name: passbolt_caddy
    image: caddy@sha256:cf1bd22f2415bc99b785ece1df2c49d32985ac4ac42d84df335be17350593693 # tag 2.9.1
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - passbolt_caddy_data:/data
      - passbolt_caddy_config:/config
    networks:
      - reverse_proxy
    restart: always

volumes:  # Must already exist - they are created with the initial_setup.sh script
  passbolt_database_volume:
    external: true
  passbolt_gpg_volume:
    external: true
  passbolt_images_volume:
    external: true
  passbolt_caddy_data:
    external: true
  passbolt_caddy_config:
    external: true

networks:
  default:
    driver: none # Disabling the default network
  reverse_proxy:
  database:

I would appreciate any solutions or debugging options.

Thanks.

Hey @FrantisekN-RevoltBI, welcome to the community forum :waving_hand:

I had a look at the problem you are facing and it’s unusual situation. We would need more info in order to help you debug the issue. Here are the some things we would need from you:

  1. Number of records in the database. Run below SQL queries into your database and share the results with us.

    SELECT COUNT(*) FROM users;
    SELECT COUNT(*) FROM groups;
    SELECT COUNT(*) FROM groups_users;
    SELECT COUNT(*) FROM action_logs;
    
  2. To know which SQL query is slow, you can enable the slow query logs. Here’s the step - https://mariadb.com/kb/en/slow-query-log-overview/

  3. Browser extension logs to know which endpoint is taking time and if any HTTP requests are blocking others. Here’s how you enable the Browser extension logs - https://www.passbolt.com/docs/hosting/troubleshooting/logs/#browser-extension

Regards,
Ishan