You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Learn about the ghost cleanup process, a background process that physically removes rows that are marked for deletion from data pages.
4
+
author: MashaMSFT
5
+
ms.author: mathoma
6
+
ms.reviewer: dfurman, randolphwest
7
+
ms.date: 12/08/2025
8
+
ms.service: sql
9
+
ms.subservice: supportability
10
+
ms.topic: concept-article
11
+
helpviewer_keywords:
12
+
- "ghost cleanup"
13
+
- "ghost rows"
14
+
- "ghost clean up process"
15
+
---
16
+
17
+
# Ghost cleanup process guide
18
+
19
+
Ghost cleanup is a background process that physically removes the rows that were marked for deletion by DML statements. The following article provides an overview of this process.
20
+
21
+
## Ghost rows
22
+
23
+
Rows that are deleted from the leaf level pages of an index aren't physically removed from the page. Instead, the row is marked for future removal, or *ghosted*. This means that the row stays on the page but a bit is changed in the row header to indicate that the row is a ghost. This is to optimize performance during a delete operation. Ghosts are necessary for row-level locking and for snapshot isolation transactions where the database engine must maintain older row versions.
24
+
25
+
## Ghost cleanup task
26
+
27
+
Rows that are marked for deletion, or *ghosted*, are cleaned up by the background ghost cleanup process when they're no longer required. Ghost cleanup runs periodically and checks to see if any pages have ghosted rows. If it finds any, it physically removes these rows. There's a single ghost cleanup thread for all databases on a [!INCLUDE [ssde-md](../includes/ssde-md.md)] instance.
28
+
29
+
When a row is ghosted, the database is marked as having ghosted entries. The ghost cleanup process only scans such databases. The ghost cleanup process also marks the database as having no ghosted rows once all ghosted rows are removed, and skips this database the next time it runs. The process also skips any database if it can't acquire a shared lock on the database. It retries lock acquisition on the database the next time it runs.
30
+
31
+
The following query returns an approximate number of ghosted rows in a database.
32
+
33
+
```sql
34
+
SELECTSUM(ghost_record_count) AS total_ghost_records,
In high-load systems with many deletes, the ghost cleanup process might reduce performance if it replaces many of the frequently accessed pages in the buffer pool with other pages that have ghosted rows. As a result, the frequently accessed pages must be re-read from disk, generating extra disk I/O and increasing query latency. If this occurs, you can disable ghost cleanup using [trace flag 661](../t-sql/database-console-commands/dbcc-traceon-trace-flags-transact-sql.md#tf661).
44
+
45
+
Without ghost cleanup, your database can grow unnecessarily large, which can also reduce performance due to extra I/O and memory consumption. Since the ghost cleanup process removes rows that are marked as ghosts, disabling the process leaves these rows on the page, preventing the database engine from reusing this space. This forces the database engine to add data to new pages instead, leading to bloated database files, and can also cause [page splits](indexes/specify-fill-factor-for-an-index.md). Page splits increase disk I/O, which can reduce query performance. If ghost cleanup is disabled, the database might run out of space.
46
+
47
+
> [!WARNING]
48
+
> Disabling the ghost cleanup process permanently isn't recommended.
49
+
50
+
To remove ghost rows when ghost cleanup is disabled, rebuild indexes on tables where rows were deleted. Rebuilding an index creates new pages from existing data, omitting ghosted rows in the process.
51
+
52
+
## Related content
53
+
54
+
-[Pages and extents architecture guide](pages-and-extents-architecture-guide.md)
Removes residual information left on database pages because of data modification routines in [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)]. `sp_clean_db_file_free_space` cleans all pages in only one file of a database.
25
+
Removes residual information on data pages. `sp_clean_db_file_free_space` cleans all pages in only one file of a database.
@@ -47,21 +48,21 @@ The data file ID to clean. *@fileid* is **int**, with no default.
47
48
48
49
#### [ @cleaning_delay = ]*cleaning_delay*
49
50
50
-
Specifies an interval to delay between the cleaning of pages. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the effect on the I/O system.
51
+
Specifies an interval to delay before the cleanup of each page, in seconds. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system at the expense of increasing the duration of the cleanup process.
51
52
52
53
## Return code values
53
54
54
55
`0` (success) or `1` (failure).
55
56
56
57
## Remarks
57
58
58
-
Deletes operations from a table or update operations that cause a row to move can immediately free up space on a page by removing references to the row. However, under certain circumstances, the row can physically remain on the data page as a ghost record. A background process periodically removes ghost records. This residual data isn't returned by the [!INCLUDE [ssDE](../../includes/ssde-md.md)] in response to queries. However, in environments in which the physical security of the data or backup files is at risk, you can use `sp_clean_db_file_free_space` to clean these ghost records. To perform this operation for all database files at once, use [sp_clean_db_free_space](sp-clean-db-free-space-transact-sql.md).
59
+
The `sp_clean_db_file_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page, and then zero-initializes the remainder of the data space on the page. In environments where the physical security of the data files or the underlying storage is at risk, you can use this stored procedure to ensure that no residual deleted data remains in the data files or in storage.
59
60
60
-
The length of time required to run `sp_clean_db_file_free_space` depends on the size of the file, the available free space, and the capacity of the disk. Because running `sp_clean_db_file_free_space` can significantly affect I/O activity, we recommend that you run this procedure outside usual operation hours.
61
+
The time required to run `sp_clean_db_file_free_space` depends on the size of the data file, the number of used pages in the file, and the I/O capabilities of the disk. Because running `sp_clean_db_file_free_space` can significantly increase I/O activity, we recommend that you run this procedure outside the usual operation hours.
61
62
62
63
Before you run `sp_clean_db_file_free_space`, we recommend that you create a full database backup.
63
64
64
-
The related [sp_clean_db_free_space](sp-clean-db-free-space-transact-sql.md) stored procedure cleans all files in the database.
65
+
To perform this operation for all data files in a database, use [sp_clean_db_free_space](sp-clean-db-free-space-transact-sql.md).
Removes residual information left on database pages because of data modification routines in [!INCLUDE [ssNoVersion](../../includes/ssnoversion-md.md)].`sp_clean_db_free_space` cleans all pages in all files of the database.
25
+
Removes residual information on data pages.`sp_clean_db_free_space` cleans all pages in all data files of the database.
@@ -42,29 +43,29 @@ The name of the database to clean. *@dbname* is **sysname**, with no default.
42
43
43
44
#### [ @cleaning_delay = ]*cleaning_delay*
44
45
45
-
Specifies an interval to delay between the cleaning of pages. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the effect on the I/O system.
46
+
Specifies an interval to delay before the cleanup of each page, in seconds. *@cleaning_delay* is **int**, with a default of `0`. This delay helps reduce the load on the I/O system at the expense of increasing the duration of the cleanup process.
46
47
47
48
## Return code values
48
49
49
50
`0` (success) or `1` (failure).
50
51
51
52
## Remarks
52
53
53
-
Delete operations from a table or update operations that cause a row to move can immediately free up space on a page by removing references to the row. However, under certain circumstances, the row can physically remain on the data page as a ghost record. A background process periodically removes ghost records. This residual data isn't returned by the [!INCLUDE [ssDE](../../includes/ssde-md.md)] in response to queries. However, in environments in which the physical security of the data or backup files is at risk, you can use `sp_clean_db_free_space`to clean these ghost records. To perform this operation per database file, use [sp_clean_db_file_free_space](sp-clean-db-file-free-space-transact-sql.md).
54
+
The `sp_clean_db_free_space` system stored procedure moves all rows on a page, including the ghosted records if any, to the beginning of the page, and then zero-initializes the remainder of the data space on the page. In environments where the physical security of the data files or the underlying storage is at risk, you can use this stored procedure to ensure that no residual deleted data remains in the data files or in storage.
54
55
55
-
The length of time required to run `sp_clean_db_free_space` depends on the size of the file, the available free space, and the capacity of the disk. Because running `sp_clean_db_free_space` can significantly affect I/O activity, we recommend that you run this procedure outside usual operation hours.
56
+
The time required to run `sp_clean_db_free_space` depends on the size of the data files, the number of used pages in the files, and the I/O capabilities of the disk. Because running `sp_clean_db_free_space` can significantly increase I/O activity, we recommend that you run this procedure outside the usual operation hours.
56
57
57
58
Before you run `sp_clean_db_free_space`, we recommend that you create a full database backup.
58
59
59
-
The related [sp_clean_db_file_free_space](sp-clean-db-file-free-space-transact-sql.md) stored procedure can clean a single file.
60
+
To perform this operation per database file, use [sp_clean_db_file_free_space](sp-clean-db-file-free-space-transact-sql.md).
60
61
61
62
## Permissions
62
63
63
64
Requires membership in the `db_owner` database role.
64
65
65
66
## Examples
66
67
67
-
The following example cleans all residual information from the [!INCLUDE [sssampledbobject-md](../../includes/sssampledbobject-md.md)] database.
68
+
The following example cleans all residual data from the [!INCLUDE [sssampledbobject-md](../../includes/sssampledbobject-md.md)] database.
0 commit comments