Custom fields with types object and multiobject generate duplicate DB queries #162

Closed
opened 2026-04-05 16:22:32 +02:00 by MrUnknownDE · 0 comments
Owner

Originally created by @miaow2 on 3/12/2026

NetBox Version

v4.5.4

Python Version

3.12

Area(s) of Concern

  • User Interface
  • REST API
  • GraphQL API
  • Python ORM
  • Other

Details

Hi NetBox developers!
In our company, we developed several internal NetBox plugins and added numerous custom fields with types object and multiobject from core NetBox models (particularly from VirtualMachine) to our own. We noticed a significant increase in the load time of the virtual machines API endpoint when retrieving 1000 objects per page. Using the debug toolbar, we discovered that each virtual machine object makes separate database queries for every object custom field. This appears to be an N+1 problem.
If a VirtualMachine model has 10 object custom fields, each VM object will generate an additional 10 DB queries.

How to reproduce it:

  1. create 10 object custom fields to any model for VirtualMachine model (in my test, I added custom fields to Prefix, ClusterType, Device, Tenant, DeviceRole, Interface, Location, Platform, Rack, Region, Role models)
  2. fill those custom fields with data
  3. run NetBox with debug toolbar enabled
  4. make GET request to api/virtualization/virtual-machines/
  5. check SQL in debug tool bar

Screenshots of GET request to api/virtualization/virtual-machines/ with duplicate DB queries. I uploaded only the first several screenshots of the page. In all test requests, I use the default page size of 50 objects.

Image Image Image Image

There are 340 queries in 387.51ms
If you request without custom fields api/virtualization/virtual-machines/?omit=custom_fields, then there will be 16 queries in 50.21ms. This is a very big difference.

Image

I resolved this issue by defining ListSerializer for CustomFieldModelSerializer, which collects all primary keys from custom fields and retrieves them from the database in a single query per model, then caches the results. This approach significantly improves performance by reducing the number of database queries.

With my fix, I have only 43 queries in 70.82ms

Image Image

I would be happy to submit a PR if you accept the issue. I welcome your review, as I am not certain that this is the optimal approach to fixing the problem.

*Originally created by @miaow2 on 3/12/2026* ### NetBox Version v4.5.4 ### Python Version 3.12 ### Area(s) of Concern - [ ] User Interface - [x] REST API - [ ] GraphQL API - [ ] Python ORM - [ ] Other ### Details Hi NetBox developers! In our company, we developed several internal NetBox plugins and added numerous custom fields with types `object` and `multiobject` from core NetBox models (particularly from VirtualMachine) to our own. We noticed a significant increase in the load time of the virtual machines API endpoint when retrieving 1000 objects per page. Using the debug toolbar, we discovered that each virtual machine object makes separate database queries for every object custom field. This appears to be an N+1 problem. If a VirtualMachine model has 10 object custom fields, each VM object will generate an additional 10 DB queries. How to reproduce it: 1. create 10 object custom fields to any model for VirtualMachine model (in my test, I added custom fields to Prefix, ClusterType, Device, Tenant, DeviceRole, Interface, Location, Platform, Rack, Region, Role models) 2. fill those custom fields with data 3. run NetBox with debug toolbar enabled 4. make GET request to `api/virtualization/virtual-machines/` 5. check SQL in debug tool bar Screenshots of GET request to `api/virtualization/virtual-machines/` with duplicate DB queries. I uploaded only the first several screenshots of the page. In all test requests, I use the default page size of 50 objects. <img width="2718" height="1569" alt="Image" src="https://github.com/user-attachments/assets/2c2a9d72-b05a-491e-8513-848b5b1a31f6" /> <img width="2717" height="1499" alt="Image" src="https://github.com/user-attachments/assets/0ec509b3-1890-47a3-b0b0-9a2e776149be" /> <img width="2706" height="1536" alt="Image" src="https://github.com/user-attachments/assets/bd4334cc-7fc7-47d7-a263-595cf8a78cc0" /> <img width="2709" height="1509" alt="Image" src="https://github.com/user-attachments/assets/1f01b754-61bb-4f06-a41f-cab7175893a5" /> There are 340 queries in 387.51ms If you request without custom fields `api/virtualization/virtual-machines/?omit=custom_fields`, then there will be 16 queries in 50.21ms. This is a very big difference. <img width="2723" height="1265" alt="Image" src="https://github.com/user-attachments/assets/66ac0fb8-6534-4006-872b-d96d6a348d6c" /> I resolved this issue by defining `ListSerializer` for [CustomFieldModelSerializer](https://github.com/netbox-community/netbox/blob/main/netbox/netbox/api/serializers/features.py#L17C7-L17C33), which collects all primary keys from custom fields and retrieves them from the database in a single query per model, then caches the results. This approach significantly improves performance by reducing the number of database queries. With my fix, I have only 43 queries in 70.82ms <img width="2709" height="1517" alt="Image" src="https://github.com/user-attachments/assets/a7c0d5aa-c4b8-49c9-b76e-b4e2256897f3" /> <img width="2709" height="1295" alt="Image" src="https://github.com/user-attachments/assets/514c7c00-972f-4d5e-8f1b-423187ee1721" /> I would be happy to submit a PR if you accept the issue. I welcome your review, as I am not certain that this is the optimal approach to fixing the problem.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#162