ELK Stack — Aliases
Aliases
An alias is an alternate name that points to one or more indices. Your application queries the alias instead of the real index name, which gives you the flexibility to swap, filter, or restructure indices behind the scenes without any client-side changes.
Why Use Aliases
- Zero-downtime reindexing — Reindex into a new index, then swap the alias.
- Filtered views — Create an alias that only exposes a subset of data.
- Simplified querying — Query
logsinstead oflogs-2026.03.28,logs-2026.03.29,.... - Write routing — Direct writes to a specific index through a write alias.
Creating an Alias
Using the _aliases API
The _aliases endpoint supports atomic, multi-action operations:
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "logs-2026.04.01",
"alias": "logs-today"
}
}
]
}'
{
"acknowledged": true
}
Using the Index Alias Endpoint
curl -s -X PUT "localhost:9200/logs-2026.04.01/_alias/logs-today"
{
"acknowledged": true
}
Listing Aliases
All Aliases
curl -s -X GET "localhost:9200/_aliases?pretty"
{
"logs-2026.04.01": {
"aliases": {
"logs-today": {}
}
},
"logs-2026.03.31": {
"aliases": {}
}
}
Aliases for a Specific Index
curl -s -X GET "localhost:9200/logs-2026.04.01/_alias?pretty"
{
"logs-2026.04.01": {
"aliases": {
"logs-today": {}
}
}
}
Check If an Alias Exists
curl -s -o /dev/null -w "%{http_code}" -X HEAD "localhost:9200/_alias/logs-today"
# Returns 200 if exists, 404 if not
Deleting an Alias
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"remove": {
"index": "logs-2026.04.01",
"alias": "logs-today"
}
}
]
}'
{
"acknowledged": true
}
Alias Pointing to Multiple Indices
An alias can span multiple indices. Searches against the alias will query all of them:
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{ "add": { "index": "logs-2026.03.30", "alias": "logs-last-3-days" } },
{ "add": { "index": "logs-2026.03.31", "alias": "logs-last-3-days" } },
{ "add": { "index": "logs-2026.04.01", "alias": "logs-last-3-days" } }
]
}'
{
"acknowledged": true
}
You can also use a wildcard pattern:
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "logs-2026.03.*",
"alias": "logs-march"
}
}
]
}'
{
"acknowledged": true
}
Filtered Aliases
A filtered alias only exposes documents that match a given query. This is useful for multi-tenant setups where each tenant should only see their own data.
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "orders",
"alias": "orders-us",
"filter": {
"term": {
"country": "US"
}
}
}
}
]
}'
{
"acknowledged": true
}
Now querying orders-us returns only US orders:
curl -s -X GET "localhost:9200/orders-us/_search?pretty" \
-H "Content-Type: application/json" \
-d '{
"query": { "match_all": {} }
}'
{
"hits": {
"total": { "value": 1524, "relation": "eq" },
"hits": [
{
"_index": "orders",
"_id": "o1001",
"_source": {
"order_id": "o1001",
"country": "US",
"amount": 129.99
}
}
]
}
}
Alias with Routing
Routing controls which shard a document is stored on. You can attach routing to an alias so all reads and writes through that alias go to a specific shard:
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "orders",
"alias": "orders-tenant-42",
"filter": {
"term": { "tenant_id": 42 }
},
"routing": "42"
}
}
]
}'
{
"acknowledged": true
}
You can also set search_routing and index_routing independently:
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "orders",
"alias": "orders-tenant-99",
"search_routing": "99",
"index_routing": "99"
}
}
]
}'
{
"acknowledged": true
}
Write Index
When an alias points to multiple indices, you must designate exactly one as the write index. All index (write) requests through the alias go to that index.
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{
"add": {
"index": "logs-000001",
"alias": "logs-write",
"is_write_index": true
}
},
{
"add": {
"index": "logs-000002",
"alias": "logs-write"
}
}
]
}'
{
"acknowledged": true
}
Searches against logs-write query both indices. Writes go to logs-000001.
Zero-Downtime Reindexing with Alias Swap
This is the most common real-world use of aliases. The pattern:
- Your application reads and writes through alias
products. - You create a new index
products-v2with updated mappings. - You reindex data from
products-v1toproducts-v2. - You atomically swap the alias.
Step 1: Setup — Application Uses the Alias
# Create v1 index
curl -s -X PUT "localhost:9200/products-v1" \
-H "Content-Type: application/json" \
-d '{
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "float" }
}
}
}'
# Point alias to v1
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{ "add": { "index": "products-v1", "alias": "products", "is_write_index": true } }
]
}'
Step 2: Create v2 with New Mappings
curl -s -X PUT "localhost:9200/products-v2" \
-H "Content-Type: application/json" \
-d '{
"mappings": {
"properties": {
"name": { "type": "text" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"category": { "type": "keyword" }
}
}
}'
Step 3: Reindex
curl -s -X POST "localhost:9200/_reindex" \
-H "Content-Type: application/json" \
-d '{
"source": { "index": "products-v1" },
"dest": { "index": "products-v2" }
}'
{
"took": 1245,
"total": 50000,
"updated": 0,
"created": 50000,
"deleted": 0,
"failures": []
}
Step 4: Atomic Alias Swap
curl -s -X POST "localhost:9200/_aliases" \
-H "Content-Type: application/json" \
-d '{
"actions": [
{ "remove": { "index": "products-v1", "alias": "products" } },
{ "add": { "index": "products-v2", "alias": "products", "is_write_index": true } }
]
}'
{
"acknowledged": true
}
Both actions execute atomically — there is no moment where the alias is missing. Your application experiences zero downtime.
Step 5: Clean Up
curl -s -X DELETE "localhost:9200/products-v1"
{
"acknowledged": true
}
Aliases vs Data Streams
| Feature | Aliases | Data Streams |
|---|---|---|
| Use case | General purpose | Append-only time-series |
| Write target | Configurable write index | Automatic (latest backing index) |
| Rollover | Manual or ILM | Automatic with ILM |
| Update / delete | Supported | Only via update-by-query on backing index |
| Setup complexity | Low | Requires matching index template |
Use data streams for logs and metrics. Use aliases when you need update/delete support or custom routing.
Quick Reference
| Task | Command |
|---|---|
| Create alias | POST _aliases with add action |
| Delete alias | POST _aliases with remove action |
| List all aliases | GET _aliases |
| Check alias exists | HEAD _alias/<alias-name> |
| Alias with filter | add action with filter field |
| Alias with routing | add action with routing field |
| Set write index | add action with "is_write_index": true |
| Atomic swap | POST _aliases with remove + add in one request |
Next → Analyzers and Tokenizers