Skip to content

Optimized api/latest/fleet/software/titles endpoint#40458

Merged
getvictor merged 10 commits intomainfrom
35799-software-titles
Feb 27, 2026
Merged

Optimized api/latest/fleet/software/titles endpoint#40458
getvictor merged 10 commits intomainfrom
35799-software-titles

Conversation

@getvictor
Copy link
Copy Markdown
Member

@getvictor getvictor commented Feb 24, 2026

Related issue: Resolves #35799

Loadtest results for 100K hosts and 300K software titles.

=== Performance Test Results: No team_id (all teams) ===

Description                     Average  Worst    Results
-----------                     -------  -----    -------
Page 0, hosts_count DESC        229ms    241ms    20 items
Page 0, hosts_count ASC         203ms    211ms    20 items
Page 1, hosts_count DESC        339ms    423ms    20 items
Page 1000, hosts_count DESC     202ms    219ms    20 items
100 per_page, hosts_count DESC  620ms    708ms    100 items
Default sort (no order params)  229ms    245ms    20 items
Order by name ASC, page 0       4.642s   4.785s   20 items
Order by name ASC, page 1000    6.418s   6.771s   20 items
Vulnerable only                 3.431s   3.496s   20 items
Search 'chrome'                 9.6s     10.111s  20 items
Known exploit filter            9.792s   10.102s  20 items
Min CVSS score 7.0              12.368s  12.665s  20 items
CVSS range 7.0-9.0              12.221s  12.523s  20 items
Available for install           87ms     93ms     NO RESULTS
Self-service only               4.46s    4.757s   20 items

=== Performance Test Results: team_id=0 (no team / unassigned) ===

Description                     Average  Worst    Results
-----------                     -------  -----    -------
Page 0, hosts_count DESC        378ms    404ms    20 items
Page 0, hosts_count ASC         339ms    345ms    20 items
Page 1, hosts_count DESC        478ms    513ms    20 items
Page 1000, hosts_count DESC     398ms    417ms    20 items
100 per_page, hosts_count DESC  864ms    1.025s   100 items
Default sort (no order params)  399ms    411ms    20 items
Order by name ASC, page 0       5.346s   5.41s    20 items
Order by name ASC, page 1000    7.444s   7.615s   20 items
Search 'chrome'                 9.051s   9.245s   20 items
Known exploit filter            10.511s  10.884s  20 items
Min CVSS score 7.0              16.589s  16.701s  20 items
CVSS range 7.0-9.0              15.878s  15.999s  20 items
Available for install           1.394s   1.429s   1 items
Self-service only               1.4s     1.456s   1 items

Documented in the issue:
The fix includes a small behavior change. The default primary sort of /software/titles remains host_counts, but the secondary sort is now software_title_id and not name. This was necessary to optimize the endpoint. This means that if you have 1 host in your fleet, the software page will not show the software titles ordered by name anymore. For large fleets, this does not matter since all titles generally have different host counts.

Checklist for submitter

  • Changes file added for user-visible changes in changes/, orbit/changes/ or ee/fleetd-chrome/changes.

Testing

  • Added/updated automated tests
  • QA'd all new/changed functionality manually

Database migrations

  • Checked schema for all modified table for columns that will auto-update timestamps during migration.

Summary by CodeRabbit

  • Refactor
    • Optimized the software titles endpoint for improved query performance and faster data retrieval.
    • Enhanced database efficiency when retrieving software information, resulting in better overall system responsiveness and reduced query times.

@getvictor
Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes the /api/latest/fleet/software/titles endpoint to address severe performance issues (queries taking 40+ seconds at scale with 300K software titles and 95K hosts). The optimization introduces a two-phase query strategy for the common case of listing titles ordered by hosts_count without additional filters.

Changes:

  • Introduces an optimized query path that uses a covering index scan followed by enrichment of only the paginated results
  • Parallelizes list and count queries using errgroup to further improve performance
  • Refactors shared post-processing logic into a dedicated function
  • Updates the database index on software_titles_host_counts to include global_stats for better query optimization

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
server/datastore/mysql/software_titles.go Implements two-phase optimized query path with covering index scan, parallel list/count queries using errgroup, and refactored post-processing logic
server/datastore/mysql/migrations/tables/20260225000000_OptimizeSoftwareTitlesHostCountsIndex.go Database migration to replace index with optimized version including global_stats column
server/datastore/mysql/schema.sql Schema updates reflecting new index and migration counter
changes/35799-software-titles User-facing changelog entry

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 24, 2026

Walkthrough

This PR optimizes the /api/latest/fleet/software/titles endpoint by introducing a two-phase query path for listing software titles under specific conditions. A new covering index is created on the software_titles_host_counts table with columns (team_id, global_stats, hosts_count, software_title_id) to replace the existing non-covering index. The datastore code refactors post-processing logic into a shared function, adds parallelized query execution using errgroup, and implements an optimized path gate to determine when the fast-path queries are viable. Existing behavior is maintained for non-optimized cases.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Optimized api/latest/fleet/software/titles endpoint' clearly describes the main change—optimizing a specific API endpoint—which aligns with the PR's primary objective.
Linked Issues check ✅ Passed The PR code changes directly address issue #35799 by introducing query optimization via index changes, a new migration, and a two-phase query optimization path in the software titles endpoint implementation.
Out of Scope Changes check ✅ Passed All file changes are within scope: a changes file for the issue, a database migration for the index optimization, schema.sql updates documenting the index change, and software_titles.go implementation of the optimized query path.
Description check ✅ Passed PR description includes related issue reference, changes file checklist confirmation, testing verification, and database migration checks, but lacks detail on input validation, backwards compatibility verification, and host isolation testing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 35799-software-titles

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/datastore/mysql/software_titles.go`:
- Around line 273-289: The count query is using mutated pagination arguments
because appendListOptionsWithCursorToSQL modifies getTitlesStmt and appends to
args; fix by creating the count SQL and its own args before mutating args—for
example, capture getTitlesCountStmt and a copy of args (e.g., countArgs :=
append([]interface{}{}, args...)) prior to calling
appendListOptionsWithCursorToSQL and spliceSecondaryOrderBySoftwareTitlesSQL,
then use countArgs with sqlx.GetContext for the count goroutine while using the
mutated getTitlesStmt and args for sqlx.SelectContext; update references to
getTitlesStmt, getTitlesCountStmt, args, and the two goroutines to use the
separate arg slices.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01f61b9 and d5a1158.

📒 Files selected for processing (4)
  • changes/35799-software-titles
  • server/datastore/mysql/migrations/tables/20260225000000_OptimizeSoftwareTitlesHostCountsIndex.go
  • server/datastore/mysql/schema.sql
  • server/datastore/mysql/software_titles.go

Comment thread server/datastore/mysql/software_titles.go
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 25, 2026

Codecov Report

❌ Patch coverage is 87.01923% with 27 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.24%. Comparing base (a449381) to head (17382aa).
⚠️ Report is 31 commits behind head on main.

Files with missing lines Patch % Lines
server/datastore/mysql/software_titles.go 88.94% 10 Missing and 11 partials ⚠️
...226182000_OptimizeSoftwareTitlesHostCountsIndex.go 66.66% 4 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #40458      +/-   ##
==========================================
- Coverage   66.29%   66.24%   -0.05%     
==========================================
  Files        2467     2467              
  Lines      197538   197561      +23     
  Branches     8618     8585      -33     
==========================================
- Hits       130952   130875      -77     
- Misses      54736    54808      +72     
- Partials    11850    11878      +28     
Flag Coverage Δ
backend 68.11% <87.01%> (-0.07%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@getvictor getvictor marked this pull request as ready for review February 27, 2026 17:10
@getvictor getvictor requested a review from a team as a code owner February 27, 2026 17:10
@getvictor getvictor assigned mostlikelee and ksykulev and unassigned mostlikelee Feb 27, 2026
@getvictor getvictor merged commit 7107b1f into main Feb 27, 2026
51 checks passed
@getvictor getvictor deleted the 35799-software-titles branch February 27, 2026 20:30
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.

Improve software endpoint performance (Software titles page)

5 participants