Fixes #21231: Cache table existence for ObjectType checks #515

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

Originally created by @pheus on 1/20/2026

Fixes: #21231

Summary

This PR introduces a process-level cache for the core_objecttype table existence check within ObjectTypeManager.get_for_model(), based on the incredible findings of @jetseverschuren-novoserve.

Currently, NetBox performs database introspection on every get_for_model() call to determine if it should fall back to ContentType (a check retained for backward compatibility during v4.4 migrations). This hits pg_catalog.pg_class repeatedly, causing significant performance degradation on data-heavy pages and API endpoints.

Proposed Changes:

  • Added a _table_exists boolean flag to ObjectTypeManager.
  • The manager now performs introspection at most once per worker process.
  • Once the table is detected, the flag is set to True, bypassing all future introspection calls for that process.
  • The logic explicitly avoids caching a False result to ensure safety during active migrations or upgrades.

Performance Impact:
Benchmarks identified by the community show a reduction in lookup time from ~44ms to ~3ms per call in fully migrated environments by eliminating the high-frequency introspection queries.

Testing:
I have verified this solution by successfully migrating an empty v3.7.8 database to the most recent commit in main. The fallback logic correctly handles the pre-migration state and transitions seamlessly once the core_objecttype table is provisioned.

Special thanks to @jetseverschuren-novoserve for identifying this bottleneck and providing the detailed analysis!

*Originally created by @pheus on 1/20/2026* ### Fixes: #21231 ### Summary This PR introduces a process-level cache for the `core_objecttype` table existence check within `ObjectTypeManager.get_for_model()`, based on the incredible findings of `@jetseverschuren-novoserve`. Currently, NetBox performs database introspection on every `get_for_model()` call to determine if it should fall back to `ContentType` (a check retained for backward compatibility during v4.4 migrations). This hits `pg_catalog.pg_class` repeatedly, causing significant performance degradation on data-heavy pages and API endpoints. **Proposed Changes:** - Added a `_table_exists` boolean flag to `ObjectTypeManager`. - The manager now performs introspection at most once per worker process. - Once the table is detected, the flag is set to `True`, bypassing all future introspection calls for that process. - The logic explicitly avoids caching a `False` result to ensure safety during active migrations or upgrades. **Performance Impact:** Benchmarks identified by the community show a reduction in lookup time from ~44ms to ~3ms per call in fully migrated environments by eliminating the high-frequency introspection queries. **Testing:** I have verified this solution by successfully migrating an empty v3.7.8 database to the most recent commit in `main`. The fallback logic correctly handles the pre-migration state and transitions seamlessly once the `core_objecttype` table is provisioned. Special thanks to @jetseverschuren-novoserve for identifying this bottleneck and providing the detailed analysis!
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github/netbox#515