After upgrading from OJS 3.4 to 3.5.0-4, several journal managers have reported that the user search feature in the admin panel became noticeably slow — in some cases, taking over five minutes to return results or timing out completely. If your installation has a large user database, the problem is even more pronounced.
One forum user documented PHP-FPM logs showing multiple child processes timing out after more than 300 seconds on simple user search queries. Role-based searches sometimes returned no results at all, and the “Invite to a Role” workflow became nearly unusable.
Important note on scope: The diagnostic steps below cover the most likely causes based on the symptoms reported and how OJS 3.5 handles user queries internally. However, no confirmed resolution has been posted in the source forum thread — nobody has reported back saying “I did X and the problem went away.” Some installations may need deeper investigation beyond what is covered here. Treat these steps as a structured troubleshooting path, not a guaranteed fix.
Table of Contents
What Causes Slow User Search in OJS 3.5

OJS 3.5 introduced changes to how the system handles user queries behind the scenes. When the user table grows beyond a few thousand records, several bottlenecks can emerge at once.
The first culprit is missing or inefficient database indexes. OJS relies on MySQL or PostgreSQL to match search phrases against user fields like username, email, first_name, and last_name. Without proper indexes on these columns — and on the join tables that map users to roles — the database engine must perform full table scans. On an installation with tens of thousands of users, a full scan can take minutes even on decent hardware.
The second factor is the includePermissions=true parameter that OJS appends to search requests in the admin user grid. This flag forces the system to load permission data for every matching user in the result set. When combined with unindexed role joins, it multiplies the query cost.
A third contributing factor is PHP execution limits. The default max_execution_time in many PHP-FPM configurations is set to 30 seconds. When the database query runs longer than that, PHP kills the worker — but only after the operating system has already spent resources on a doomed request. If your PHP log shows entries like “execution timed out” with times exceeding 300 seconds, the database query is running far past any reasonable threshold.
Finally, server resources play a role. Large result sets consume memory, and if PHP’s memory_limit is too low, the process may swap or crash. On shared hosting or VPS environments with limited RAM, this compounds every other problem.
A separate concern worth noting: the “zero results” symptom — where role-based searches return no users at all, especially with includePermissions=true in the URL — may not be a performance issue at all. It could point to a query construction bug in OJS 3.5.x that skips valid results under certain role-permission combinations. If your searches are fast but empty, check the OJS 3.5.x changelog and PKP GitHub issues for related fixes, as this behavior may need a code patch rather than server tuning.

Step 1: Check and Add Database Indexes for User Search
The most effective place to start is verifying that the users table and its related tables have proper indexes. Start by examining the current indexes on your database.
For MySQL or MariaDB, connect to your OJS database and run:
SHOW INDEX FROM users;
SHOW INDEX FROM user_user_groups;
SHOW INDEX FROM user_groups;
Look for indexes on these columns:
users.emailusers.usernameusers.first_nameusers.last_nameuser_user_groups.user_iduser_user_groups.user_group_id
If any are missing, add them:
ALTER TABLE users ADD INDEX idx_users_email (email);
ALTER TABLE users ADD INDEX idx_users_username (username);
ALTER TABLE users ADD FULLTEXT idx_users_name (first_name, last_name);
ALTER TABLE user_user_groups ADD INDEX idx_uug_user_id (user_id);
ALTER TABLE user_user_groups ADD INDEX idx_uug_user_group_id (user_group_id);
The FULLTEXT index on first_name and last_name is especially important — OJS 3.5 uses LIKE '%phrase%' patterns for name searches, and a standard B-tree index does not help with leading-wildcard queries. A full-text index allows the database to use its built-in text search engine instead of scanning every row.
After adding indexes, test the search again. On a database with 50,000 users, proper indexing alone can reduce search time from minutes to under a second.
Step 2: Review and Adjust PHP-FPM Configuration
If the database is returning results quickly but PHP is still timing out, the issue is in the PHP layer. Check your PHP-FPM pool configuration — typically at /etc/php/8.x/fpm/pool.d/www.conf or a custom pool file.
Review these settings:
max_execution_time = 120
memory_limit = 512M
request_terminate_timeout = 120
The max_execution_time should be set high enough to accommodate the largest reasonable search. 120 seconds is a practical ceiling for a user search — anything longer indicates the database layer needs attention, not PHP. If you previously had it at 30 seconds, a user search on a large install may have been killed prematurely even when the database was performing adequately.
The memory_limit should reflect the size of your user base. As a rough guideline, allocate at least 256 MB for journals with under 10,000 users, and 512 MB or more for larger installations. OJS loads user objects into memory during search, and insufficient memory triggers out-of-memory errors that can look like timeouts.
After changing PHP configuration, restart PHP-FPM:
sudo systemctl restart php8.2-fpm
Step 3: Check and Configure Caching
OJS 3.5 supports multiple caching backends. A properly configured cache can reduce the load on the database during repeated searches.
In your config.inc.php file, check the cache settings:
[cache]
driver = redis
If you have Redis available, switching the cache driver from file to redis reduces disk I/O and speeds up repeated lookups of user roles and permissions. Install the Redis PHP extension and point the configuration to your Redis instance:
[cache]
driver = redis
host = 127.0.0.1
port = 6379
For environments where Redis is not available, the file-based cache is acceptable but should reside on fast storage, preferably an SSD.
Also enable OJS’s built-in data cache by setting:
cache = On
This caches frequently accessed configuration, plugin data, and locale files, freeing resources for the actual search queries.
Step 4: Monitor and Tune MySQL Configuration
If the above steps improve but do not fully resolve the issue, look at MySQL’s own configuration. The innodb_buffer_pool_size parameter controls how much data MySQL keeps in memory. For a database-heavy workload like OJS, this should be set to 50-70% of the server’s available RAM.
Check your current setting:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
On a server with 8 GB of RAM running only OJS and the database, a setting of 4-5 GB is reasonable:
[mysqld]
innodb_buffer_pool_size = 4G
Also check the slow query log to identify exactly which queries are taking the most time:
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 2;
After running a few searches, examine the slow query log (typically /var/log/mysql/slow.log) to see if there are any remaining unindexed queries. Each entry in the log is a candidate for a new index or query optimization.
Preventing the Problem on Future Upgrades
The user search slowdown after upgrading from OJS 3.4 to 3.5 highlights a broader point: major version upgrades can change how database queries are structured. Before upgrading a production OJS installation, run the new version on a staging copy of your database and profile the most common operations — user search, submission listing, and editorial workflow queries.

If you maintain your OJS installation with a theme from Open Journal Theme, the theme’s lightweight structure does not add overhead to admin-side operations like user search. However, the database and server configuration steps in this article apply regardless of which front-end theme you use.
When to Seek Additional Help
If you have applied the steps above and user search is still unacceptably slow, consider these next actions:
- Check the PKP Community Forum: The issue discussed in this article originated from a forum thread where multiple users reported similar symptoms after upgrading to 3.5.0-4. Monitor that thread or related GitHub issues for official patches.
- Review the OJS release notes: Subsequent OJS 3.5.x releases may include query optimizations that address this problem at the application level.
- Consult a server administrator: A professional review of your MySQL or PostgreSQL configuration, PHP-FPM tuning, and server resource allocation can uncover bottlenecks that generic advice misses.
For journals that want a professionally maintained OJS installation with optimized performance out of the box, Open Journal Theme provides managed OJS hosting and configuration services that handle database indexing, caching, and server tuning as part of the setup.
This article was written based on a real performance issue reported by OJS users on the PKP Community Forum. All configuration recommendations reference standard OJS 3.5 documentation and widely accepted MySQL/PHP optimization practices. The diagnostic steps above are the most likely starting points based on reported symptoms; individual installations may require additional investigation.
