Schema definition
defineSchema
Define the schema for your Convex project.A map from table name to table definition.
Whether Convex should validate at runtime that documents match your schema.When
true, Convex will:- Check that all existing documents match your schema when pushed
- Check that all insertions and updates match your schema
false to skip runtime validation while keeping TypeScript types.Whether TypeScript should allow accessing tables not in the schema.When
true, using tables not listed in the schema generates a TypeScript error.
When false, unlisted tables have document type any.Set to false for rapid prototyping.defineTable
Define a table in your schema.Either an object mapping field names to validators, or a validator (for union types).
System fields
Every document automatically has system fields that you don’t need to define:A unique document ID. Generated automatically on insert.
The timestamp (milliseconds since epoch) when the document was created.
Indexes
index
Define an index on a table for efficient queries.The name of the index. Best practice: use
"by_field1_field2" naming.The fields to index, in order. Must specify at least one field.Index fields must be queried in the same order they’re defined. If you need to query by
field2 then field1, create a separate index.Whether to stage this index. Staged indexes don’t block push completion and can’t be used in queries until enabled.
searchIndex
Define a full-text search index.The name of the search index.
vectorIndex
Define a vector index for similarity search.The name of the vector index.
The field containing vectors. Must be a
v.array(v.float64()) field.The length of the vectors. Must be between 2 and 2048 inclusive.
Additional fields to index for fast filtering in vector searches.
Whether to stage this index.
Field validators
Use validators fromconvex/values to define field types:
Union types
Define discriminated union types using validators:Schema evolution
When you modify your schema:- Adding fields: Add them as optional (
v.optional()) or provide a default in your code - Removing fields: Remove from schema, then clean up old data with a migration
- Changing types: Create a new field, migrate data, then remove the old field
- Adding indexes: Add to schema and push. Convex will backfill automatically
- Removing indexes: Remove from schema and push
Best practices
Name indexes descriptively
Use
"by_field1_field2" naming to make it clear what fields are indexed and in what order.Use optional fields for flexibility
Make fields optional with
v.optional() if they might not always be present. This makes schema evolution easier.Index frequently queried fields
Create indexes for fields you filter or sort by frequently. Queries with indexes are dramatically faster.
Use validators for type safety
Validators catch bugs early by validating data at runtime and providing TypeScript types.
Stage large indexes
For large tables, use
staged: true on new indexes to avoid blocking deployments during backfill.