NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Elasticsearch List Indices: _cat/indices, GET Indices, and Filtering Patterns

To list indices in Elasticsearch, the most common command is GET /_cat/indices?v, which returns a human-readable table of every index along with its health, document count, and size. For JSON output that scripts can parse, use GET /_all/_settings or GET /*. For just the names, GET /_cat/indices?h=index is the cleanest option. The same APIs work on Elasticsearch 7.x, 8.x, and 9.x, and on OpenSearch with identical syntax.

This guide covers every way to enumerate indices, how to filter and format the output, what to do about hidden and system indices, and how to wire this into client libraries.

The Quick Answer: _cat/indices

GET /_cat/indices?v

Output looks like this:

health status index   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   logs    abcXYZ123              3   1   12450123   8421         5.2gb      2.6gb
yellow open   metrics defGHI456              1   1   873244     12           420mb      420mb

The ?v flag adds the column header row. Without it, you get just the data.

Useful Flags

  • ?h=index,docs.count,store.size: pick the columns you want.
  • ?s=store.size:desc: sort. The example sorts by storage descending so the largest indices show first.
  • ?bytes=gb: control the unit (b, kb, mb, gb, tb).
  • ?format=json: return JSON instead of the text table.
  • ?expand_wildcards=all: include hidden indices (defaults to open,closed, hidden excluded).
  • ?include_unloaded_segments=true: include data from unloaded segments. Slower, but accurate on clusters with frozen indices.
  • ?health=red: filter to a particular health status.

A common workflow command for finding the largest indices on a cluster:

GET /_cat/indices?v&s=store.size:desc&bytes=gb&h=index,health,pri,rep,docs.count,store.size

Listing a Subset by Pattern

GET /_cat/indices/logs-*?v
GET /_cat/indices/logs-2026-*,metrics-*?v

The path supports comma-separated names and wildcards. Combined with expand_wildcards, you can be precise about which kinds of indices are matched. To exclude an index pattern, use the negation prefix:

GET /_cat/indices/logs-*,-logs-2025-*

Listing as JSON

For scripts and dashboards, the text table is not ideal. Use either format=json on _cat/indices, or the indices API:

GET /_cat/indices?format=json&pretty
GET /logs-*

GET /<pattern> returns full index metadata (settings, mappings, aliases) per index. It is heavier than _cat/indices and slower on clusters with many indices. Use it when you need configuration, not just a roll call.

For just settings:

GET /_all/_settings

For just aliases:

GET /_alias
GET /_alias/<alias-name>

Hidden and System Indices

Indices whose names start with a dot (.security, .kibana_*, .monitoring-*) are considered hidden or system indices. By default, _cat/indices does not list them. To include hidden indices:

GET /_cat/indices?expand_wildcards=open,closed,hidden
# or, all kinds at once:
GET /_cat/indices?expand_wildcards=all

Be careful: most system indices are managed by Elasticsearch or its features (Security, Fleet, Kibana). Never delete or directly modify them. Use this listing mode for observability, not for cleanup.

Listing Data Stream Backing Indices

Data streams expose backing indices that look like .ds-<stream-name>-<date>-<generation>. They are hidden by default. To see them:

GET /_cat/indices/.ds-*?expand_wildcards=hidden&v

To list data streams themselves rather than their backing indices:

GET /_data_stream
GET /_data_stream/logs-*

Listing From a Client Library

Python (elasticsearch-py)

# Names only
indices = es.cat.indices(h="index", format="json")
names = [i["index"] for i in indices]

# Full metadata
all_indices = es.indices.get(index="*")

JavaScript (@elastic/elasticsearch)

const { body } = await client.cat.indices({ h: 'index', format: 'json' })
const names = body.map(i => i.index)

curl + jq

curl -s "$ES/_cat/indices?format=json" | jq -r '.[].index'

Common Listing Patterns

Find indices missing replicas

GET /_cat/indices?v&h=index,rep&format=json

Filter the result for "rep": "0".

Find oversized indices (likely candidates for shrinking, rollover, or splitting)

GET /_cat/indices?v&s=pri.store.size:desc&bytes=gb&h=index,pri,pri.store.size

Find unhealthy indices

GET /_cat/indices?v&health=red
GET /_cat/indices?v&health=yellow

A yellow health on a single-node development cluster is normal (replicas are unassigned because there is no second node to place them on). On a multi-node production cluster, yellow or red means action is required.

Find indices without an ILM policy

There is no built-in flag for this. The pattern is to compare GET /<pattern>/_settings against the policies you expect, or to use the ILM explain API:

GET /<pattern>/_ilm/explain

Any index where managed: false is not under ILM management.

Performance Caveats

  • _cat/indices reads cluster state plus shard stats. On clusters with tens of thousands of indices, it can take many seconds. Cache the output if you are calling it repeatedly.
  • include_unloaded_segments=true queries underlying frozen storage and is slower than the default.
  • GET /* returning all mappings for every index can be megabytes of payload on a large cluster. Restrict by pattern wherever you can.

How Pulse Helps With Index Inventories

Listing indices is the easy part; knowing which indices on a real cluster are oversized, missing replicas, missing ILM coverage, holding stale data, or quietly burning disk is the hard part. Pulse continuously inventories Elasticsearch and OpenSearch clusters and surfaces the indices that need attention: index-size outliers, indices without ILM, indices on the wrong tier, and orphan indices no application is reading from. Teams running Pulse stop having to write ad-hoc _cat/indices queries to answer "what do we have?". Connect your cluster to Pulse and let the inventory work happen automatically.

Frequently Asked Questions

Q: How do I see just the names of all indices?

GET /_cat/indices?h=index

This returns one index name per line.

Q: How do I list indices in a specific date range?

If your index naming includes dates (logs-2026-05-13), use a wildcard:

GET /_cat/indices/logs-2026-05-*

For more precise queries, list by creation date with the JSON form:

GET /_cat/indices?h=index,creation.date.string&format=json&s=creation.date:desc

Q: Why does _cat/indices not show my .kibana indices?

By default, hidden and system indices are excluded. Add ?expand_wildcards=all.

Q: How can I list indices sorted by size?

GET /_cat/indices?v&s=store.size:desc&bytes=gb

pri.store.size is the primary-only size; store.size includes replicas.

Q: Is there a difference between _cat/indices and GET /_aliases?

Yes. _cat/indices lists indices and their stats. GET /_aliases lists alias-to-index mappings. An alias is not an index, so an alias name will not appear in _cat/indices directly, only the underlying indices will.

Q: Can I list closed indices?

Yes:

GET /_cat/indices?expand_wildcards=closed

Closed indices show with status close and have no document or storage stats.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.