> ## Documentation Index
> Fetch the complete documentation index at: https://vlyai-1c28d863.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Indexes

> Make queries fast. Index design rules, when to add an index, and how to inspect query performance.

Indexes turn O(n) table scans into O(log n) lookups. Add them whenever you filter or sort by a field on a non-tiny table.

## Defining an index

```typescript convex/schema.ts theme={null}
tasks: defineTable({...})
  .index("by_team",                ["teamId"])
  .index("by_team_and_status",     ["teamId", "status"])
  .index("by_team_and_priority",   ["teamId", "priority"])
```

Naming: `by_<field>` for single-column, `by_<a>_and_<b>` for compound.

## Using an index

```typescript theme={null}
.withIndex("by_team_and_status",
  q => q.eq("teamId", teamId).eq("status", "open"))
```

The `q` chain inside `withIndex` matches the index's column order.

## When to add an index

<CardGroup cols={2}>
  <Card title="✅ When you filter by it" icon="check-circle">
    `.filter(t => t.field === value)` is O(n). `.withIndex(...)` is O(log n).
  </Card>

  <Card title="✅ When you sort by it" icon="check-circle">
    Sorted-order queries on indexed fields are free; on non-indexed, you read everything and sort in memory.
  </Card>

  <Card title="❌ For tiny tables" icon="x-circle">
    \< 100 rows: no benefit. Don't bother.
  </Card>

  <Card title="❌ Pre-emptively" icon="x-circle">
    Each index slightly slows writes. Add when a query is slow, not before.
  </Card>
</CardGroup>

## Compound indexes follow query order

`["teamId", "status"]` accelerates queries that filter by `teamId` (or `teamId` + `status` together). It does **not** accelerate filtering by `status` alone.

For "filter by team OR by status independently," create both indexes:

```typescript theme={null}
.index("by_team",   ["teamId"])
.index("by_status", ["status"])
```

## Built-in indexes

Every table has an implicit index on `_id` (the primary key) and `_creationTime`. So `.order("desc").take(10)` for "most recent 10" is always fast.

## Inspecting query performance

vly's editor flags slow queries in the console. For deeper inspection:

```bash theme={null}
vly convex query-stats --project prj_01...
```

Shows top slow queries, top missed-index queries, and recommendations.

## Tips

<Tip>
  **When you add an index, vly auto-rewrites existing queries to use it (if applicable).** No manual update needed.
</Tip>

<Tip>
  **For "find by exact field value," always index.** The `where field = X` pattern is the bread and butter — index it.
</Tip>

## Related

<CardGroup cols={3}>
  <Card title="Schema" icon="database" href="/convex/schema">
    Index syntax.
  </Card>

  <Card title="Queries" icon="search" href="/convex/queries">
    Using indexes.
  </Card>

  <Card title="Performance issues" icon="gauge" href="/troubleshooting/performance-issues">
    Debugging slow queries.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.