---
name: vibedb-indexing
description: Speed up VibeDB queries 10-1000x with indexes. Use when queries are slow (>100ms), working with large collections (>1000 docs), or need unique constraints.
---

# VibeDB Indexing

Make your queries 10-1000x faster with indexes.

## Why index?

**Without index**: Scans every document (slow for large collections)
**With index**: Direct lookup via B-tree (fast even with millions of documents)

**Simple rule**: If you query a field frequently, create an index on it.

## Quick start

```python
from vibedb import VibeDB

db = VibeDB("app.db")
users = db.collection("users")

# Create index on email field
users.create_index(["email"])

# Now email queries are 100x faster!
user = users.find_one({"email": "alice@example.com"})
```

## Create index

### Simple index
```python
# Index on single field
users.create_index(["email"])
users.create_index(["age"])
```

### Unique index
```python
# Prevent duplicates
users.create_index(["email"], unique=True)

# This will now fail:
users.insert({"email": "dup@example.com"})
users.insert({"email": "dup@example.com"})  # Error!
```

### Composite index
```python
# Index on multiple fields
users.create_index(["role", "status"])

# Fast for queries on both fields
users.find({"role": "user", "status": "active"})

# Also fast for queries on first field only
users.find({"role": "user"})

# NOT fast for second field only (wrong order)
users.find({"status": "active"})  # Won't use index
```

### Custom name
```python
users.create_index(["email"], name="my_email_index")
```

## Manage indexes

### List indexes
```python
indexes = users.list_indexes()
for idx in indexes:
    print(f"Name: {idx['name']}")
    print(f"Fields: {idx['fields']}")
    print(f"Unique: {idx['unique']}")
```

### Drop index
```python
users.drop_index("users_idx_email")
```

## Auto-suggestions

VibeDB automatically tracks slow queries and suggests indexes!

```python
# Run some queries
for _ in range(20):
    users.find({"age": {"$gte": 25}}).to_list()
    users.find({"role": "user"}).to_list()

# Get auto-suggestions
suggestions = users.index_suggestions()

for s in suggestions:
    print(f"Fields: {s['fields']}")
    print(f"Reason: {s['reason']}")
    print(f"Est. speedup: {s['estimated_speedup']}")
    print(f"Priority: {s['priority']}")

# Apply top suggestion
if suggestions and suggestions[0]['priority'] >= 3.0:
    users.create_index(suggestions[0]['fields'])
```

## When to create indexes

### ✅ Create index when:
- Field queried frequently (>10 times)
- Collection has >1,000 documents
- Queries take >100ms
- Field used in `find()`, `sort()`, or `count()`
- Need uniqueness constraint

### ❌ Don't create index when:
- Collection is tiny (<100 documents)
- Field rarely queried
- Just prototyping/testing
- Field values not selective (e.g., boolean with 50/50 split)

## Performance impact

```python
import time

# Add 10,000 users
users.insert_many([
    {"email": f"user{i}@example.com", "age": 20 + (i % 50)}
    for i in range(10000)
])

# WITHOUT index
start = time.time()
user = users.find_one({"email": "user5000@example.com"})
without = (time.time() - start) * 1000
print(f"Without index: {without:.2f}ms")  # ~50ms

# CREATE index
users.create_index(["email"])

# WITH index
start = time.time()
user = users.find_one({"email": "user5000@example.com"})
with_idx = (time.time() - start) * 1000
print(f"With index: {with_idx:.2f}ms")  # ~1ms

print(f"Speedup: {without / with_idx:.0f}x faster")
```

## Configure slow query tracking

```python
# Set threshold for what counts as "slow"
db = VibeDB(
    "app.db",
    slow_query_threshold_ms=50,  # 50ms threshold (more sensitive)
    log_slow_queries=True
)

# Or disable slow query logging
db = VibeDB("app.db", log_slow_queries=False)
```

## Common patterns

### Pattern: Auto-optimize on startup
```python
def optimize_collection(collection):
    """Apply high-priority index suggestions."""
    for s in collection.index_suggestions():
        if s['priority'] >= 4.0:  # Only high priority
            try:
                collection.create_index(s['fields'])
                print(f"✓ Created index on {s['fields']}")
            except:
                pass  # Index might exist

# Use on app startup
optimize_collection(users)
```

### Pattern: Common user indexes
```python
def setup_user_indexes(users):
    """Standard indexes for user collections."""
    users.create_index(["email"], unique=True)
    users.create_index(["username"], unique=True)
    users.create_index(["created_at"])
    users.create_index(["status"])

setup_user_indexes(users)
```

### Pattern: Session indexes
```python
def setup_session_indexes(sessions):
    """Standard indexes for sessions."""
    sessions.create_index(["session_id"], unique=True)
    sessions.create_index(["user_id"])
    sessions.create_index(["expires_at"])

setup_session_indexes(sessions)
```

## Nested field indexes

Index on nested fields using dot notation:

```python
# Sample data with nested fields
users.insert({
    "name": "Alice",
    "address": {
        "city": "NYC",
        "zip": "10001"
    }
})

# Create index on nested field
users.create_index(["address.city"])

# Now fast:
nyc_users = users.find({"address.city": "NYC"}).to_list()
```

## Index limitations

- Indexes speed up **reads** but slow down **writes** (slightly)
- Each index uses disk space (~10-20% of data size)
- Maximum recommended: 5-10 indexes per collection
- Composite index order matters

## Best practices

1. **Start without indexes** - Add them when needed
2. **Index after 1000+ documents** - Not worth it before
3. **Use index suggestions** - Let VibeDB tell you what to index
4. **Index selective fields** - High cardinality fields (email > boolean)
5. **Monitor query times** - Add indexes when >100ms
6. **Don't over-index** - Each index has cost

## Quick reference

```python
# Create index
users.create_index(["field"])
users.create_index(["field"], unique=True)
users.create_index(["field1", "field2"])  # Composite

# Manage
users.list_indexes()
users.drop_index("index_name")

# Auto-suggest
suggestions = users.index_suggestions()
users.create_index(suggestions[0]['fields'])
```

For more details, see `reference.md`.
