> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# CREATE CHANGEFEED

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

The `CREATE CHANGEFEED` <InternalLink path="sql-statements">statement</InternalLink> creates a new changefeed, which targets an allowlist of tables called "watched rows".  Every change to a watched row is emitted as a record in a configurable format (`JSON` or Avro) to a <InternalLink path="changefeed-sinks">configurable sink</InternalLink> or directly to the SQL session.

When a changefeed emits messages to a sink, it works as a <InternalLink path="how-does-a-changefeed-work">job</InternalLink>. You can [create](#examples), [pause](#pause-a-changefeed), [resume](#resume-a-paused-changefeed), <InternalLink path="alter-changefeed">alter</InternalLink>, or [cancel](#cancel-a-changefeed) a changefeed job.

To get started with changefeeds, refer to the <InternalLink path="create-and-configure-changefeeds">Create and Configure Changefeeds</InternalLink> page for important usage considerations. For details on how changefeeds emit messages, refer to the <InternalLink path="changefeed-messages">Changefeed Messages</InternalLink> page.

The [examples](#examples) on this page provide the foundational syntax of the `CREATE CHANGEFEED` statement. For examples on more specific use cases with changefeeds, refer to the following pages:

* <InternalLink path="cdc-queries">Change Data Capture Queries</InternalLink>
* <InternalLink path="changefeeds-on-tables-with-column-families">Changefeeds on Tables with Column Families</InternalLink>
* <InternalLink path="export-data-with-changefeeds">Export Data with Changefeeds</InternalLink>

Cockroach Labs recommends monitoring your changefeeds to track <InternalLink path="monitor-and-debug-changefeeds">retryable errors</InternalLink> and <InternalLink path="architecture/storage-layer#protected-timestamps">protected timestamp</InternalLink> usage. Refer to the <InternalLink path="monitor-and-debug-changefeeds">Monitor and Debug Changefeeds</InternalLink> page for more information.

## Required privileges

<Danger>
  As of v25.1, **viewing and managing** a changefeed job by users with the [`CHANGEFEED` privilege](#changefeed-privilege) is **deprecated**. This functionality of the `CHANGEFEED` privilege will be removed in a future release.

  We recommend transitioning users that need to view and manage running changefeed jobs to <InternalLink path="create-role">roles</InternalLink> that own the <InternalLink path="show-jobs">jobs</InternalLink> or <InternalLink path="grant">granting</InternalLink> them the `VIEWJOB` or `CONTROLJOB` privilege. For more details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).
</Danger>

### Privilege model

<Tip>
  For fine-grained access control, we recommend using the system-level privileges [`CHANGEFEED`](#changefeed-privilege) and [`CONTROLJOB` / `VIEWJOB`](#view-and-manage-changefeed-jobs).
</Tip>

The following summarizes the operations users can run depending on whether the assigned privileges are at the job or table level:

| Granted privileges                                                                                                               | Usage                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CHANGEFEED`                                                                                                                     | Create changefeeds on tables. For details, refer to [`CHANGEFEED` privilege](#changefeed-privilege).<br />**Deprecated**: View and manage changefeed jobs on tables. Instead, transition users that need to view and manage running changefeed jobs to <InternalLink path="create-role">roles</InternalLink> that own the <InternalLink path="show-jobs">jobs</InternalLink> or <InternalLink path="grant">granting</InternalLink> them the `VIEWJOB` or `CONTROLJOB` privilege. For more details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).                                                                                                                                                                                                                                                                                                                   |
| `CHANGEFEED` + <InternalLink path="create-external-connection#required-privileges">`USAGE`</InternalLink> on external connection | Create changefeeds on tables to an external connection URI. For details, refer to [`CHANGEFEED` privilege](#changefeed-privilege).<br />**Deprecated**: View and manage changefeed jobs on tables. Instead, transition users that need to view and manage running changefeed jobs to <InternalLink path="create-role">roles</InternalLink> that own the <InternalLink path="show-jobs">jobs</InternalLink> or <InternalLink path="grant">granting</InternalLink> them the `VIEWJOB` or `CONTROLJOB` privilege. For more details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).<br /><br />**Note:** If you need to manage access to changefeed sink URIs, set the `changefeed.permissions.require_external_connection_sink.enabled=true` cluster setting. This will mean that users with these privileges can **only** create changefeeds on external connections. |
| Job ownership                                                                                                                    | <InternalLink path="show-jobs#show-changefeed-jobs">View</InternalLink> and manage changefeed jobs (<InternalLink path="pause-job">pause</InternalLink>, <InternalLink path="resume-job">resume</InternalLink>, and <InternalLink path="cancel-job">cancel</InternalLink>). For details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `CONTROLJOB`                                                                                                                     | Manage changefeed jobs (<InternalLink path="pause-job">pause</InternalLink>, <InternalLink path="resume-job">resume</InternalLink>, and <InternalLink path="cancel-job">cancel</InternalLink>). For details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `VIEWJOB`                                                                                                                        | <InternalLink path="show-jobs#show-changefeed-jobs">View</InternalLink> changefeed jobs. For details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `SELECT`                                                                                                                         | Create a sinkless changefeed that emits messages to a SQL client.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| **Deprecated** `CONTROLCHANGEFEED` role option + `SELECT`                                                                        | Create changefeeds on tables. Users with the `CONTROLCHANGEFEED` role option must have `SELECT` on each table, even if they are also granted the `CHANGEFEED` privilege.<br /><br />The `CONTROLCHANGEFEED` role option will be removed in a future release. We recommend using the system-level privileges [`CHANGEFEED`](#changefeed-privilege) and [`CONTROLJOB`/ `VIEWJOB`](#view-and-manage-changefeed-jobs) for fine-grained access control.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `admin`                                                                                                                          | Create, view, and manage changefeed jobs.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

#### `CHANGEFEED` privilege

<Note>
  Viewing and managing changefeed jobs with the `CHANGEFEED` privilege is **deprecated** as of v25.1. Instead, transition users that need to view and manage running changefeed jobs to <InternalLink path="create-role">roles</InternalLink> that own the <InternalLink path="show-jobs">jobs</InternalLink> or <InternalLink path="grant">granting</InternalLink> them the `VIEWJOB` or `CONTROLJOB` privilege. For more details, refer to [View and manage changefeed jobs](#view-and-manage-changefeed-jobs).
</Note>

You can <InternalLink path="grant#grant-privileges-on-specific-tables-in-a-database">grant</InternalLink> a user the `CHANGEFEED` privilege to allow them to create changefeeds on a specific table:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
GRANT CHANGEFEED ON TABLE example_table TO user;
```

When you grant a user the `CHANGEFEED` privilege on a set of tables, they can create changefeeds on the target tables even if the user does **not** have the <InternalLink path="alter-role#role-options">`CONTROLCHANGEFEED` role option</InternalLink> or the `SELECT` privilege on the tables.

These users will be able to create changefeeds, but they will not be able to run a `SELECT` query on that data directly. However, they could still read this data indirectly if they have read access to the <InternalLink path="changefeed-sinks">sink</InternalLink>.

You can add `CHANGEFEED` to the user or role's <InternalLink path="security-reference/authorization#default-privileges">default privileges</InternalLink> with <InternalLink path="alter-default-privileges#grant-default-privileges-to-a-specific-role">`ALTER DEFAULT PRIVILEGES`</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER DEFAULT PRIVILEGES GRANT CHANGEFEED ON TABLES TO user;
```

To restrict a user's access to changefeed data and sink credentials, enable the `changefeed.permissions.require_external_connection_sink.enabled` cluster setting. When you enable this setting, users with the <InternalLink path="create-changefeed#required-privileges">`CHANGEFEED` privilege</InternalLink> on a set of tables can only create changefeeds into <InternalLink path="create-external-connection">external connections</InternalLink>.

#### View and manage changefeed jobs

Users can <InternalLink path="show-jobs#show-changefeed-jobs">view</InternalLink> and manage changefeed jobs when one of the following are met:

* **Job ownership**: They own the job, or are a member of a role that owns a job.
* **Global privileges**: They are assigned <InternalLink path="security-reference/authorization#supported-privileges">`CONTROLJOB` or `VIEWJOB`</InternalLink>.

To give a set of users access to a specific job, or set of jobs, assign them to a <InternalLink path="security-reference/authorization#users-and-roles">role</InternalLink> that owns the job(s).

You can transfer ownership of a job to a role or user using the <InternalLink path="alter-job">`ALTER JOB`</InternalLink> statement:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER JOB job_ID OWNER TO role_name;
```

## Synopsis

<img src="https://mintcdn.com/cockroachlabs/9gyQKEP-CuQuCsI3/images/sql-diagrams/v25.3/create_changefeed.svg?fit=max&auto=format&n=9gyQKEP-CuQuCsI3&q=85&s=57c47a260cce8dc9c5b357f0d21a1575" alt="create_changefeed syntax diagram" style={{maxWidth: "100%", overflowX: "auto"}} width="1303" height="337" data-path="images/sql-diagrams/v25.3/create_changefeed.svg" />

## Parameters

| Parameter          | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `table_name`       | The name of the table (or tables in a comma separated list) to create a changefeed for.<br /><br />**Note:** Before creating a changefeed, consider the number of changefeeds versus the number of tables to include in a single changefeed. Each scenario can have an impact on total memory usage or changefeed performance. Refer to <InternalLink path="create-and-configure-changefeeds">Create and Configure Changefeeds</InternalLink> for more detail.                                  |
| `sink`             | The location of the configurable sink. The scheme of the URI indicates the type. For more information, refer to [Sink URI](#sink-uri).<br /><br />**Note:** If you create a changefeed without a sink, your changefeed will run like a <InternalLink path="changefeed-for">basic changefeed</InternalLink> sending messages to the SQL client. For more detail, refer to the <InternalLink path="create-and-configure-changefeeds#create">Create and Configure Changefeeds</InternalLink> page. |
| `option` / `value` | For a list of available options and their values, refer to [Options](#options).                                                                                                                                                                                                                                                                                                                                                                                                                 |

### CDC query parameters

Change data capture queries allow you to define the change data emitted to your sink when you create a changefeed. See the <InternalLink path="cdc-queries">Change Data Capture Queries</InternalLink> page for detail on the functionality, syntax, and use cases for changefeeds created with queries.

| Parameter                | Description                                                                                                                       |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
| `sink`                   | The location of the configurable sink. The scheme of the URI indicates the type. For more information, see [Sink URI](#sink-uri). |
| `option` / `value`       | For a list of available options and their values, see [Options](#options).                                                        |
| `target_list`            | The columns to emit data from.                                                                                                    |
| `changefeed_target_expr` | The target table for the changefeed.                                                                                              |
| `opt_where_clause`       | An optional `WHERE` clause to apply filters to the table.                                                                         |

### Sink URI

To form the URI for each sink:

```
'{scheme}://{host}:{port}?{query_parameters}'
```

| URI Component      | Description                                                                                                                                                  |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `scheme`           | The type of sink, e.g., <InternalLink path="changefeed-sinks#kafka">`kafka`</InternalLink>, <InternalLink path="changefeed-sinks">`gcpubsub`</InternalLink>. |
| `host`             | The sink's hostname or IP address.                                                                                                                           |
| `port`             | The sink's port.                                                                                                                                             |
| `query_parameters` | The sink's [query parameters](#query-parameters).                                                                                                            |

For more comprehensive detail of using and configuring each sink, refer to:

* [Amazon MSK](#amazon-msk)  <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>
* [Apache Pulsar](#apache-pulsar) (in Preview)  <InternalLink path="changefeed-sinks#apache-pulsar">Apache Pulsar</InternalLink> (in Preview)
* [Azure Event Hubs](#azure-event-hubs)  <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>
* [Cloud Storage](#cloud-storage-sink) / HTTP  <InternalLink path="changefeed-sinks#cloud-storage-sink">Cloud Storage</InternalLink> / HTTP
* [Confluent Cloud](#confluent-cloud)  <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink>
* [Google Cloud Pub/Sub](#google-cloud-pub-sub)  <InternalLink path="changefeed-sinks">Google Cloud Pub/Sub</InternalLink>
* [Kafka](#kafka)  <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>
* [Webhook](#webhook-sink)  <InternalLink path="changefeed-sinks#webhook-sink">Webhook</InternalLink>

You can create an external connection to represent a changefeed sink URI. This allows you to specify the external connection's name in statements rather than the provider-specific URI. For detail on using external connections, see the <InternalLink path="create-external-connection">`CREATE EXTERNAL CONNECTION`</InternalLink> page.

### Query parameters

<Note>
  Parameters should always be URI-encoded before they are included the changefeed's URI, as they often contain special characters. Use Javascript's [encodeURIComponent](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) function or Go language's [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape) function to URI-encode the parameters. Other languages provide similar functions to URI-encode special characters.
</Note>

Query parameters include:

| Parameter                  | Sink Type                                                                                                                                                                                                                                                                                                                           | Type                                                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ASSUME_ROLE`              | <InternalLink path="changefeed-sinks">Amazon S3</InternalLink>, <InternalLink path="changefeed-sinks#cloud-storage-sink">Google Cloud Storage</InternalLink>, <InternalLink path="changefeed-sinks">Google Cloud Pub/Sub</InternalLink>                                                                                             | <InternalLink path="string">`STRING`</InternalLink> | Pass the [ARN](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) of the role to assume. Use in combination with `AUTH=implicit` or `specified`. <br />`external_id`: Use as a value to `ASSUME_ROLE` to specify the [external ID](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html) for third-party access to your S3 bucket.                                                                                                                                                                                                                                                                             |
| `AUTH`                     | <InternalLink path="changefeed-sinks">Amazon S3</InternalLink>, <InternalLink path="changefeed-sinks#cloud-storage-sink">Google Cloud Storage</InternalLink>, <InternalLink path="changefeed-sinks">Google Cloud Pub/Sub</InternalLink>, <InternalLink path="changefeed-sinks#cloud-storage-sink">Azure Blob Storage</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The authentication parameter can define either `specified` (default) or `implicit` authentication. To use `specified` authentication, pass your [Service Account](https://cloud.google.com/iam/docs/understanding-service-accounts) credentials with the URI. To use `implicit` authentication, configure these credentials via an environment variable. Refer to the <InternalLink path="cloud-storage-authentication">Cloud Storage Authentication page</InternalLink> page for examples of each of these.                                                                                                                                                                 |
| `api_key`                  | <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink>                                                                                                                                                                                                                                                | <InternalLink path="string">`STRING`</InternalLink> | The API key created for the cluster in Confluent Cloud.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `api_secret`               | <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink>                                                                                                                                                                                                                                                | <InternalLink path="string">`STRING`</InternalLink> | The API key's secret generated in Confluent Cloud. **Note:** This must be [URL-encoded](https://www.urlencoder.org/) before passing into the connection string.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `ca_cert`                  | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#webhook-sink">webhook</InternalLink>, [Confluent schema registry](https://docs.confluent.io/platform/current/schema-registry/index.html)                                                                                     | <InternalLink path="string">`STRING`</InternalLink> | The base64-encoded `ca_cert` file. Specify `ca_cert` for a Kafka sink, webhook sink, and/or a Confluent schema registry. <br /><br />For usage with a Kafka sink, see <InternalLink path="changefeed-sinks#kafka">Kafka Sink URI</InternalLink>. <br /><br /> It's necessary to state `https` in the schema registry's address when passing `ca_cert`: <br />`confluent_schema_registry='https://schema_registry:8081?ca_cert=LS0tLS1CRUdJTiBDRVJUSUZ'` <br /> See [`confluent_schema_registry`](#confluent-schema-registry) for more detail on using this option. <br /><br />Note: To encode your `ca.cert`, run `base64 -w 0 ca.cert`.                                    |
| `client_cert`              | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#webhook-sink">webhook</InternalLink>, [Confluent schema registry](https://docs.confluent.io/platform/current/schema-registry/index.html)                                                                                     | <InternalLink path="string">`STRING`</InternalLink> | The base64-encoded Privacy Enhanced Mail (PEM) certificate. This is used with `client_key`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `client_key`               | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#webhook-sink">webhook</InternalLink>, [Confluent schema registry](https://docs.confluent.io/platform/current/schema-registry/index.html)                                                                                     | <InternalLink path="string">`STRING`</InternalLink> | The base64-encoded private key for the PEM certificate. This is used with `client_cert`.<br /><br />**Note:** Client keys are often encrypted. You will receive an error if you pass an encrypted client key in your changefeed statement. To decrypt the client key, run: `openssl rsa -in key.pem -out key.decrypt.pem -passin pass:{PASSWORD}`. Once decrypted, be sure to update your changefeed statement to use the new `key.decrypt.pem` file instead.                                                                                                                                                                                                                |
| `file_size`                | <InternalLink path="changefeed-sinks#cloud-storage-sink">cloud</InternalLink>                                                                                                                                                                                                                                                       | <InternalLink path="string">`STRING`</InternalLink> | The file will be flushed (i.e., written to the sink) when it exceeds the specified file size. This can be used with the [`WITH resolved` option](#options), which flushes on a specified cadence. When you change or increase `file_size`, ensure that you adjust the `changefeed.memory.per_changefeed_limit` <InternalLink path="cluster-settings">cluster setting</InternalLink>, which has a default of `512MiB`. Buffering messages can quickly reach this limit if you have increased the file size. Refer to <InternalLink path="advanced-changefeed-configuration">Advanced Changefeed Configuration</InternalLink> for more detail. <br /><br />**Default:** `16MB` |
| `insecure_tls_skip_verify` | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#webhook-sink">webhook</InternalLink>                                                                                                                                                                                         | <InternalLink path="bool">`BOOL`</InternalLink>     | If `true`, disable client-side validation of responses. Note that a CA certificate is still required; this parameter means that the client will not verify the certificate. **Warning:** Use this query parameter with caution, as it creates [MITM](https://wikipedia.org/wiki/Man-in-the-middle_attack) vulnerabilities unless combined with another method of authentication. <br /><br />**Default:** `false`                                                                                                                                                                                                                                                            |
| `partition_format`         | <InternalLink path="changefeed-sinks#cloud-storage-sink">cloud</InternalLink>                                                                                                                                                                                                                                                       | <InternalLink path="string">`STRING`</InternalLink> | Specify how changefeed [file paths](#general-file-format) are partitioned in cloud storage sinks. Use `partition_format` with the following values: <ul><li>`daily` is the default behavior that organizes directories by dates (`2022-05-18/`, `2022-05-19/`, etc.).</li><li>`hourly` will further organize directories by hour within each date directory (`2022-05-18/06`, `2022-05-18/07`, etc.).</li><li>`flat` will not partition the files at all.</li></ul>For example: `CREATE CHANGEFEED FOR TABLE users INTO 'gs://...?AUTH...&partition_format=hourly'` <br /><br /> **Default:** `daily`                                                                        |

For example: `CREATE CHANGEFEED FOR TABLE users INTO 'gs://...?AUTH...&partition_format=hourly'` <br /><br /> **Default:** `daily`
`S3_STORAGE_CLASS` | <InternalLink path="changefeed-sinks#amazon-s3">Amazon S3 cloud storage sink</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Specify the Amazon S3 storage class for files created by the changefeed. See [Create a changefeed with an S3 storage class](#create-a-changefeed-with-an-s3-storage-class) for the available classes and an example. <br /><br />**Default:** `STANDARD`
`sasl_aws_iam_role_arn` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The ARN for the IAM role that has the permissions to create a topic and send data to the topic. For more details on setting up an Amazon MSK cluster with an IAM role, refer to [the AWS documentation](https://docs.aws.amazon.com/msk/latest/developerguide/serverless-getting-started.html).
`sasl_aws_iam_session_name` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The user-specified string that identifies the session in AWS.
`sasl_aws_region` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The region of the Amazon MSK cluster.
`sasl_client_id`   | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Client ID for OAuth authentication from a third-party provider. This parameter is only applicable with `sasl_mechanism=OAUTHBEARER`.
`sasl_client_secret` | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Client secret for OAuth authentication from a third-party provider. This parameter is only applicable with `sasl_mechanism=OAUTHBEARER`. **Note:** You must [base64 encode](https://www.base64encode.org/) this value when passing it in as part of a sink URI.
`sasl_enabled` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>, <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink> | <InternalLink path="bool">`BOOL`</InternalLink> | If `true`, set the authentication protocol with the [`sasl_mechanism`](#sasl-mechanism) parameter. You must have `tls_enabled` set to `true` to use SASL.<br /><br />For Confluent Cloud and Azure Event Hubs sinks, this is set to `true` by default.<br /><br /> **Default:** `false`
`sasl_grant_type` | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Override the default OAuth client credentials grant type for other implementations. This parameter is only applicable with `sasl_mechanism=OAUTHBEARER`.
`sasl_handshake` | <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink> | <InternalLink path="bool">`BOOL`</InternalLink> | For Confluent Cloud and Azure Event Hubs sinks, this is set to `true` by default.
`sasl_mechanism` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>, <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Can be set to [`OAUTHBEARER`](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_oauth.html),  [`SCRAM-SHA-256`](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_scram.html), [`SCRAM-SHA-512`](https://docs.confluent.io/platform/current/kafka/authentication_sasl/authentication_sasl_scram.html), or [`PLAIN`](https://docs.confluent.io/current/kafka/authentication_sasl/authentication_sasl_plain.html). A `sasl_user` and `sasl_password` are required for `PLAIN` and `SCRAM` authentication.<br /><br />For Amazon MSK clusters, set to <InternalLink path="changefeed-sinks#amazon-msk">`AWS_MSK_IAM`</InternalLink>. [`sasl_aws_iam_role_arn`](#sasl-aws-iam-role-arn), [`sasl_aws_iam_session_name`](#sasl-aws-iam-session-name), and [`sasl_aws_region`](#sasl-aws-region) are also required in the sink uri.<br /><br />Refer to the <InternalLink path="connect-to-a-changefeed-kafka-sink-with-oauth-using-okta">Connect to a Changefeed Kafka sink with OAuth Using Okta</InternalLink> tutorial for detail setting up OAuth using Okta.<br /><br />For Confluent Cloud and Azure Event Hubs sinks, `sasl_mechanism=PLAIN` is required but set automatically by CockroachDB.<br /><br /> **Default:** `PLAIN`
`sasl_scopes` | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | A list of scopes that the OAuth token should have access for. This parameter is only applicable with `sasl_mechanism=OAUTHBEARER`.
`sasl_token_url` | <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Client token URL for OAuth authentication from a third-party provider. **Note:** You must [URL encode](https://www.urlencoder.org/) this value before passing in a URI. This parameter is only applicable with `sasl_mechanism=OAUTHBEARER`.
`sasl_user` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Your SASL username.
`sasl_password` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Your SASL password. **Note:** Passwords should be [URL encoded](https://wikipedia.org/wiki/Percent-encoding) since the value can contain characters that would cause authentication to fail.
`shared_access_key` | <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The URL-encoded key for your Event Hub shared access policy.
`shared_access_key_name` | <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | The name of your Event Hub shared access policy.
`tls_enabled` | <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink> | <InternalLink path="bool">`BOOL`</InternalLink>                 | If `true`, enable Transport Layer Security (TLS) on the connection to Kafka. This can be used with a `ca_cert` (see below).<br /><br />For Confluent Cloud and Azure Event Hubs sinks, this is set to `true` by default.<br /><br />**Default:** `false`
`topic_name` | <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink>, <InternalLink path="changefeed-sinks">GC Pub/Sub</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Allows arbitrary topic naming for Kafka and GC Pub/Sub topics. See the <InternalLink path="changefeed-sinks#topic-naming">Kafka topic naming limitations</InternalLink> or <InternalLink path="changefeed-sinks">GC Pub/Sub topic naming</InternalLink> for detail on supported characters etc. <br /><br />For example, `CREATE CHANGEFEED FOR foo,bar INTO 'kafka://sink?topic_name=all'` will emit all records to a topic named `all`. Note that schemas will still be registered separately. When using Kafka, this parameter can be combined with the [`topic_prefix` parameter](#topic-prefix) (this is not supported for GC Pub/Sub). <br /><br />**Default:** table name.
`topic_prefix`     | <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>, <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>, <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink> | <InternalLink path="string">`STRING`</InternalLink> | Adds a prefix to all topic names.<br /><br />For example, `CREATE CHANGEFEED FOR TABLE foo INTO 'kafka://...?topic_prefix=bar_'` would emit rows under the topic `bar_foo` instead of `foo`.

### Options

| Option                                                                                         | Value                                                                      | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <a id="avro-schema-prefix" /> `avro_schema_prefix`                                             | Schema prefix name                                                         | Provide a namespace for the schema of a table in addition to the default, the table name. This allows multiple databases or clusters to share the same schema registry when the same table name is present in multiple databases.<br /><br />Example: `CREATE CHANGEFEED FOR foo WITH format=avro, confluent_schema_registry='registry_url', avro_schema_prefix='super'` will register subjects as `superfoo-key` and `superfoo-value` with the namespace `super`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <a id="compression" /> `compression`                                                           | `gzip`, `zstd`                                                             | Compress changefeed data files written to:<ul><li><InternalLink path="changefeed-sinks#cloud-storage-sink">Cloud storage sinks</InternalLink></li><li><InternalLink path="changefeed-sinks#webhook-sink">Webhook sinks</InternalLink></li></ul>. For compression options when using a Kafka sink, see <InternalLink path="changefeed-sinks#kafka-sink-configuration">Kafka sink configuration</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| <a id="confluent-registry" /> <a id="confluent-schema-registry" /> `confluent_schema_registry` | Schema Registry address                                                    | The [Schema Registry](https://docs.confluent.io/current/schema-registry/docs/index.html#sr) address is required to use `avro`.<br /><br />Use the  `timeout={duration}` query parameter  <InternalLink path="create-changefeed">`timeout={duration}` query parameter</InternalLink> ([duration string](https://pkg.go.dev/time#ParseDuration)) in your Confluent Schema Registry URI to change the default timeout for contacting the schema registry. By default, the timeout is 30 seconds.<br /><br />To connect to Confluent Cloud, use the following URL structure: `'https://{API_KEY_ID}:{API_SECRET_URL_ENCODED}@{CONFLUENT_REGISTRY_URL}:443'`. See the <InternalLink path="stream-a-changefeed-to-a-confluent-cloud-kafka-cluster#step-8-create-a-changefeed">Stream a Changefeed to a Confluent Cloud Kafka Cluster</InternalLink> tutorial for further detail.<br /><br />Use the `changefeed.schema_registry.retry_count` metric to measure the number of request retries performed when sending requests to the schema registry. For more detail on monitoring changefeeds, refer to <InternalLink path="monitor-and-debug-changefeeds">Monitor and Debug Changefeeds</InternalLink>.                                                                                                                                                                                                                                                                                                                         |
| `cursor`                                                                                       | <InternalLink path="as-of-system-time#parameters">Timestamp</InternalLink> | Emit any changes after the given timestamp. `cursor` does not output the current state of the table first. When `cursor` is not specified, the changefeed starts by doing an initial scan of all the watched rows and emits the current value, then moves to emitting any changes that happen after the scan.<br /><br />The changefeed will encounter an error if you specify a timestamp that is before the configured garbage collection window for the target table. (Refer to <InternalLink path="configure-replication-zones#replication-zone-variables">`gc.ttlseconds`</InternalLink>.) With default garbage collection settings, this means you cannot create a changefeed that starts more than <InternalLink path="configure-replication-zones">the-default-MVCC-garbage-collection-interval</InternalLink> in the past.<br /><br />You can use `cursor` to [start-a-new-changefeed-where-a-previous-changefeed-ended](#start-a-new-changefeed-where-another-ended).<br /><br />Example: `cursor='1536242855577149065.0000000000'`                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `diff`                                                                                         | N/A                                                                        | Publish a <InternalLink path="changefeed-message-envelopes">`before` field</InternalLink> with each message, which includes the value of the row before the update was applied. Changefeeds must use the `diff` option with the default [`wrapped` envelope](#envelope) or the `enriched` envelope to emit the `before` field.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| <a id="encode-json-value-null-as-object" /> `encode_json_value_null_as_object`                 | N/A                                                                        | Emit JSON `NULL` values as `{"__crdb_json_null__": true}` to distinguish these values from SQL `NULL` values. Refer to the <InternalLink path="changefeed-messages#json">Changefeed Messages</InternalLink> page for an example.<br /><br />**Note:** When this option is enabled, if the changefeed encounters the literal value `{"__crdb_json_null__": true}` in JSON, it will have the same representation as a JSON `NULL` value and a warning will be printed to the <InternalLink path="logging#dev">`DEV` logging channel</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `end_time`                                                                                     | <InternalLink path="as-of-system-time#parameters">Timestamp</InternalLink> | Indicate the timestamp up to which the changefeed will emit all events and then complete with a `successful` status. Provide a future timestamp to `end_time` in number of nanoseconds since the [Unix epoch](https://wikipedia.org/wiki/Unix_time). For example, `end_time="1655402400000000000"`. You cannot use `end_time` and [`initial_scan = 'only'`](#initial-scan) simultaneously.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| <a id="envelope" /> `envelope`                                                                 | `wrapped` / `enriched` / `bare` / `key_only` / `row`                       | `wrapped` the default envelope structure for changefeed messages containing an array of the primary key, a top-level field for the type of message, and the current state of the row (or `null` for deleted rows).<br /><br />Refer to the <InternalLink path="changefeed-message-envelopes">Changefeed Message Envelopes</InternalLink> page for more detail on each envelope.<br /><br />Default: `envelope=wrapped`. Default for <InternalLink path="cdc-queries">CDC-queries</InternalLink>: `envelope=bare`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| <a id="execution-locality" /> `execution_locality`                                             | Key-value pairs                                                            | Restricts the execution of a changefeed to nodes that match the defined locality filter requirements, e.g., `WITH execution_locality = 'region=us-west-1a,cloud=aws'`. <br /><br />See <InternalLink path="changefeeds-in-multi-region-deployments#run-a-changefeed-job-by-locality">Run a changefeed job by locality</InternalLink> for usage and reference detail.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <a id="format" /> `format`                                                                     | `json` / `avro` / `csv` / `parquet`                                        | Format of the emitted message. <br /><br />`avro`: For mappings of CockroachDB types to Avro types, <InternalLink path="changefeed-messages#avro-types">refer-to-the-table</InternalLink> and detail on <InternalLink path="changefeed-messages#avro-limitations">Avro-limitations</InternalLink>. **Note:** [`confluent_schema_registry`](#confluent-schema-registry) is required with `format=avro`. <br /><br />`csv`: You cannot combine `format=csv` with the [`diff`](#diff) or [`resolved`](#resolved) options. Changefeeds use the same CSV format as the <InternalLink path="export">`EXPORT`</InternalLink> statement. Refer to <InternalLink path="export-data-with-changefeeds">Export-data-with-changefeeds</InternalLink> for details using these options to create a changefeed as an alternative to `EXPORT`. **Note:** [`initial_scan = 'only'`](#initial-scan) is required with `format=csv`. <br /><br />`parquet`: Cloud storage is the only supported sink. The [`topic_in_value`](#topic-in-value) option is not compatible with `parquet` format.<br /><br />Default: `format=json`.                                                                                                                                                                                                                                                                                                                                                                                                                 |
| <a id="full-table-name" /> `full_table_name`                                                   | N/A                                                                        | Use fully qualified table name in topics, subjects, schemas, and record output instead of the default table name. This can prevent unintended behavior when the same table name is present in multiple databases.<br /><br />**Note:** This option cannot modify existing table names used as topics, subjects, etc., as part of an <InternalLink path="alter-changefeed">`ALTER CHANGEFEED`</InternalLink> statement. To modify a topic, subject, etc., to use a fully qualified table name, create a new changefeed with this option. <br /><br />Example: `CREATE CHANGEFEED FOR foo... WITH full_table_name` will create the topic name `defaultdb.public.foo` instead of `foo`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <a id="gc-protect-expires-after" /> `gc_protect_expires_after`                                 | [Duration string](https://pkg.go.dev/time#ParseDuration)                   | Automatically expires protected timestamp records that are older than the defined duration. In the case where a changefeed job remains paused, `gc_protect_expires_after` will trigger the underlying protected timestamp record to expire and cancel the changefeed job to prevent accumulation of protected data.<br /><br />Refer to <InternalLink path="protect-changefeed-data">Protect-Changefeed-Data-from-Garbage-Collection</InternalLink> for more detail on protecting changefeed data.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `headers_json_column_name`                                                                     | <InternalLink path="string">`STRING`</InternalLink>                        | Specify a <InternalLink path="jsonb">JSONB</InternalLink> column that the changefeed emits as Kafka headers, separate from the message payload, for each row’s change event. `headers_json_column_name` is supported for Kafka sinks. For more details, refer to <InternalLink path="changefeed-messages#specify-a-column-as-a-kafka-header">Specify a column as a Kafka header</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| <a id="ignore-disable-changefeed-replication" /> `ignore_disable_changefeed_replication`       | <InternalLink path="bool">`BOOL`</InternalLink>                            | When set to `true`, the changefeed **will emit** events even if CDC filtering for TTL jobs is configured using the `disable_changefeed_replication` <InternalLink path="set-vars">session variable</InternalLink>, `sql.ttl.changefeed_replication.disabled` <InternalLink path="cluster-settings">cluster setting</InternalLink>, or the `ttl_disable_changefeed_replication` <InternalLink path="row-level-ttl">table storage parameter</InternalLink>.<br /><br />Refer to [Filter changefeeds for tables using TTL](#filter-changefeeds-for-tables-using-row-level-ttl) for usage details.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| <a id="initial-scan" /> `initial_scan`                                                         | `yes`/`no`/`only`                                                          | Control whether or not an initial scan will occur at the start time of a changefeed. Only one `initial_scan` option (`yes`, `no`, or `only`) can be used. If none of these are set, an initial scan will occur if there is no [`cursor`](#cursor), and will not occur if there is one. This preserves the behavior from previous releases. With `initial_scan = 'only'` set, the changefeed job will end with a successful status (`succeeded`) after the initial scan completes. You cannot specify `yes`, `no`, `only` simultaneously. <br /><br />If used in conjunction with `cursor`, an initial scan will be performed at the cursor timestamp. If no `cursor` is specified, the initial scan is performed at `now()`. <br /><br />Although the <InternalLink path="create-changefeed">`initial_scan` / `no_initial_scan`</InternalLink> syntax from previous versions is still supported, you cannot combine the previous and current syntax.<br /><br />Default: `initial_scan = 'yes'`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `kafka_sink_config`                                                                            | <InternalLink path="string">`STRING`</InternalLink>                        | Set fields to configure the required level of message acknowledgement from the Kafka server, the version of the server, and batching parameters for Kafka sinks. Set the message file compression type. See <InternalLink path="changefeed-sinks#kafka-sink-configuration">Kafka sink configuration</InternalLink> for more detail on configuring all the available fields for this option. <br /><br />Example: `CREATE CHANGEFEED FOR table INTO 'kafka://localhost:9092' WITH kafka_sink_config='{"Flush": {"MaxMessages": 1, "Frequency": "1s"}, "RequiredAcks": "ONE"}'`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| <a id="key-column" /> `key_column`                                                             | `'column'`                                                                 | Override the key used in <InternalLink path="changefeed-messages">message metadata</InternalLink>. This changes the key hashed to determine downstream partitions. In sinks that support partitioning by message, CockroachDB uses the [32-bit FNV-1a](https://wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function) hashing algorithm to determine which partition to send to.<br /><br />**Note:** `key_column` does not preserve ordering of messages from CockroachDB to the downstream sink, therefore you must also include the [`unordered`](#unordered) option in your changefeed creation statement. It does not affect per-key <InternalLink path="changefeed-messages#ordering-and-delivery-guarantees">ordering guarantees</InternalLink> or the output of [`key_in_value`](#key-in-value).<br /><br />See the [Define a key to determine the changefeed sink partition](#define-a-key-to-determine-the-changefeed-sink-partition) example.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| <a id="key-in-value" /> `key_in_value`                                                         | N/A                                                                        | Add a primary key array to the emitted message. This makes the <InternalLink path="primary-key">primary key</InternalLink> of a deleted row recoverable in sinks where each message has a value but not a key (most have a key and value in each message). `key_in_value` is automatically used for <InternalLink path="changefeed-sinks#cloud-storage-sink">cloud storage sinks</InternalLink>, <InternalLink path="changefeed-sinks#webhook-sink">webhook sinks</InternalLink>, and <InternalLink path="changefeed-sinks">GC Pub/Sub sinks</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| <a id="lagging-ranges-threshold" /> `lagging_ranges_threshold`                                 | [Duration string](https://pkg.go.dev/time#ParseDuration)                   | Set a duration from the present that determines the length of time a range is considered to be lagging behind, which will then track in the <InternalLink path="monitor-and-debug-changefeeds">`lagging_ranges`</InternalLink> metric. Note that ranges undergoing an [initial scan](#initial-scan) for longer than the threshold duration are considered to be lagging. Starting a changefeed with an initial scan on a large table will likely increment the metric for each range in the table. As ranges complete the initial scan, the number of ranges lagging behind will decrease.<br /><br />**Default:** `3m`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| <a id="lagging-ranges-polling-interval" /> `lagging_ranges_polling_interval`                   | [Duration string](https://pkg.go.dev/time#ParseDuration)                   | Set the interval rate for when lagging ranges are checked and the `lagging_ranges` metric is updated. Polling adds latency to the `lagging_ranges` metric being updated. For example, if a range falls behind by 3 minutes, the metric may not update until an additional minute afterward.<br /><br />**Default:** `1m`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `metrics_label`                                                                                | <InternalLink path="string">`STRING`</InternalLink>                        | Define a metrics label to which the metrics for one or multiple changefeeds increment. All changefeeds also have their metrics aggregated.<br /><br />The maximum length of a label is 128 bytes. There is a limit of 1024 unique labels.<br /><br />`WITH metrics_label=label_name` <br /><br />For more detail on usage and considerations, see <InternalLink path="monitor-and-debug-changefeeds#using-changefeed-metrics-labels">Using changefeed metrics labels</InternalLink>.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| <a id="min-checkpoint-frequency" /> `min_checkpoint_frequency`                                 | [Duration string](https://pkg.go.dev/time#ParseDuration)                   | Controls how often a node's changefeed <InternalLink path="how-does-a-changefeed-work">aggregator</InternalLink> will flush their progress to the <InternalLink path="how-does-a-changefeed-work">coordinating changefeed node</InternalLink>. A node's changefeed aggregator will wait at least the specified duration between sending progress updates for the ranges it is watching to the coordinator. This can help you control the flush frequency of higher latency sinks to achieve better throughput. However, more frequent checkpointing can increase CPU usage. If this is set to `0s`, a node will flush messages as long as the high-water mark has increased for the ranges that particular node is processing. If a changefeed is resumed, then `min_checkpoint_frequency` is the amount of time that changefeed will need to catch up. That is, it could emit <InternalLink path="changefeed-messages#duplicate-messages">duplicate messages</InternalLink> during this time. <br /><br />**Note:** [`resolved`](#resolved) messages will not be emitted more frequently than the configured `min_checkpoint_frequency` (but may be emitted less frequently). If you require `resolved` messages more frequently than `30s`, you must configure `min_checkpoint_frequency` to at least the desired `resolved` message frequency. For more details, refer to <InternalLink path="changefeed-messages#resolved-timestamp-frequency">Resolved message frequency</InternalLink>.<br /><br />**Default:** `30s` |
| `mvcc_timestamp`                                                                               | N/A                                                                        | Include the <InternalLink path="architecture/storage-layer#mvcc">MVCC</InternalLink> timestamp for each emitted row in a changefeed. With the `mvcc_timestamp` option, each emitted row will always contain its MVCC timestamp, even during the changefeed's initial backfill.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| <a id="on-error" /> `on_error`                                                                 | `pause` / `fail`                                                           | Use `on_error=pause` to pause the changefeed when encountering **non**-retryable errors. `on_error=pause` will pause the changefeed instead of sending it into a terminal failure state. **Note:** Retryable errors will continue to be retried with this option specified. <br /><br />Use with [`protect_data_from_gc_on_pause`](#protect-data-from-gc-on-pause) to protect changes from <InternalLink path="configure-replication-zones">garbage collection</InternalLink>.<br /><br />If a changefeed with `on_error=pause` is running when a watched table is <InternalLink path="truncate">truncated</InternalLink>, the changefeed will pause but will not be able to resume reads from that table. Using <InternalLink path="alter-changefeed">`ALTER CHANGEFEED`</InternalLink> to drop the table from the changefeed and then <InternalLink path="resume-job">resuming the job</InternalLink> will work, but you cannot add the same table to the changefeed again. Instead, you will need to [create a new changefeed](#start-a-new-changefeed-where-another-ended) for that table.<br /><br />Default: `on_error=fail`                                                                                                                                                                                                                                                                                                                                                                                          |
| <a id="protect-data-from-gc-on-pause" /> `protect_data_from_gc_on_pause`                       | N/A                                                                        | This option is deprecated as of v23.2 and will be removed in a future release.<br /><br />When a <InternalLink path="pause-job">changefeed is paused</InternalLink>, ensure that the data needed to <InternalLink path="resume-job">resume the changefeed</InternalLink> is not garbage collected. If `protect_data_from_gc_on_pause` is **unset**, pausing the changefeed will release the existing protected timestamp records. It is also important to note that pausing and adding `protect_data_from_gc_on_pause` to a changefeed will not protect data if the <InternalLink path="configure-replication-zones">garbage collection</InternalLink> window has already passed. <br /><br />Use with [`on_error=pause`](#on-error) to protect changes from garbage collection when encountering non-retryable errors. <br /><br />Refer to <InternalLink path="protect-changefeed-data">Protect Changefeed Data from Garbage Collection</InternalLink> for more detail on protecting changefeed data.<br /><br />**Note:** If you use this option, changefeeds that are left paused for long periods of time can prevent garbage collection. Use with the [`gc_protect_expires_after`](#gc-protect-expires-after) option to set a limit for protected data and for how long a changefeed will remain paused.                                                                                                                                                                                                              |
| `pubsub_sink_config`                                                                           | <InternalLink path="string">`STRING`</InternalLink>                        | Set fields to configure sink batching and retries. The schema is as follows:<br /><br /> `{ "Flush": { "Messages": ..., "Bytes": ..., "Frequency": ..., }, "Retry": {"Max": ..., "Backoff": ..., } }`. <br /><br />**Note** that if either `Messages` or `Bytes` are nonzero, then a non-zero value for `Frequency` must be provided. <br /><br />Refer to <InternalLink path="changefeed-sinks">Pub/Sub sink configuration</InternalLink> for more details on using this option.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| <a id="resolved" /> <a id="resolved-option" /> `resolved`                                      | [Duration string](https://pkg.go.dev/time#ParseDuration)                   | Emit <InternalLink path="changefeed-messages#resolved-messages">resolved timestamps</InternalLink> in a format dependent on the connected sink. Resolved timestamps do not emit until the changefeed job's progress has been checkpointed.<br /><br />Set a minimum amount of time that the changefeed's high-water mark (overall resolved timestamp) must advance by before another resolved timestamp is emitted. Example: `resolved='10s'`. This option will **only** emit a resolved timestamp if the timestamp has advanced (and by at least the optional duration, if set). If a duration is unspecified, all resolved timestamps are emitted as the high-water mark advances.<br /><br />**Note:** If you set `resolved` lower than `30s`, then you **must** also set [`min_checkpoint_frequency`](#min-checkpoint-frequency) to at minimum the same value as `resolved`, because `resolved` messages may be emitted less frequently than `min_checkpoint_frequency`, but cannot be emitted more frequently.<br /><br />Refer to <InternalLink path="changefeed-messages#resolved-messages">Resolved messages</InternalLink> for more detail.                                                                                                                                                                                                                                                                                                                                                                        |
| <a id="schema-change-events" /> `schema_change_events`                                         | `default` / `column_changes`                                               | The type of schema change event that triggers the behavior specified by the `schema_change_policy` option:<ul><li>`default`: Include all <InternalLink path="alter-table#add-column">`ADD COLUMN`</InternalLink> events for columns that have a non-`NULL` <InternalLink path="default-value">`DEFAULT` value</InternalLink> or are <InternalLink path="computed-columns">computed</InternalLink>, and all <InternalLink path="alter-table#drop-column">`DROP COLUMN`</InternalLink> events.</li><li>`column_changes`: Include all schema change events that add or remove any column.</li></ul>Default: `schema_change_events=default`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| <a id="schema-change-policy" /> `schema_change_policy`                                         | `backfill` / `nobackfill` / `stop`                                         | The behavior to take when an event specified by the `schema_change_events` option occurs:<ul><li>`backfill`: When <InternalLink path="changefeed-messages#schema-changes-with-column-backfill">schema changes with column backfill</InternalLink> are finished, output all watched rows using the new schema.</li><li>`nobackfill`: For <InternalLink path="changefeed-messages#schema-changes-with-column-backfill">schema changes with column backfill</InternalLink>, perform no logical backfills. The changefeed will not emit any messages about the schema change. However, if the schema change with column backfill runs inside an <InternalLink path="begin-transaction">explicit transaction</InternalLink> and the <InternalLink path="set-vars">`autocommit_before_ddl` session setting</InternalLink> is disabled, it will emit the entire table to the changefeed.</li><li>`stop`: For <InternalLink path="changefeed-messages#schema-changes-with-column-backfill">schema changes with column backfill</InternalLink>, wait for all data preceding the schema change to be resolved before exiting with an error indicating the timestamp at which the schema change occurred. An `error: schema change occurred at <timestamp>` will display in the `cockroach.log` file.</li></ul>Default: `schema_change_policy=backfill`                                                                                                                                                                                |
| <a id="split-column-families" /> `split_column_families`                                       | N/A                                                                        | Use this option to create a changefeed on a table with multiple <InternalLink path="column-families">column families</InternalLink>. The changefeed will emit messages for each of the table's column families. See <InternalLink path="changefeeds-on-tables-with-column-families">Changefeeds on tables with column families</InternalLink> for more usage detail.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `topic_in_value`                                                                               | <InternalLink path="bool">`BOOL`</InternalLink>                            | Set to include the topic in each emitted row update. This option is automatically set for <InternalLink path="changefeed-sinks#webhook-sink">webhook sinks</InternalLink>. **Note:** `topic_in_value` is not compatible with changefeeds running in [`parquet` format](#format).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `unordered`                                                                                    | N/A                                                                        | Run a changefeed to <InternalLink path="changefeed-sinks">Google Cloud Pub/Sub</InternalLink> without specifying a region.<br /><br />You must include the `unordered` option with [`key_column`](#key-column) in your changefeed creation statement.<br /><br />You cannot use `unordered` with `resolved`, because resolved timestamps may not be correct in unordered mode.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| <a id="updated" /> `updated`                                                                   | N/A                                                                        | Include updated timestamps with each row.<br /><br />If a `cursor` is provided, the "updated" timestamps will match the <InternalLink path="architecture/storage-layer#mvcc">MVCC</InternalLink> timestamps of the emitted rows, and there is no initial scan. If a `cursor` is not provided, the changefeed will perform an initial scan (as of the time the changefeed was created), and the "updated" timestamp for each change record emitted in the initial scan will be the timestamp of the initial scan. Similarly, when a <InternalLink path="changefeed-messages#schema-changes-with-column-backfill">backfill is performed for a schema change</InternalLink>, the "updated" timestamp is set to the first timestamp for when the new schema is valid.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| <a id="virtual-columns" /> `virtual_columns`                                                   | `STRING`                                                                   | Changefeeds omit <InternalLink path="computed-columns">virtual computed columns</InternalLink> from emitted <InternalLink path="changefeed-messages">messages</InternalLink> by default. To maintain the behavior of previous CockroachDB versions where the changefeed would emit <InternalLink path="null-handling">`NULL`</InternalLink> values for virtual computed columns, set `virtual_columns = "null"` when you start a changefeed. <br /><br />You may also define `virtual_columns = "omitted"`, though this is already the default behavior for v22.1+. If you do not set `"omitted"` on a table with virtual computed columns when you create a changefeed, you will receive a warning that changefeeds will filter out virtual computed values. <br /><br />**Default:** `"omitted"`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `webhook_auth_header`                                                                          | <InternalLink path="string">`STRING`</InternalLink>                        | Pass a value (password, token etc.) to the HTTP [Authorization header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Authorization) with a webhook request for a "Basic" HTTP authentication scheme. <br /><br /> Example: With a username of "user" and password of "pwd", add a colon between "user:pwd" and then base64 encode, which results in "dXNlcjpwd2Q=". `WITH webhook_auth_header='Basic dXNlcjpwd2Q='`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `webhook_client_timeout`                                                                       | <InternalLink path="interval">`INTERVAL`</InternalLink>                    | If a response is not recorded from the sink within this timeframe, it will error and retry to connect. Note this must be a positive value. <br /><br />**Default:** `"3s"`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `webhook_sink_config`                                                                          | <InternalLink path="string">`STRING`</InternalLink>                        | Set fields to configure sink batching and retries. The schema is as follows:<br /><br /> `{ "Flush": { "Messages": ..., "Bytes": ..., "Frequency": ..., }, "Retry": {"Max": ..., "Backoff": ..., } }`. <br /><br />**Note** that if either `Messages` or `Bytes` are nonzero, then a non-zero value for `Frequency` must be provided. <br /><br />See <InternalLink path="changefeed-sinks#webhook-sink-configuration">Webhook sink configuration</InternalLink> for more details on using this option.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |

<Note>
  Using the `format=avro`, `envelope=key_only`, and `updated` options together is rejected. `envelope=key_only` prevents any rows with updated fields from being emitted, which makes the `updated` option meaningless.
</Note>

## Files

The files emitted to a sink use the following naming conventions:

* [General file format](#general-file-format)
* [Resolved file format](#resolved-file-format)

<Note>
  The timestamp format is `YYYYMMDDHHMMSSNNNNNNNNNLLLLLLLLLL`.
</Note>

### General file format

```
/[date]/[timestamp]-[uniquer]-[topic]-[schema-id]
```

For example:

```
/2020-04-02/202004022058072107140000000000000-56087568dba1e6b8-1-72-00000000-test_table-1.ndjson
```

When emitting changefeed messages to a <InternalLink path="changefeed-sinks#cloud-storage-sink">cloud storage sink</InternalLink>, you can specify a partition format for your files using the [`partition_format`](#partition-format) query parameter. This will result in the following file path formats:

* `daily`: This is the default option and will follow the same pattern as the previous general file format.

* `hourly`: This will partition into an hourly directory as the changefeed emits messages, like the following:

  ```
  /2020-04-02/20/202004022058072107140000000000000-56087568dba1e6b8-1-72-00000000-test_table-1.ndjson
  ```

* `flat`: This will result in no file partitioning. The cloud storage path you specify when creating a changefeed will store all of the message files with no additional directories created.

### Resolved file format

```
/[date]/[timestamp].RESOLVED
```

For example:

```
/2020-04-04/202004042351304139680000000000000.RESOLVED
```

## Examples

Before running any of the examples in this section it is necessary to <InternalLink path="create-and-configure-changefeeds#enable-rangefeeds">enable the `kv.rangefeed.enabled` cluster setting</InternalLink>. If you are working on a CockroachDB Standard or Basic cluster, this cluster setting is enabled by default.

The following examples show the syntax for managing changefeeds and starting changefeeds with different use cases and features. The [Options](#options) table on this page provides a list of all the available options. For information on sink-specific query parameters and configurations, refer to the <InternalLink path="changefeed-sinks">Changefeed Sinks</InternalLink> page.

You can create an external connection to represent a changefeed sink URI. This allows you to specify the external connection's name in statements rather than the provider-specific URI. For detail on using external connections, see the <InternalLink path="create-external-connection">`CREATE EXTERNAL CONNECTION`</InternalLink> page.

We recommend limiting the number of changefeeds per cluster to 80.

### Create a changefeed connected to a sink

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name, table_name2, table_name3
  INTO 'scheme://host:port'
  WITH updated, resolved;
```

You can connect a changefeed to the following sinks:

* [Amazon MSK](#amazon-msk)  <InternalLink path="changefeed-sinks#amazon-msk">Amazon MSK</InternalLink>
* [Apache Pulsar](#apache-pulsar) (in Preview)  <InternalLink path="changefeed-sinks#apache-pulsar">Apache Pulsar</InternalLink> (in Preview)
* [Azure Event Hubs](#azure-event-hubs)  <InternalLink path="changefeed-sinks#azure-event-hubs">Azure Event Hubs</InternalLink>
* [Cloud Storage](#cloud-storage-sink) / HTTP  <InternalLink path="changefeed-sinks#cloud-storage-sink">Cloud Storage</InternalLink> / HTTP
* [Confluent Cloud](#confluent-cloud)  <InternalLink path="changefeed-sinks#confluent-cloud">Confluent Cloud</InternalLink>
* [Google Cloud Pub/Sub](#google-cloud-pub-sub)  <InternalLink path="changefeed-sinks">Google Cloud Pub/Sub</InternalLink>
* [Kafka](#kafka)  <InternalLink path="changefeed-sinks#kafka">Kafka</InternalLink>
* [Webhook](#webhook-sink)  <InternalLink path="changefeed-sinks#webhook-sink">Webhook</InternalLink>

### Create a changefeed that filters and transforms change data

<InternalLink path="cdc-queries">CDC queries</InternalLink> can filter and transform change data before emitting it to a sink or [a SQL client](#create-a-sinkless-changefeed).

You can adapt a changefeed with CDC queries by including `SELECT` and `WHERE` clauses in your `CREATE` statement:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED INTO 'scheme://host:port'
  WITH updated, resolved
  AS SELECT owner_id, status
  FROM vehicles
  WHERE status = 'lost';
```

CDC queries can only run on a single table per changefeed.

### Create a sinkless changefeed

You can create a changefeed that will send messages to the SQL client rather than a sink:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name, table_name2, table_name3
  WITH updated, resolved;
```

To create a sinkless changefeed using <InternalLink path="cdc-queries">CDC queries</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED WITH updated, resolved
  AS SELECT owner_id, status
  FROM vehicles
  WHERE status = 'lost';
```

### Use an external connection to specify a changefeed sink

<InternalLink path="create-external-connection">External connections</InternalLink> provide a way to define a name for a sink, which you can use instead of the provider-specific URI.

To restrict a user's access to changefeed data and sink credentials, enable the `changefeed.permissions.require_external_connection_sink.enabled` cluster setting. When you enable this setting, users with the <InternalLink path="create-changefeed#required-privileges">`CHANGEFEED` privilege</InternalLink> on a set of tables can only create changefeeds into <InternalLink path="create-external-connection">external connections</InternalLink>.

External connections support all changefeed sinks.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE EXTERNAL CONNECTION kafka_sink
  AS 'kafka://broker.address.com:9092?topic_prefix=bar_&tls_enabled=true&ca_cert={certificate}&sasl_enabled=true&sasl_user={sasl user}&sasl_password={url-encoded password}&sasl_mechanism=SCRAM-SHA-256';
```

In the changefeed statement, you specify the external connection name:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name INTO 'external://kafka_sink'
  WITH resolved;
```

### Filter changefeeds for tables using row-level TTL

Use the `ttl_disable_changefeed_replication` table storage parameter to prevent changefeeds from sending `DELETE` messages issued by row-level TTL jobs for a table. Include the storage parameter when you create or alter the table. For example:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE TABLE tbl (
  id UUID PRIMARY KEY default gen_random_uuid(),
  value TEXT
) WITH (ttl_expire_after = '3 weeks', ttl_job_cron = '@daily', ttl_disable_changefeed_replication = 'true');
```

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER TABLE events SET (ttl_expire_after = '1 year', ttl_disable_changefeed_replication = 'true');
```

You can also widen the scope to the cluster by setting the `sql.ttl.changefeed_replication.disabled` <InternalLink path="cluster-settings">cluster setting</InternalLink> to `true`. This will prevent changefeeds from emitting deletes issued by all TTL jobs on a cluster.

If you want to have a changefeed ignore the storage parameter or cluster setting that disables changefeed replication, you can set the changefeed option `ignore_disable_changefeed_replication` to `true`:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name INTO 'external://changefeed-sink'
  WITH resolved, ignore_disable_changefeed_replication = true;
```

This is useful when you have multiple use cases for different changefeeds on the same table. For example, you have a table with a changefeed streaming changes to another database for analytics workflows in which you do not want to reflect row-level TTL deletes. Secondly, you have a changefeed on the same table for audit-logging purposes for which you need to persist every change through the changefeed.

For guidance on how to filter changefeed messages to emit <InternalLink path="row-level-ttl">row-level TTL</InternalLink> deletes only, refer to <InternalLink path="cdc-queries#reference-ttl-in-a-cdc-query">Change Data Capture Queries</InternalLink>.

### Disallow schema changes on tables to improve changefeed performance

Use the `schema_locked` <InternalLink path="with-storage-parameter">storage parameter</InternalLink> to indicate that a <InternalLink path="online-schema-changes">schema change</InternalLink> is not currently ongoing on a watched table. This allows the changefeed to take a fast path that avoids checking if there are schema changes that could require synchronization between <InternalLink path="how-does-a-changefeed-work">changefeed aggregators</InternalLink>. This helps to decrease the latency between a write committing to a table and it emitting to the <InternalLink path="changefeed-sinks">changefeed's sink</InternalLink>.

Enable `schema_locked` on the watched table with the <InternalLink path="alter-table">`ALTER TABLE`</InternalLink> statement:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER TABLE watched_table SET (schema_locked = true);
```

CockroachDB attempts to automatically unset `schema_locked` before performing a schema change and reapply it when done. However, certain schema changes (such as `ALTER TABLE ... SET LOCALITY`) cannot automatically unset it. For these cases, you must manually unlock the table with `schema_locked = false`, complete the schema change, and then lock the table again with `schema_locked = true`. The changefeed will run as normal while `schema_locked` is unset, but it will not benefit from the performance optimization.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER TABLE watched_table SET (schema_locked = false);
```

### Manage a changefeed

For changefeed jobs, use <InternalLink path="show-jobs">`SHOW CHANGEFEED JOBS`</InternalLink> to check the status:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SHOW CHANGEFEED JOBS;
```

Use the following SQL statements to pause, resume, or cancel a changefeed.

#### Pause a changefeed

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
PAUSE JOB job_id;
```

For more information, see <InternalLink path="pause-job">`PAUSE JOB`</InternalLink>.

#### Resume a paused changefeed

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
RESUME JOB job_id;
```

For more information, see <InternalLink path="resume-job">`RESUME JOB`</InternalLink>.

#### Cancel a changefeed

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CANCEL JOB job_id;
```

For more information, see <InternalLink path="cancel-job">`CANCEL JOB`</InternalLink>.

#### Modify a changefeed

To modify a changefeed, <InternalLink path="create-and-configure-changefeeds#pause">pause</InternalLink> the job and then use:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER CHANGEFEED job_id {ADD table DROP table SET option UNSET option};
```

You can add new table targets, remove them, set new <InternalLink path="create-changefeed#options">changefeed options</InternalLink>, and unset them.

For more information, see <InternalLink path="alter-changefeed">`ALTER CHANGEFEED`</InternalLink>.

#### Configuring all changefeeds

It is useful to be able to pause all running changefeeds during troubleshooting, testing, or when a decrease in CPU load is needed.

To pause all running changefeeds:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
PAUSE JOBS (WITH x AS (SHOW CHANGEFEED JOBS) SELECT job_id FROM x WHERE status = ('running'));
```

This will change the status for each of the running changefeeds to `paused`, which can be verified with <InternalLink path="show-jobs#show-changefeed-jobs">`SHOW CHANGEFEED JOBS`</InternalLink>.

To resume all running changefeeds:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
RESUME JOBS (WITH x AS (SHOW CHANGEFEED JOBS) SELECT job_id FROM x WHERE status = ('paused'));
```

This will resume the changefeeds and update the status for each of the changefeeds to `running`.

### Start a new changefeed where another ended

In some situations, you may want to start a changefeed where a previously running changefeed ended. For example, a changefeed could encounter an error it cannot recover from, such as when a <InternalLink path="create-and-configure-changefeeds#known-limitations">`TRUNCATE` is performed</InternalLink>, and you need to restart the changefeed.

1. Use <InternalLink path="show-jobs#show-changefeed-jobs">`SHOW CHANGEFEED JOB`</InternalLink> to find the <InternalLink path="monitor-and-debug-changefeeds#monitor-a-changefeed">high-water timestamp</InternalLink> for the ended changefeed:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   SHOW CHANGEFEED JOB {job_id};
   ```

   ```
           job_id       | ... |      high_water_timestamp      | ...
   +--------------------+ ... +--------------------------------+ ...
     383870400694353921 | ... | 1537279405671006870.0000000000 | ...
   (1 row)
   ```

<Note>
  If a changefeed has failed, you must restart the changefeed from a timestamp **after** the event that caused the failure.
</Note>

1. Use the `high_water_timestamp` to start the new changefeed:

   ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   CREATE CHANGEFEED FOR TABLE table_name, table_name2, table_name3
     INTO 'scheme//host:port'
     WITH cursor = '<high_water_timestamp';
   ```

When you use the `cursor` option to start a changefeed, it will not perform an [initial scan](#initial-scan).

### Create a changefeed with an S3 storage class

To associate the changefeed message files with a <InternalLink path="use-cloud-storage#amazon-s3-storage-classes">specific storage class</InternalLink> in your Amazon S3 bucket, use the `S3_STORAGE_CLASS` parameter with the class. For example, the following S3 connection URI specifies the `INTELLIGENT_TIERING` storage class:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name
  INTO 's3://{BUCKET NAME}?AWS_ACCESS_KEY_ID={KEY ID}&AWS_SECRET_ACCESS_KEY={SECRET ACCESS KEY}&S3_STORAGE_CLASS=INTELLIGENT_TIERING'
  WITH resolved;
```

Use the parameter to set one of these [storage classes](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html#AmazonS3-PutObject-request-header-StorageClass) listed in Amazon's documentation. For more general usage information, see Amazon's [Using Amazon S3 storage classes](https://docs.aws.amazon.com/AmazonS3/latest/userguide/storage-class-intro.html) documentation.

### Define a key to determine the changefeed sink partition

With the [`key_column`](#key-column) option, you can define the key used in message metadata that determines the partition for the changefeed message at your <InternalLink path="changefeed-sinks">downstream sink</InternalLink>. This option overrides the default <InternalLink path="primary-key">primary key</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
CREATE CHANGEFEED FOR TABLE table_name
  INTO 'external://kafka-sink'
  WITH key_column='partition_column', unordered;
```

`key_column` does not preserve ordering of messages from CockroachDB to the downstream sink, therefore you **must** include the [`unordered`](#unordered) option. It does not affect per-key <InternalLink path="changefeed-messages#ordering-and-delivery-guarantees">ordering guarantees</InternalLink> or the output of [`key_in_value`](#key-in-value).

## See also

* <InternalLink path="change-data-capture-overview">Change Data Capture Overview</InternalLink>
* <InternalLink path="sql-statements">SQL Statements</InternalLink>
* <InternalLink path="ui-cdc-dashboard">Changefeed Dashboard</InternalLink>
* <InternalLink path="monitor-and-debug-changefeeds">Monitor and Debug Changefeeds</InternalLink>
