[9.4] [Security Solution] Make kbn-openapi-generator producing lazy loaded Zod schemas (#264125)#265139
Merged
maximpn merged 1 commit intoelastic:9.4from Apr 22, 2026
Merged
Conversation
…Zod schemas (elastic#264125) ## Summary Reduces the baseline heap footprint of the many generated Zod schemas (OpenAPI `*.gen.ts` files) by deferring their construction until first use, and letting the GC reclaim materialized schemas once no consumer is holding on to them. Generated schemas are declared at module-load time but only a subset is actually exercised at runtime, so materializing all of them eagerly wastes memory — and pinning them for the process lifetime wastes memory even for schemas used once. ## Changes - Add `lazySchema(factory)` in `@kbn/zod/v4` — a Zod-typed wrapper around `lazyGCableObject` used by generated schemas. Unused schemas stay as a single Proxy + closure; transiently-used schemas are collectible after their last reference is dropped. - Update the `zod_operation_schema.handlebars` template in `@kbn/openapi-generator` so generated request/response/params/body schemas and named component schemas are wrapped in `lazySchema(() => …)`. Caveat documented on the helper: `instanceof z.ZodType` on a lazy schema is `false` because the Proxy target is an empty object. Zod internals and typical consumers use structural `_zod` / `.def` checks rather than `instanceof`, so this is safe in practice. ## Feature flag Lazy loaded Zod schemas have been smoke tested and there aren't noticeable performance degradations revealed. Anyway `disableLazyZodSchemas` feature flag has been added to have an ability to disable this optimization. After applying the changes **Kibana restart is required**. To make the optimization disabled add the following to the Kibana config ```yaml feature_flags: overrides: disableLazyZodSchemas: true ``` ### Identify risks - Consumers that rely on `instanceof z.ZodType` / `instanceof z.ZodObject` against a generated schema will see `false`. Mitigation: Zod and common helpers use structural checks (`_zod`, `.def`) rather than `instanceof`, and this is called out in the helper JSDoc. Reviewers should flag any `instanceof` usage against generated schemas. - First-access and rebuild cost: the first property access on a previously unused schema materializes it. Because the cache is a `WeakRef`, if the materialized schema is reclaimed between uses (only possible once the caller has dropped its reference), the next access rebuilds it from the factory — so repeatedly re-materializing the same schema across GC cycles adds overhead. Hot paths should retain a reference (e.g. `const s = Schema; s.parse(...)`) for the duration of their work. - Large surface change in regenerated `*.gen.ts` files — regeneration is mechanical from the updated handlebars template. Part of elastic#264170 (cherry picked from commit c9fbbf4) # Conflicts: # packages/kbn-optimizer/limits.yml # x-pack/platform/plugins/shared/cases/common/bundled-types.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/live_query/create_live_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/live_query/find_live_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/live_query/get_live_query_results.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/live_query/live_queries.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/model/schema/common_attributes.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/packs/copy_pack.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/packs/create_pack.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/packs/find_packs.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/packs/packs.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/packs/update_packs.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/saved_query/copy_saved_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/saved_query/create_saved_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/saved_query/find_saved_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/saved_query/saved_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/saved_query/update_saved_query.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/scheduled_results/scheduled_results.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/unified_history/get_unified_history.gen.ts # x-pack/platform/plugins/shared/osquery/common/api/unified_history/unified_history.gen.ts # x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/find_endpoint_list_item/find_endpoint_list_item.gen.ts # x-pack/solutions/security/packages/kbn-securitysolution-endpoint-exceptions-common/api/update_endpoint_list_item/update_endpoint_list_item.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/detection_engine/model/rule_response_actions/response_actions.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_download/file_download.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/file_info/file_info.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/list/list.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/execute/execute.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/get_file/get_file.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/isolate/isolate.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/kill_process/kill_process.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/run_script/run_script.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/running_procs/running_procs.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/scan/scan.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/suspend_process/suspend_process.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/unisolate/unisolate.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/response_actions/upload/upload.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/state/state.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/actions/status/status.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/model/schema/common.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/policy/policy_response.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/endpoint/protection_updates_note/protection_updates_note.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/timeline/copy_timeline/copy_timeline_route.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/timeline/delete_timelines/delete_timelines_route.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_draft_timelines/get_draft_timelines_route.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timeline/get_timeline_route.gen.ts # x-pack/solutions/security/plugins/security_solution/common/api/timeline/get_timelines/get_timelines_route.gen.ts
jbudz
approved these changes
Apr 22, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Backport
This will backport the following commits from
mainto9.4:Questions ?
Please refer to the Backport tool documentation