Stores and Store Routes

Stores and store routes control where Mach5 writes index data.

What is a store?

A store is the object storage location where Mach5 persists index data.

Examples:

  • s3://example-bucket/primary-index-data
  • s3://example-bucket/secondary-index-data

The store configuration defines the bucket and optional prefix. It does not decide which index goes there.

What is a store route?

A store route decides which store a newly created index should use.

Each store route has:

  • a target store_id
  • an index name regex in pattern
  • a numeric priority
  • an optional namespace regex in namespace_pattern

At index creation time, Mach5 evaluates the configured store routes, picks the first matching route, and records the chosen store on the index.

After that, the index keeps using that store. Changing store routes later does not move existing indexes.

The examples below use the StoreRouteConfig payload shape:

{
  "store_id": "<store-id>",
  "priority": 10,
  "pattern": ".*",
  "namespace_pattern": null
}

How matching works

Store route matching is based on the index name, not on:

  • the store bucket
  • the store prefix
  • the warehouse name
  • the /warehouse/... URL

pattern is a regular expression matched against the index name.

Examples:

  • .* matches every index name
  • ^logs-.* matches index names that start with logs-
  • ^metrics-.* matches index names that start with metrics-

Regular expressions are not implicitly anchored. If you want to match the beginning of the index name, use ^.

How priority works

Higher numeric priority wins over lower numeric priority.

For example, if two generic routes both match an index:

  • {"pattern": ".*", "priority": 0}
  • {"pattern": ".*", "priority": 10}

the route with priority 10 is selected.

One important exception applies:

  • Mach5 evaluates routes with a namespace_pattern first
  • Mach5 only evaluates routes without a namespace_pattern if no namespace-specific route matches

So a matching namespace-specific route can win over a generic route even if the generic route has a higher numeric priority.

Common examples

Single-store deployment

If you only have one store, use one simple catch-all route:

{
  "store_id": "<primary-store-id>",
  "priority": 10,
  "pattern": ".*",
  "namespace_pattern": null
}

This routes all newly created indexes to the same store.

Two stores with disjoint index prefixes

Use anchored regexes when the index name itself tells you which store to use:

[
  {
    "store_id": "<logs-store-id>",
    "priority": 10,
    "pattern": "^logs-.*",
    "namespace_pattern": null
  },
  {
    "store_id": "<metrics-store-id>",
    "priority": 10,
    "pattern": "^metrics-.*",
    "namespace_pattern": null
  }
]

Because these rules are intended to match different index names, priority should not matter in normal use.

Override all new indexes to a new store

If both routes match every index, priority decides which store new indexes use:

[
  {
    "store_id": "<existing-store-id>",
    "priority": 0,
    "pattern": ".*",
    "namespace_pattern": null
  },
  {
    "store_id": "<new-store-id>",
    "priority": 10,
    "pattern": ".*",
    "namespace_pattern": null
  }
]

In this case, new indexes are routed to <new-store-id>.

Existing indexes that were already created in <existing-store-id> stay there.

Namespace-specific routing

You can also route by namespace:

[
  {
    "store_id": "<prod-store-id>",
    "priority": 5,
    "pattern": ".*",
    "namespace_pattern": "^prod$"
  },
  {
    "store_id": "<default-store-id>",
    "priority": 100,
    "pattern": ".*",
    "namespace_pattern": null
  }
]

An index created in namespace prod uses <prod-store-id>, even though the generic route has a higher priority.

When do you need multiple stores?

Most deployments only need one store and one route with pattern: .*.

Multiple stores are mainly useful when you intentionally want different sets of indexes to live in different object storage locations, for example:

  • gradual cutover from one storage prefix to another
  • keeping different index families in different prefixes or buckets
  • environment-specific or namespace-specific routing