﻿---
title: Query streams
description: Query streams are virtual, read-only streams defined by an ES|QL query that let you create reusable named views of your data without affecting ingestion.
url: https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/query-streams
products:
  - Elastic Cloud Enterprise
  - Elastic Cloud Hosted
  - Elastic Cloud Serverless
  - Elastic Cloud on Kubernetes
  - Elastic Observability
  - Elastic Stack
  - Elasticsearch
  - Kibana
applies_to:
  - Elastic Cloud Serverless: Preview
  - Elastic Stack: Preview since 9.4
---

# Query streams
Query streams are virtual, read-only streams defined by an ES|QL query. Unlike classic and wired streams that store ingested data, query streams resolve at query-time — no data is written to storage, and no ingestion pipeline, routing rules, or retention policies are affected.
Use query streams to create persistent, named views of your data that you can attach assets to, organize hierarchically, and reference by name in ES|QL queries.

## Root and nested query streams

Query streams can be **root-level** or **nested**:
- **Root-level query streams** reference any existing stream in the `FROM` clause and stand alone in the stream hierarchy.
- **Nested query streams** are logically grouped under a parent stream. The ES|QL query must reference the parent stream. Nesting organizes streams visually without affecting data routing or storage.


## Create a query stream


### Create a root-level query stream

1. Go to **Streams** in the navigation menu or use the [global search field](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/explore-analyze/find-and-organize/find-apps-and-objects).
2. Select **Create stream**, then choose **Query stream**.
3. Enter a name for the stream.
4. Write an ES|QL query that defines the data this stream represents. The query must reference at least one existing stream.
5. Preview the query results, then select **Save**.


### Create a nested query stream

1. Go to **Streams** and open a wired stream.
2. Go to the **Partitioning** tab.
3. Select **Add child stream**, then choose **Query stream**.
4. Enter a name and write the ES|QL query. The query should reference the parent stream.
5. Select **Save**.


## Query a query stream

When you create a query stream named `logs.nginx`, the system creates an ES|QL view named `$.logs.nginx`. The `$.` prefix keeps query stream views in a separate namespace from ingest streams, so they never shadow or interfere with your underlying data streams.
To query a query stream directly in ES|QL, use its prefixed view name:
```esql
FROM $.logs.nginx
| WHERE status_code >= 500
```

When you open a query stream in Discover, the query is pre-populated automatically using the correct prefixed name.

## What you can do with query streams

Query streams are read-only views, so features that modify ingestion, storage, or routing aren't available. The following table shows which Streams features apply:

| Feature                                                                                                                                                 | Available                                     |                                                               |
|---------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------|---------------------------------------------------------------|
| [Significant events](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/significant-events)  | Yes                                           |                                                               |
| [Schema](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/schema) — add field descriptions | Yes — field types are derived from ES         | QL output and can't be changed, but descriptions can be added |
| Attach dashboards, alerts, SLOs                                                                                                                         | Yes                                           |                                                               |
| [Partitioning](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/partitioning)              | No — query streams don't route ingested data  |                                                               |
| [Processing](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/extract)                     | No — query streams don't run ingest pipelines |                                                               |
| [Retention](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/retention)                    | No — query streams don't store data           |                                                               |
| [Data quality](https://docs-v3-preview.elastic.dev/elastic/docs-content/pull/6994/solutions/observability/streams/management/data-quality)              | No — query streams don't store data           |                                                               |


## Query streams vs ES|QL in Discover

You can write ES|QL queries directly in Discover without creating a query stream. The right choice depends on whether you need the result to persist as a governed product entity.

|                        | Query stream                                                        | ES                                                | QL in Discover                     |
|------------------------|---------------------------------------------------------------------|---------------------------------------------------|------------------------------------|
| **Persistence**        | Saved as a named, reusable entity                                   | Session-only unless saved as a saved search       |                                    |
| **Governance**         | Named, owned, appears in Streams listing                            | None                                              |                                    |
| **Asset attachment**   | Dashboards, alerts, SLOs                                            | Not supported                                     |                                    |
| **Significant events** | Yes                                                                 | No                                                |                                    |
| **Stream hierarchy**   | Appears in the Streams listing, can be nested under a parent stream | Not part of stream hierarchy                      |                                    |
| **ES**                 | QL reference                                                        | Queryable by prefixed name (`FROM $.stream-name`) | Not directly referenceable by name |
| **Best for**           | Persistent views you need to monitor, share, or attach alerts to    | Exploratory or one-off analysis                   |                                    |


### When to create a query stream

Create a query stream when you need to:
- **Attach an alert, SLO, or dashboard** to a specific slice of your data.
- **Monitor significant events** — significant events discovery runs against the query on a schedule.
- **Share a reusable data view** — teammates can find the stream by name in the Streams listing or reference it in ES|QL.
- **Organize data logically** — nest the stream under a parent to keep related views grouped without changing ingestion.


### When to use ES|QL in Discover

Use ES|QL directly in Discover when you're:
- Exploring data to understand its shape before committing to a view.
- Running a one-off analysis you don't need to revisit.
- Iterating on a query before deciding whether to save it as a stream.