feat: optimize project list external endpoint#7869
Conversation
WalkthroughThe queryset in ProjectListCreateAPIEndpoint.get_queryset was modified to reduce select_related preloading from multiple relations ("workspace", "workspace__owner", "default_assignee", "project_lead") to only "project_lead". No other logic or public interfaces were changed. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant API as ProjectListCreateAPIEndpoint
participant ORM as ORM/DB
C->>API: GET /projects
API->>ORM: Query Projects<br/>select_related("project_lead")
Note right of ORM: Previously also selected<br/>"workspace", "workspace__owner",<br/>"default_assignee"
ORM-->>API: Project rows + joined project_lead
API-->>C: Response with projects
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this comment.
Pull Request Overview
This PR optimizes the external projects list endpoint by reducing the number of database joins in the project queryset. The change removes unnecessary select_related fields to improve query performance.
- Removes unnecessary database joins from the project queryset
- Maintains only the essential
project_leadrelationship - Improves performance for external project list endpoints
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/api/plane/api/views/project.py(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Lint API
- GitHub Check: Analyze (javascript)
| | Q(network=2) | ||
| ) | ||
| .select_related("workspace", "workspace__owner", "default_assignee", "project_lead") | ||
| .select_related("project_lead") |
There was a problem hiding this comment.
Reintroduce eager loading for workspace/default_assignee to avoid N+1 queries
With this change the list endpoint stops preloading workspace, workspace__owner, and default_assignee. Any client that uses the documented expand parameter (or the serializer’s default fields) now triggers one extra query per project for each of those relations, undoing the optimization we previously had. That’s a significant performance regression for a list API that can easily return dozens of projects. Please keep those relations in select_related (or replace them with an equivalent prefetch strategy) so the endpoint remains O(1) queries.
- .select_related("project_lead")
+ .select_related("workspace", "workspace__owner", "default_assignee", "project_lead")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| .select_related("project_lead") | |
| .select_related("workspace", "workspace__owner", "default_assignee", "project_lead") |
🤖 Prompt for AI Agents
In apps/api/plane/api/views/project.py around line 82, the query no longer
eager-loads workspace, workspace__owner, and default_assignee which causes N+1
queries on the list endpoint; restore those relations to the queryset (e.g. add
them back into select_related or use an equivalent prefetch_related for
m2m/lookups) so the endpoint remains O(1) queries when returning many projects,
ensuring workspace, workspace__owner, and default_assignee are included in the
eager-loading set.
Description
Type of Change
Summary by CodeRabbit