Skip to content

FOUR-31892: Optimize Tasks API index endpoint query performance#8881

Open
AugustoLopezProcess wants to merge 5 commits into
feature/FOUR-30918from
feature/FOUR-31892
Open

FOUR-31892: Optimize Tasks API index endpoint query performance#8881
AugustoLopezProcess wants to merge 5 commits into
feature/FOUR-30918from
feature/FOUR-31892

Conversation

@AugustoLopezProcess

@AugustoLopezProcess AugustoLopezProcess commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Issue & Reproduction Steps

The Tasks list API (GET /api/1.0/tasks) is slow on instances with a large number of tasks, especially when the inbox uses the non_system=true filter and eager-loads related models (processRequest, process, user, draft, etc.).
How to reproduce:

  1. Use an instance with a large task volume (or seed many process_request_tokens records).
  2. Log in as a user with tasks in their inbox.
  3. Open the Tasks/Inbox page, or call the API directly:
GET /api/1.0/tasks?non_system=true&include=processRequest,process,user,draft&status=ACTIVE&per_page=15
  1. Observe slow response times and/or high query count. The nonSystem filter uses whereHas('process.categories'), which triggers expensive Process global scopes. The base query also loads heavy JSON columns (data, self_service_groups, token_properties) and over-fetches relation columns.

Solution

  • Added indexOptimized() to the API v1.1 TaskController, reusing existing index filtering logic with an optimized query path.
  • Added indexOptimizedBaseQuery() and applyIndexFieldSelection() to:
  • Eager-load only requested include relations with minimal column selection.
  • Exclude heavy JSON columns by default when no explicit fields/columns are provided.
  • Map UI columns to the minimum DB fields needed.
  • Updated scopeNonSystem() on ProcessRequestToken to accept an $optimized flag; when enabled, uses a direct EXISTS subquery instead of whereHas('process.categories'), avoiding Process global scopes.
  • Wired the optimized nonSystem path through excludeNonVisibleTasks() via an optimized request flag.
  • Added a dedicated v1.1 route: GET /api/1.1/tasks/tasksOptimized.
  • Added OPTIMIZED_TASKS_ENABLED config (config/app.php, default true); when enabled, the standard v1.0 TaskController::index() delegates to the optimized implementation.

How to Test

  1. Ensure OPTIMIZED_TASKS_ENABLED=true in .env (or omit it to use the default).
  2. Log in and open Tasks / Inbox — confirm tasks load, filters work, columns render, and saved searches behave as before.
  3. Compare API performance before/after (or with the flag toggled):
  • Optimized (default): GET /api/1.0/tasks?non_system=true&include=processRequest,process,user,draft&status=ACTIVE
  • Explicit v1.1 endpoint: GET /api/1.1/tasks/tasksOptimized (same query params)
  • Legacy path: set OPTIMIZED_TASKS_ENABLED=false, clear config cache, repeat the v1.0 call
  1. Verify non_system=true still excludes system-category processes in both paths.
  2. Test edge cases: PMQL filters, processesIManage=true, overdue filter, pagination, and column/field selection via columns or fields params.
  3. Confirm response payload shape matches expectations for the Tasks UI and any consumers (Saved Search counts, etc.).

Related Tickets & Packages

Code Review Checklist

  • I have pulled this code locally and tested it on my instance, along with any associated packages.
  • This code adheres to ProcessMaker Coding Guidelines.
  • This code includes a unit test or an E2E test that tests its functionality, or is covered by an existing test.
  • This solution fixes the bug reported in the original ticket.
  • This solution does not alter the expected output of a component in a way that would break existing Processes.
  • This solution does not implement any breaking changes that would invalidate documentation or cause existing Processes to fail.
  • This solution has been tested with enterprise packages that rely on its functionality and does not introduce bugs in those packages.
  • This code does not duplicate functionality that already exists in the framework or in ProcessMaker.
  • This ticket conforms to the PRD associated with this part of ProcessMaker.

@processmaker-sonarqube

Copy link
Copy Markdown

Quality Gate passed Quality Gate passed

Issues
0 New issues
0 Accepted issues

Measures
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarQube

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants