﻿---
title: Compare cross-project search and cross-cluster search
description: Compare cross-project search (CPS) and cross-cluster search (CCS) syntax, behavior, and query patterns to help you transition from CCS to CPS.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cps-compared-to-ccs
products:
  - Elasticsearch
applies_to:
  - Elastic Cloud Serverless: Preview
  - Elastic Stack: Generally available
---

# Compare cross-project search and cross-cluster search
Cross-project search (CPS) provides Elastic Cloud Serverless with cross-project search capabilities similar to [cross-cluster search](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/explore-analyze/cross-cluster-search) (CCS).
Both features let you search data across multiple deployments from a single request, but the query syntax, default scope, and configuration requirements are different. In general, CPS reduces setup overhead and simplifies queries by searching all linked projects by default.
This page highlights the key differences and shows side-by-side query examples to help you transition from CCS to CPS.

## Key differences

The following sections describe how CCS and CPS differ in availability, setup, query syntax, and scope behavior.
<definitions>
  <definition term="Availability">
    CCS is for Elasticsearch clusters on self-managed, Elastic Cloud Enterprise, Elastic Cloud on Kubernetes, and Elastic Cloud Hosted deployments. CPS is for Elastic Cloud Serverless projects. Use CCS when searching across clusters and CPS when searching across serverless projects.
  </definition>
  <definition term="Prerequisites and configuration">
    CCS requires remote cluster connectivity and security configuration across clusters. CPS only requires project linking in the Elastic Cloud UI, with no transport-layer setup. For details, refer to [CCS prerequisites](/elastic/docs-content/tree/main/explore-analyze/cross-cluster-search#_prerequisites) and [CPS prerequisites](/elastic/docs-content/tree/main/deploy-manage/cross-project-search-config#cps-prerequisites).
  </definition>
  <definition term="Cross-environment support">
    CCS can connect clusters across organizations and infrastructure boundaries. CPS is limited to projects within the same Elastic Cloud organization.
  </definition>
  <definition term="Default search scope">
    In CCS, a query runs against the **local cluster only** unless you explicitly include remote clusters. In CPS, a query runs against the **origin project and all linked projects** by default, so you don't need to rewrite queries as you link additional projects.
  </definition>
  <definition term="Naming">
    CCS uses **remote cluster names** as prefixes. CPS uses **project aliases**. Project aliases are derived from the project's [connection alias](/elastic/docs-content/tree/main/deploy-manage/deploy/elastic-cloud/project-settings#elasticsearch-manage-project-connection-aliases), while remote cluster names come from the cluster settings configuration.
  </definition>
  <definition term="Referencing the local cluster or origin project">
    In CCS, the local cluster appears as `(local)` in search responses and has no explicit prefix in query expressions. If no prefix is provided, the query runs against the local cluster only. In CPS, the origin project appears as `_origin` in responses and can be targeted with the `_origin:` prefix in query expressions.
  </definition>
  <definition term="Missing resources">
    In CCS, searching for an index that doesn't exist on a cluster returns an error unless `ignore_unavailable` is set to `true`. In CPS, unqualified expressions succeed as long as the target resource exists in at least one searched project. Projects that don't have the resource are silently skipped, which means queries work without error even when projects have different index sets. Qualified expressions behave like CCS: if you target a specific project and the resource is missing, the request returns an error. For details, refer to [Search in CPS](/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-search#search-expressions).
  </definition>
  <definition term="Selecting which clusters or projects to search">
    In CCS, you select which clusters to search by listing cluster names or using wildcards on cluster names in the index expression. CPS introduces [project routing](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-project-routing), which selects projects based on project metadata, including project aliases, cloud provider, region, and custom tags. Project routing supports boolean logic (`AND`, `OR`, `NOT`), grouping with parentheses, and reusable [named expressions](/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-project-routing#named-routing-expressions). Routing is evaluated before the query runs, so excluded projects are never searched. CPS also provides a [scope selector](/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-manage-scope#cps-in-kibana) in Kibana apps for controlling which projects are searched without modifying queries.
  </definition>
</definitions>


## Syntax comparison quick reference

The following tables summarize how common search tasks translate between CCS and CPS for Query DSL and ES|QL. The CCS examples assume a local cluster with a remote cluster named cluster_one. The CPS examples assume an origin project with a linked project whose alias is linked_project.
For full examples, refer to the [examples](#examples) section.

### `_search`


| Task                                                       | CCS                                              | CPS                                             |
|------------------------------------------------------------|--------------------------------------------------|-------------------------------------------------|
| [Search local/origin only](#ex-local-origin)               | `GET my-index/_search`                           | `GET _origin:my-index/_search`                  |
| [Search one remote/linked](#ex-one-remote)                 | `GET cluster_one:my-index/_search`               | `GET linked_project:my-index/_search`           |
| [Search all](#ex-search-all)                               | `GET my-index,*:my-index/_search`                | `GET my-index/_search` (default)                |
| [Exclude one](#ex-exclude)                                 | `GET my-index,*:my-index,-cluster_one:*/_search` | `GET my-index,-linked_project:*/_search`        |
| [Route by metadata](#ex-route-tags)                        | Not available                                    | `project_routing`                               |
| [Identify origin in responses](#ex-identify-origin)        | `(local)` in `_clusters`; no prefix in `_index`  | `_origin` in `_clusters`; no prefix in `_index` |
| [Identify remote/linked in responses](#ex-identify-origin) | `cluster_one:my-index` in `_index`               | `linked_project:my-index` in `_index`           |


### ES|QL


| Task                                                       | CCS                                         | CPS                                            |
|------------------------------------------------------------|---------------------------------------------|------------------------------------------------|
| [Search local/origin only](#ex-local-origin)               | `FROM my-index`                             | `FROM _origin:my-index`                        |
| [Search one remote/linked](#ex-one-remote)                 | `FROM cluster_one:my-index`                 | `FROM linked_project:my-index`                 |
| [Search all](#ex-search-all)                               | `FROM my-index,cluster_one:my-index`        | `FROM my-index` (default)                      |
| [Exclude one](#ex-exclude)                                 | `FROM my-index,*:my-index,-cluster_one:*`   | `FROM my-index,-linked_project:*`              |
| [Route by metadata](#ex-route-tags)                        | Not available                               | `SET project_routing`                          |
| [Identify origin in responses](#ex-identify-origin)        | No prefix in `METADATA _index`              | No prefix in `METADATA _index`                 |
| [Identify remote/linked in responses](#ex-identify-origin) | `cluster_one:my-index` in `METADATA _index` | `linked_project:my-index` in `METADATA _index` |


## Examples

The following examples compare equivalent tasks in CCS and CPS. The CCS examples assume a local cluster with a remote cluster named `cluster_one`. The CPS examples assume an origin project with a linked project whose alias is `linked_project`.

### Search the local cluster or origin project only

Restrict a query to a single cluster or project without including results from remote clusters or linked projects. Use this when you need to isolate results to one cluster or project, for example when debugging a local issue.
<tab-set>
  <tab-item title="CCS">
    In CCS, a plain index name targets the local cluster only. No prefix is needed.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM my-index
    | LIMIT 10
    ```
  </tab-item>

  <tab-item title="CPS">
    In CPS, a plain index name searches all projects. To restrict to the origin project, use the `_origin:` prefix.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM _origin:my-index
    | LIMIT 10
    ```
  </tab-item>
</tab-set>


### Search one remote cluster or linked project

Target a specific remote cluster or linked project. Use this when you want to check data from a single cluster or project without pulling in results from others.
<tab-set>
  <tab-item title="CCS">
    Prefix the index with the remote cluster name.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM cluster_one:my-index
    | LIMIT 10
    ```
  </tab-item>

  <tab-item title="CPS">
    Prefix the index with the linked project alias.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM linked_project:my-index
    | LIMIT 10
    ```
  </tab-item>
</tab-set>


### Search local and all remotes, or all projects

Search an index across every available cluster or project at once. Use this when you want to correlate data from all clusters or projects, for example during an incident investigation that spans multiple clusters or projects.
<tab-set>
  <tab-item title="CCS">
    List the local index and each remote cluster explicitly, or use a wildcard for remote clusters.**`_search`**
    ```json
    ```
    Or, using a wildcard to include all remote clusters:
    ```json
    ```
    **ES|QL**List each cluster explicitly in the `FROM` command.
    ```esql
    FROM my-index,cluster_one:my-index
    | LIMIT 10
    ```
  </tab-item>

  <tab-item title="CPS">
    Use the index name with no prefix. All linked projects are searched by default.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM my-index
    | LIMIT 10
    ```
  </tab-item>
</tab-set>


### Exclude clusters or projects

Search broadly but skip one or more clusters or projects. Use this when you need results from most clusters or projects but want to leave some out, for example to exclude development or staging projects. In CPS, because all projects are searched by default, you only need to specify what to skip.
<tab-set>
  <tab-item title="CCS">
    Prefix the cluster name with `-` and use `*` in the index position. You can chain multiple exclusions.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM my-index,*:my-index,-cluster_one:*,-cluster_two:*
    | LIMIT 10
    ```
  </tab-item>

  <tab-item title="CPS">
    Use the same `-` prefix with the project alias. An exclusion pattern requires a preceding inclusion pattern. You can exclude multiple projects.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM my-index,-linked_project:*,-staging_project:*
    | LIMIT 10
    ```
  </tab-item>
</tab-set>


### Identify where a document came from

Determine which cluster or project returned a specific document. Use this when you want to trace a result back to its source when searching across multiple clusters or projects.
In both CCS and CPS, the `_index` field in the response indicates where each document originated.
<tab-set>
  <tab-item title="CCS">
    Documents from a remote cluster include the cluster name as a prefix: `cluster_one:my-index`. Documents from the local cluster have no prefix: `my-index`.**`_search`**
    ```json
    ```
    Example response:
    ```json
    {
      "hits": {
        "hits": [
          { "_index": "my-index", "_id": "1", "_source": { "message": "local doc" } },
          { "_index": "cluster_one:my-index", "_id": "2", "_source": { "message": "remote doc" } }
        ]
      },
      ...
    }
    ```
    **ES|QL**Use `METADATA _index` to include the field:
    ```esql
    FROM my-index,cluster_one:my-index METADATA _index
    | KEEP _index, message
    | LIMIT 10
    ```
    Example results:
    ```json
    {
      "columns": [
        { "name": "_index", "type": "keyword" },
        { "name": "message", "type": "keyword" }
      ],
      "values": [
        [ "my-index", "local doc" ],
        [ "cluster_one:my-index", "remote doc" ]
      ]
    }
    ```
  </tab-item>

  <tab-item title="CPS">
    Documents from a linked project include the project alias as a prefix: `linked_project:my-index`. Documents from the origin project have no prefix: `my-index`.**`_search`**
    ```json
    ```
    Example response:
    ```json
    {
      "hits": {
        "hits": [
          { "_index": "my-index", "_id": "1", "_source": { "message": "origin doc" } },
          { "_index": "linked_project:my-index", "_id": "2", "_source": { "message": "linked doc" } }
        ]
      },
      ...
    }
    ```
    **ES|QL**Use `METADATA _index` to include the field:
    ```esql
    FROM my-index METADATA _index
    | KEEP _index, message
    | LIMIT 10
    ```
    Example results:
    ```json
    {
      "columns": [
        { "name": "_index", "type": "keyword" },
        { "name": "message", "type": "keyword" }
      ],
      "values": [
        [ "my-index", "origin doc" ],
        [ "linked_project:my-index", "linked doc" ]
      ]
    }
    ```
    You can also use [project tags](/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-tags#tag-queries) like `_project._alias` in `METADATA` (ES|QL) or `fields` (`_search`) to identify the source project directly, without parsing the `_index` prefix.
  </tab-item>
</tab-set>


### Route by metadata

Route a query to a subset of projects based on project metadata like cloud provider, region, or custom tags, rather than using the index expression alone. This capability is new in CPS and has no CCS equivalent.
<tab-set>
  <tab-item title="CCS">
    In CCS, you select clusters by naming them in the index expression. You can't route queries based on cluster metadata.**`_search`**
    ```json
    ```
    **ES|QL**
    ```esql
    FROM cluster_one:logs-*,cluster_two:logs-*
    | STATS COUNT(*) BY service.name
    ```
  </tab-item>

  <tab-item title="CPS">
    In CPS, use [`project_routing`](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-project-routing) to select projects dynamically. Project routing supports boolean logic (`AND`, `OR`, `NOT`) and wildcards.**`_search`**
    ```json

    {
      "project_routing": "_csp:aws AND _region:us*"
    }
    ```
    **ES|QL**
    ```esql
    SET project_routing="_csp:aws AND _region:us*";
    FROM logs-*
    | STATS COUNT(*) BY service.name
    ```
    You can also define reusable [named expressions](/elastic/docs-content/tree/main/explore-analyze/cross-project-search/cross-project-search-project-routing#named-routing-expressions) and reference them with the `@` prefix:**`_search`**
    ```json

    {
      "project_routing": "@us-aws"
    }
    ```
    **ES|QL**
    ```esql
    SET project_routing="@us-aws";
    FROM logs-*
    | STATS COUNT(*) BY service.name
    ```
  </tab-item>
</tab-set>


## Learn more about Serverless

If you're evaluating Elastic Cloud Serverless, refer to the following resources:
- [Compare Elastic Cloud Hosted and Serverless](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/deploy-manage/deploy/elastic-cloud/differences-from-other-elasticsearch-offerings): Learn more about the differences between Elastic Cloud Serverless and other Elasticsearch offerings.
- [Elastic Cloud Serverless](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/deploy-manage/deploy/elastic-cloud/serverless): An introduction to Elastic Cloud Serverless and its features.
- [Start a free trial](https://cloud.elastic.co/serverless-registration): Explore the product with a free trial of Elastic Cloud Serverless.
- [Migrate your Elasticsearch data](https://docs-v3-preview.elastic.dev/elastic/docs-content/tree/main/manage-data/migrate): Learn about options for migrating between Elasticsearch deployment types, including how to migrate to Elastic Cloud Serverless.