Skip to main content

Why this matters


Every entity in Midaz supports metadata — custom key-value pairs that extend the standard data model. While metadata is flexible and powerful, querying large collections by metadata fields can become slow without proper indexing. Metadata indexes solve this by creating MongoDB indexes on specific metadata keys, turning expensive collection scans into fast indexed lookups. This is especially important in production environments with high transaction volumes where you filter or sort by metadata values.

How it works


When you create a metadata index, Midaz instructs MongoDB to build an index on the metadata.<key> field of the specified entity collection. From that point on, any query that filters by that metadata key benefits from the index — MongoDB uses the index to locate matching documents directly instead of scanning every document. Indexes are:
  • Per-entity: Each index targets a specific entity type (e.g., transaction, operation).
  • Per-key: Each index covers a single metadata key.
  • Optional uniqueness: You can enforce that no two documents in the collection share the same value for the indexed metadata key.
  • Sparse by default: Only documents that actually have the indexed metadata key are included in the index, saving storage and improving write performance.

Supported entity types


Metadata indexes are currently available for the following entities:
EntityCollectionModule
transactionTransactionsTransaction
operationOperationsTransaction
operation_routeOperation RoutesTransaction
transaction_routeTransaction RoutesTransaction
Onboarding module entities (organizations, ledgers, accounts, assets, segments, portfolios, account types) support metadata but do not currently support custom metadata indexes.

Creating a metadata index


Use the Create a Metadata Index endpoint:
{
  "metadataKey": "tier",
  "unique": false,
  "sparse": true
}
Parameters:
FieldTypeRequiredDescription
metadataKeystringYesThe metadata key to index. Must start with a letter and contain only alphanumeric characters and underscores. Max 100 characters.
uniquebooleanNoWhether the index enforces uniqueness across documents. Default: false.
sparsebooleanNoWhether the index only includes documents that have the metadata key. Default: true.
Response:
{
  "indexName": "metadata.tier_1",
  "entityName": "transaction",
  "metadataKey": "tier",
  "unique": false,
  "sparse": true
}

Listing metadata indexes


Use the List Metadata Indexes endpoint to see all indexes across all entity types, including usage statistics:
{
  "items": [
    {
      "indexName": "metadata.tier_1",
      "entityName": "transaction",
      "metadataKey": "tier",
      "unique": false,
      "sparse": true,
      "stats": {
        "accesses": 1523,
        "statsSince": "2024-12-01T10:30:00Z"
      }
    }
  ],
  "page": 1,
  "limit": 10
}
The stats.accesses field shows how many queries have used the index since statistics collection started — useful for identifying unused indexes that can be safely removed.

Deleting a metadata index


Use the Delete a Metadata Index endpoint:
DELETE /v1/settings/metadata-indexes/entities/{entity_name}/key/{index_key}
Deleting an index is immediate and affects query performance for any operation that was using it. Make sure no critical queries depend on the index before removing it.

Performance considerations


When to create indexes:
  • You frequently filter transactions or operations by a specific metadata key (e.g., tier, channel, partner_id).
  • List queries on large collections are slow when filtering by metadata.
  • You need to enforce uniqueness on a metadata field (e.g., external reference IDs).
When NOT to create indexes:
  • The metadata key is rarely used in queries — indexes consume storage and slow down writes.
  • The collection is small enough that full scans are fast.
  • You’re adding indexes speculatively “just in case.”
Limits: There is a maximum number of metadata indexes per entity. Exceeding this limit returns error 0135 (Metadata Index Limit Exceeded). If you hit this limit, review existing indexes using the list endpoint and remove any that show low or zero accesses.
Start with indexes on the metadata keys you actually query in production. Use the stats.accesses field from the list endpoint to validate that your indexes are being used — and remove those that aren’t.