Understanding Deletion Strategy Behavior in Discovery. Summary<!-- /*NS Branding Styles*/ --> .ns-kb-css-body-editor-container { p { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } span { font-size: 12pt; font-family: Lato; color: var(--now-color--text-primary, #000000); } h2 { font-size: 24pt; font-family: Lato; color: var(--now-color--text-primary, black); } h3 { font-size: 18pt; font-family: Lato; color: var(--now-color--text-primary, black); } h4 { font-size: 14pt; font-family: Lato; color: var(--now-color--text-primary, black); } a { font-size: 12pt; font-family: Lato; color: var(--now-color--link-primary, #00718F); } a:hover { font-size: 12pt; color: var(--now-color--link-primary, #024F69); } a:target { font-size: 12pt; color: var(--now-color--link-primary, #032D42); } a:visited { font-size: 12pt; color: var(--now-color--link-primary, #00718f); } ul { font-size: 12pt; font-family: Lato; } li { font-size: 12pt; font-family: Lato; } img { display: ; max-width: ; width: ; height: ; } } In ServiceNow Discovery, the deletion strategy defines how Configuration Items (CIs) and their related records are handled when Discovery determines that a CI is stale or has not been updated during a discovery cycle. This KB explains the different deletion strategies, how related entries such as key–value tags are identified, how the system handles stale versus non-stale CIs, and why duplicates in related entries (e.g., cmdb_key_value) can occur when the Keep strategy is applied to any CI type. Where Deletion Strategies Are Stored? In Discovery, deletion strategies are stored and applied through different ServiceNow tables, depending on the discovery method and CI type: Script-based Discovery → Stored in the sa_ci_to_pattern table.Snapshot-based Discovery → Uses the sa_payload_snapshot table, which stores the Identification Engine (IE) output payload for the main CI. How to Identify Snapshot-based Deletion Strategy To determine if a CI type uses snapshot-based deletion: Navigate to the sa_ci_to_pattern table.Locate the record for the CI type and pattern.If the Strategy Script field is empty, the deletion strategy is managed via snapshot-based discovery. After Discovery, a snapshot is saved in sa_payload_snapshot, capturing: cmdb_ci → sys_id of the main CIpattern → sys_id of the executed patternie_output → JSON containing discovered items and relationships If the CI is later missing, the IE consults this snapshot to determine cleanup: Delete → Removes the CI and all related entries listed in the snapshotMark as Retired → Retires the CI but preserves the snapshotKeep → Preserves the CI; related entries may remain, possibly creating duplicates Since this article focuses on script-based deletion, particularly on how related entries (such as cmdb_key_value) are cleaned up, please see the details below. Sample Pattern : Azure - Virtual Machine (LP)Deletion strategy : AzureDefaultDeleteStrategyVMAbstractDeleteStrategy Related Entries in Discovery : Many CIs have related records stored in other tables. Examples: Key–Value tags → cmdb_key_value for VM Instances. To determine which related records belong to a CI class, Discovery uses the cmdb_related_entry table.https://instance.service-now.com/cmdb_related_entry_list.do?sysparm_query=&sysparm_first_row=1&sysparm_view= How related entries are found : In the backend, the function _findRelatedEntries(ciClass) queries cmdb_related_entry (joined with cmdb_identifier) to retrieve: table → name of the related table (e.g., cmdb_key_value)referenced_field → field linking the record back to the CI (e.g., cmdb_ci) This mapping ensures Discovery knows exactly which related tables to evaluate for cleanup. Stale vs. Non-Stale CIs :1. Stale CIs A CI is stale if it was not updated in the latest discovery cycle (sys_updated_on < schedule start time). Discovery locates all related entries for that CI using cmdb_related_entry.Depending on the deletion strategy: Delete CI → CI and related entries are deleted.Mark as Retired → CI status is updated (operational status = 6, install status = 7), stale related entries are deleted.Mark as Absent → CI is retained but marked absent, related entries are deleted. Result: Stale CIs are removed or marked, and stale related records are cleaned up. 2. Non-Stale CIs A CI is non-stale if it was updated during the latest discovery cycle (sys_updated_on > schedule start time). The CI itself remains active.Related entries are still evaluated: _reconcileRelatedEntriesUsingRelations calls _findAndDeleteStaleRelatedEntriesOfCIs.Old related entries (e.g., outdated key–value pairs) are identified via _detectStaleRecordsInList.These stale related entries are deleted from child tables such as cmdb_key_value. Result: Non-stale CIs are preserved, but their stale related entries are cleaned up. Behavior with Keep Strategy : Customers may choose not to mark a CI as Retired, Absent, or Deleted and instead set the deletion strategy to Keep, it is important to understand its impact on both the CI and its related entries: The CI itself is always preserved.Related-entry cleanup does not occur because when the deletion strategy is set to Keep, the deletion process is not triggered at all.As a result, outdated related entries (for example, old cmdb_key_value records) may remain alongside new ones, creating duplicates. This behavior explains why switching from Mark as Retired to Keep can lead to duplicates in this case key–value entries. Batch Deletion Logic for Related Entries : (See the logic: CustomDeletionStrategyUtils) : Triggering batch deletion: When a CI has related entries (e.g., cmdb_key_value) exceeding the configured threshold (glide.discovery.delete_strategy.max_deletion_records, default 2000), the deletion process uses batching to avoid system overload.Batch processing mechanism: Non-stale CIs are grouped into batches of maxCIsInSearchGroup (default 100).For each batch, the function _findAndDeleteStaleRelatedEntriesOfCIs is called to delete stale related entries.The process tracks the total number of deleted entries using staleRelatedEntriesOfCIsDeletedCnt. Stopping condition: If staleRelatedEntriesOfCIsDeletedCnt exceeds 5 * _limit (i.e., 10,000 by default if _limit = 2000), the batch deletion halts to prevent excessive load. Example: Suppose a CI has 12,000 stale cmdb_key_value entries.The deletion engine will process 2000 entries per batch and stop after deleting 10,000 in this run.The remaining 2,000 entries will be handled in the next iteration or discovery cycle.