diff --git a/TOC.md b/TOC.md
index 285d816bd926..78b559c16c7c 100644
--- a/TOC.md
+++ b/TOC.md
@@ -37,6 +37,7 @@
- [插入数据](/develop/dev-guide-insert-data.md)
- [更新数据](/develop/dev-guide-update-data.md)
- [删除数据](/develop/dev-guide-delete-data.md)
+ - [使用 TTL (Time to Live) 定期删除过期数据](/time-to-live.md)
- [预处理语句](/develop/dev-guide-prepared-statement.md)
- 数据读取
- [单表读取](/develop/dev-guide-get-data-from-single-table.md)
diff --git a/experimental-features.md b/experimental-features.md
index c4eb9e97a412..4abca6f7d9f6 100644
--- a/experimental-features.md
+++ b/experimental-features.md
@@ -34,6 +34,7 @@ aliases: ['/docs-cn/dev/experimental-features-4.0/','/zh/tidb/dev/experimental-f
+ [Cascades Planner](/system-variables.md#tidb_enable_cascades_planner):基于 Cascades 框架的自顶向下查询优化器。(v3.0 实验特性)
+ [表级锁 (Table Lock)](/tidb-configuration-file.md#enable-table-lock-从-v400-版本开始引入)(v4.0.0 实验特性)
+ [Range INTERVAL 分区](/partitioned-table.md#range-interval-分区)(v6.3.0 实验特性)
++ [使用 TTL (Time to Live) 定期删除过期数据](/time-to-live.md)。(v6.5.0 实验特性)
+ [TiFlash 查询结果物化](/tiflash/tiflash-results-materialization.md)(v6.5.0 实验特性)
## 存储
diff --git a/grafana-tidb-dashboard.md b/grafana-tidb-dashboard.md
index 2d23e41f2cf2..d04f0eeeea12 100644
--- a/grafana-tidb-dashboard.md
+++ b/grafana-tidb-dashboard.md
@@ -169,3 +169,10 @@ aliases: ['/docs-cn/dev/grafana-tidb-dashboard/','/docs-cn/dev/reference/key-mon
- Wait Duration 95: 批量消息处理的等待时间。
- Batch Client Unavailable Duration 95:批处理客户端的不可用时长。
- No Available Connection Counter:批处理客户端不可用的连接数。
+
+- TTL
+ - TTL QPS By Type:TTL 任务产生的不同类型语句的 QPS 信息。
+ - TTL Processed Rows Per Second:TTL 任务每秒处理的过期数据的行数。
+ - TTL Scan/Delete Query Duration:TTL 的扫描/删除语句的执行时间。
+ - TTL Scan/Delete Worker Time By Phase:TTL 内部工作线程的不同阶段所占用的时间。
+ - TTL Job Count By Status:当前正在执行的 TTL 任务的数量。
diff --git a/sql-statements/sql-statement-alter-table.md b/sql-statements/sql-statement-alter-table.md
index 0216b561c590..5b0506aa0bd1 100644
--- a/sql-statements/sql-statement-alter-table.md
+++ b/sql-statements/sql-statement-alter-table.md
@@ -49,6 +49,11 @@ AlterTableSpec ::=
| 'SECONDARY_UNLOAD'
| ( 'AUTO_INCREMENT' | 'AUTO_ID_CACHE' | 'AUTO_RANDOM_BASE' | 'SHARD_ROW_ID_BITS' ) EqOpt LengthNum
| ( 'CACHE' | 'NOCACHE' )
+| (
+ 'TTL' EqOpt TimeColumnName '+' 'INTERVAL' Expression TimeUnit (TTLEnable EqOpt ( 'ON' | 'OFF' ))?
+ | 'REMOVE' 'TTL'
+ | TTLEnable EqOpt ( 'ON' | 'OFF' )
+ )
| PlacementPolicyOption
PlacementPolicyOption ::=
diff --git a/sql-statements/sql-statement-create-table.md b/sql-statements/sql-statement-create-table.md
index 91f99e1d0c6e..234a9c951ac5 100644
--- a/sql-statements/sql-statement-create-table.md
+++ b/sql-statements/sql-statement-create-table.md
@@ -83,6 +83,7 @@ TableOption ::=
| 'SECONDARY_ENGINE' EqOpt ( 'NULL' | StringName )
| 'UNION' EqOpt '(' TableNameListOpt ')'
| 'ENCRYPTION' EqOpt EncryptionOpt
+| 'TTL' EqOpt TimeColumnName '+' 'INTERVAL' Expression TimeUnit (TTLEnable EqOpt ( 'ON' | 'OFF' ))?
| PlacementPolicyOption
OnCommitOpt ::=
diff --git a/system-variables.md b/system-variables.md
index 46c668ccdc58..c6e57d4611ea 100644
--- a/system-variables.md
+++ b/system-variables.md
@@ -3215,6 +3215,114 @@ Query OK, 0 rows affected, 1 warning (0.00 sec)
>
> 如果 PD leader 的 TSO RPC 延迟升高,但其现象并非由 CPU 使用率达到瓶颈而导致(可能存在网络等问题),此时,调高 `tidb_tso_client_batch_max_wait_time` 可能会导致 TiDB 的语句执行延迟上升,影响集群的 QPS 表现。
+### `tidb_ttl_delete_rate_limit` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`0`
+- 范围:`[0, 9223372036854775807]`
+- 这个变量用来对每个 TiDB 节点的 TTL 删除操作进行限流。其值代表了在 TTL 任务中单个节点每秒允许 `DELETE` 语句执行的最大次数。当此变量设置为 `0` 时,则表示不做限制。
+
+### `tidb_ttl_delete_batch_size` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`100`
+- 范围:`[1, 10240]`
+- 这个变量用于设置 TTL 任务中单个删除事务中允许删除的最大行数。
+
+### `tidb_ttl_delete_worker_count` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`4`
+- 范围:`[1, 256]`
+- 这个变量用于设置每个 TiDB 节点上 TTL 删除任务的最大并发数。
+
+### `tidb_ttl_job_enable` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`ON`
+- 类型:布尔型
+- 这个变量用于控制是否启动 TTL 后台清理任务。如果设置为 `OFF`,所有具有 TTL 属性的表会自动停止对过期数据的清理。
+
+### `tidb_ttl_scan_batch_size` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`500`
+- 范围:`[1, 10240]`
+- 这个变量用于设置 TTL 任务中用来扫描过期数据的每个 `SELECT` 语句的 `LIMIT` 的值。
+
+### `tidb_ttl_scan_worker_count` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`4`
+- 范围:`[1, 256]`
+- 这个变量用于设置每个 TiDB 节点 TTL 扫描任务的最大并发数。
+
+### `tidb_ttl_job_run_interval` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 是否持久化到集群:是
+- 默认值:`1h0m0s`
+- 范围:`[10m0s, 8760h0m0s]`
+- 这个变量用于控制 TTL 后台清理任务的调度周期。比如,如果当前值设置成了 `1h0m0s`,则代表每张设置了 TTL 属性的表会每小时清理一次过期数据。
+
+### `tidb_ttl_job_schedule_window_start_time` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 类型:时间
+- 是否持久化到集群:是
+- 默认值:`00:00 +0000`
+- 这个变量用于控制 TTL 后台清理任务的调度窗口的起始时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。
+
+### `tidb_ttl_job_schedule_window_end_time` 从 v6.5.0 版本开始引入
+
+> **警告:**
+>
+> [TTL](/time-to-live.md) 目前为实验性特性,此变量定义可能在之后发生变化或者删除。
+
+- 作用域:GLOBAL
+- 类型:时间
+- 是否持久化到集群:是
+- 默认值:`23:59 +0000`
+- 这个变量用于控制 TTL 后台清理任务的调度窗口的结束时间。请谨慎调整此参数,过小的窗口有可能会造成过期数据的清理无法完成。
+
### `tidb_txn_assertion_level` 从 v6.0.0 版本开始引入
- 作用域:SESSION | GLOBAL
diff --git a/time-to-live.md b/time-to-live.md
new file mode 100644
index 000000000000..ce1be4878a31
--- /dev/null
+++ b/time-to-live.md
@@ -0,0 +1,172 @@
+---
+title: 使用 TTL (Time to Live) 定期删除过期数据
+summary: 介绍如何通过 SQL 来管理表数据的生命周期
+---
+
+# 使用 TTL (Time to Live) 定期删除过期数据
+
+Time to Live (TTL) 提供了行级别的生命周期控制策略。通过为表设置 TTL 属性,TiDB 可以周期性地自动检查并清理表中的过期数据。此功能在一些场景可以有效节省存储空间、提升性能。
+
+TTL 常见的使用场景:
+
+* 定期删除验证码、短网址记录
+* 定期删除不需要的历史订单
+* 自动删除计算的中间结果
+
+TTL 设计的目标是在不影响在线读写负载的前提下,帮助用户周期性且及时地清理不需要的数据。TTL 会以表为单位,并发地分发不同的任务到不同的 TiDB Server 节点上,进行并行删除处理。TTL 并不保证所有过期数据立即被删除,也就是说即使数据过期了,客户端仍然有可能在这之后的一段时间内读到过期的数据,直到其真正的被后台处理任务删除。
+
+> **警告:**
+>
+> 当前该功能为实验特性,不建议在生产环境中使用。
+> TTL 无法在 [Serverless Tier clusters](https://docs.pingcap.com/tidbcloud/select-cluster-tier#serverless-tier-beta) 上使用。
+
+## 语法
+
+你可以通过 [`CREATE TABLE`](/sql-statements/sql-statement-create-table.md) 或 [`ALTER TABLE`](/sql-statements/sql-statement-alter-table.md) 语句来配置表的 TTL 功能。
+
+### 创建具有 TTL 属性的表
+
+- 创建一个具有 TTL 属性的表:
+
+ ```sql
+ CREATE TABLE t1 (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP
+ ) TTL = `created_at` + INTERVAL 3 MONTH;
+ ```
+
+ 上面的例子创建了一张表 `t1`,并指定了 `created_at` 为 TTL 的时间列,表示数据的创建时间。同时,它还通过 `INTERVAL 3 MONTH` 设置了表中行的最长存活时间为 3 个月。超过了此时长的过期数据会在之后被删除。
+
+- 设置 `TTL_ENABLE` 属性来开启或关闭清理过期数据的功能:
+
+ ```sql
+ CREATE TABLE t1 (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP
+ ) TTL = `created_at` + INTERVAL 3 MONTH TTL_ENABLE = 'OFF';
+ ```
+
+ 如果 `TTL_ENABLE` 被设置成了 `OFF`,则即使设置了其他 TTL 选项,当前表也不会自动清理过期数据。对于一个设置了 TTL 属性的表,`TTL_ENABLE` 在缺省条件下默认为 `ON`。
+
+- 为了与 MySQL 兼容,你也可以使用注释语法来设置 TTL:
+
+ ```sql
+ CREATE TABLE t1 (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP
+ ) /*T![ttl] TTL = `created_at` + INTERVAL 3 MONTH TTL_ENABLE = 'OFF'*/;
+ ```
+
+ 在 TiDB 环境中,使用表的 TTL 属性和注释语法来配置 TTL 是等价的。在 MySQL 环境中,会自动忽略注释中的内容,并创建普通的表。
+
+### 修改表的 TTL 属性
+
+- 修改表的 TTL 属性:
+
+ ```sql
+ ALTER TABLE t1 TTL = `created_at` + INTERVAL 1 MONTH;
+ ```
+
+ 上面的语句既支持修改已配置 TTL 属性的表,也支持为一张非 TTL 的表添加 TTL 属性。
+
+- 单独修改 TTL 表的 `TTL_ENABLE` 值:
+
+ ```sql
+ ALTER TABLE t1 TTL_ENABLE = 'OFF';
+ ```
+
+- 清除一张表的所有 TTL 属性:
+
+ ```sql
+ ALTER TABLE t1 REMOVE TTL;
+ ```
+
+### TTL 和数据类型的默认值
+
+TTL 可以和[数据类型的默认值](/data-type-default-values.md)一起使用。以下是两种常见的用法示例:
+
+* 使用 `DEFAULT CURRENT_TIMESTAMP` 来指定某一列的默认值为该行的创建时间,并用这一列作为 TTL 的时间列,创建时间超过 3 个月的数据将被标记为过期:
+
+ ```sql
+ CREATE TABLE t1 (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+ ) TTL = `created_at` + INTERVAL 3 MONTH;
+ ```
+
+* 指定某一列的默认值为该行的创建时间或更新时间,并用这一列作为 TTL 的时间列,创建时间或更新时间超过 3 个月的数据将被标记为过期:
+
+ ```sql
+ CREATE TABLE t1 (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ ) TTL = `created_at` + INTERVAL 3 MONTH;
+ ```
+
+### TTL 和生成列
+
+TTL 可以和[生成列](/generated-columns.md)(实验特性)一起使用,用来表达更加复杂的过期规则。例如:
+
+```sql
+CREATE TABLE message (
+ id int PRIMARY KEY,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ image bool,
+ expire_at TIMESTAMP AS (IF(image,
+ created_at + INTERVAL 5 DAY,
+ created_at + INTERVAL 30 DAY
+ ))
+) TTL = `expire_at` + INTERVAL 0 DAY;
+```
+
+上述语句的消息以 `expire_at` 列来作为过期时间,并按照消息类型来设定。如果是图片,则 5 天后过期,不然就 30 天后过期。
+
+TTL 还可以和 [JSON 类型](/data-type-json.md) 一起使用。例如:
+
+```sql
+CREATE TABLE orders (
+ id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ order_info JSON,
+ created_at DATE AS (JSON_EXTRACT(order_info, '$.created_at')) VIRTUAL
+) TTL = `created_at` + INTERVAL 3 month;
+```
+
+## TTL 任务
+
+对于每张设置了 TTL 属性的表,TiDB 内部会定期调度后台任务来清理过期的数据。你可以通过设置全局变量 [`tidb_ttl_job_run_interval`](/system-variables.md#tidb_ttl_job_run_interval-从-v650-版本开始引入) 来自定义任务的执行周期,比如通过下面的语句将后台清理任务设置为每 24 小时执行一次:
+
+```sql
+SET @@global.tidb_ttl_job_run_interval = '24h';
+```
+
+如果想禁止 TTL 任务的执行,除了可以设置表属性 `TTL_ENABLE='OFF'` 外,也可以通过设置全局变量 `tidb_ttl_job_enable` 关闭整个集群的 TTL 任务的执行。
+
+```sql
+SET @@global.tidb_ttl_job_enable = OFF;
+```
+
+在某些场景下,你可能希望只允许在每天的某个时间段内调度后台的 TTL 任务,此时可以设置全局变量 [`tidb_ttl_job_schedule_window_start_time`](/system-variables.md#tidb_ttl_job_schedule_window_start_time-从-v650-版本开始引入) 和 [`tidb_ttl_job_schedule_window_end_time`](/system-variables.md#tidb_ttl_job_schedule_window_end_time-从-v650-版本开始引入) 来指定时间窗口,比如:
+
+```sql
+SET @@global.tidb_ttl_job_schedule_window_start_time = '01:00 +0000';
+SET @@global.tidb_ttl_job_schedule_window_end_time = '05:00 +0000';
+```
+
+上述语句只允许在 UTC 时间的凌晨 1 点到 5 点调度 TTL 任务。默认情况下的时间窗口设置为 `00:00 +0000` 到 `23:59 +0000`,即允许所有时段的任务调度。
+
+## 监控与图表
+
+TiDB 会定时采集 TTL 的运行时信息,并在 Grafana 中提供了相关指标的可视化图表。你可以在 TiDB -> TTL 的面板下看到这些信息。指标详情见 [TiDB 重要监控指标详解](/grafana-tidb-dashboard.md) 中的 `TTL` 部分。
+
+## 工具兼容性
+
+作为实验特性,TTL 特性暂时不兼容包括 BR、TiDB Lightning、TiCDC 在内的数据导入导出以及同步工具。
+
+## 使用限制
+
+目前,TTL 特性具有以下限制:
+
+* 不允许在临时表上设置 TTL 属性,包括本地临时表和全局临时表。
+* 具有 TTL 属性的表不支持作为外键约束的主表被其他表引用。
+* 不保证所有过期数据立即被删除,过期数据被删除的时间取决于后台清理任务的调度周期和调度窗口。
+* 目前单个表的清理任务同时只能在同一个 TiDB Server 节点运行,这在某些场景下(比如表特别大的情况)可能会产生性能瓶颈。此问题会在后续版本中优化。