Backend

Schema

Define your database tables with Convex schemas.

Convex uses schemas to define your database structure. Tables are created automatically when you push to Convex.

Defining Tables

Create a schema file in your convex/ directory:

convex/schema.ts
import { defineSchema, defineTable } from 'convex/server'
import { v } from 'convex/values'

export default defineSchema({
  tasks: defineTable({
    title: v.string(),
    userId: v.optional(v.string()),
    isCompleted: v.boolean(),
    createdAt: v.number(),
  }).index('by_user', ['userId']),
})

The schema defines a tasks table with four fields and an index on userId for efficient queries.

Validators

The v object provides validators for all Convex types:

ValidatorDescription
v.string()String value
v.number()Number value
v.boolean()Boolean value
v.id('table')Document ID reference
v.array()Array of values
v.object()Nested object
v.optional()Optional field
v.union()One of multiple types

Indexes

Indexes improve query performance. Define them with .index():

convex/schema.ts
export default defineSchema({
  messages: defineTable({
    channelId: v.id('channels'),
    authorId: v.id('users'),
    content: v.string(),
    createdAt: v.number(),
  })
    .index('by_channel', ['channelId'])
    .index('by_author', ['authorId']),
})
Create indexes for fields you query frequently. Convex uses indexes automatically when you filter with .withIndex().

Next Steps

With your schema defined, you can:

See the Convex schema documentation for advanced patterns.