Dyrected
Deployment & OperationsInfrastructureDatabase Adapters

Indexes

Make queries and sorts fast in Dyrected by promoting the fields you filter on, and understand how uniqueness fits in.

By default, Dyrected stores each document as a single JSON blob. That's flexible — you can query and sort on any field without declaring it first — but reading a value out of JSON is slower than reading a real column, and it adds up on large collections. When you have a field you filter or sort on constantly, you want the database to treat it as a proper column. In Dyrected that's called promotion, and it's the main tool this page is about.

If you're coming from other tools, note there is no index: true field property in Dyrected. The knob you reach for is promoted: true.

Promote the fields you query

On the SQL adapters (Postgres, SQLite, MySQL), set promoted: true on a field to lift it out of the JSON blob and into its own typed column:

import { defineCollection, defineTextField, defineSelectField } from '@dyrected/core'

export const Posts = defineCollection({
  slug: 'posts',
  fields: [
    defineTextField({ name: 'title', label: 'Title', required: true }),
    defineTextField({
      name: 'slug',
      label: 'Slug',
      unique: true,
      promoted: true,
    }),
    defineSelectField({ name: 'status', label: 'Status', options: ['draft', 'published'] }),
  ],
})

On the next startup, Dyrected adds a real slug column to the collection_posts table and starts writing every document's slug there as well. From then on, filtering and sorting by slug reads the column directly instead of extracting it from JSON.

Reach for promotion on fields that are:

  • used often in where filters or sort
  • keys you look documents up by, like a slug or an external ID
  • fields you sort listings by, like a publishedAt date

You don't need to promote everything. Fields you rarely filter on are perfectly fine left in the JSON body, and promoting them just adds columns you don't benefit from.

Promotion adds a column, not automatically an index

Promotion gives the database a real column to work with, which is already a meaningful speedup over JSON extraction. It does not, on its own, create a database index on that column. For most collections that's plenty. On a very large table where a promoted field is still slow to filter, add a true index on the column using your database's own tooling — for example a CREATE INDEX in Postgres against collection_posts(slug). Promotion is what makes that possible, because the column now exists.

Enforcing uniqueness

Mark a field with unique: true when its values should never repeat across a collection — a slug, an email, an external reference:

defineTextField({ name: 'slug', label: 'Slug', unique: true, promoted: true })

Here's the important part to understand: unique: true is a declaration of intent, not a database constraint. Dyrected does not create a unique index and does not reject a duplicate write on its own — this holds both self-hosted and on Dyrected Cloud. The admin panel shows a "Unique" badge next to the field as a hint, but it doesn't block duplicates either.

So if you depend on uniqueness, enforce it in your own logic — for example, a beforeChange hook that looks for an existing document with that value and rejects the write if it finds one. See Collection hooks.

MongoDB

MongoDB stores every field natively, so there's nothing to promote — promoted has no effect there. Query performance instead comes from MongoDB's own indexes, which Dyrected does not create for you. Add the indexes you need directly in MongoDB. See MongoDB for the details.

What's already fast

Every collection table has an id primary key, so looking a document up by id is fast without any configuration. Documents also carry created_at and updated_at as real columns, so sorting a listing by newest is efficient out of the box.

For the broader performance picture — pagination, query shape, and depth — see Performance and the query APIs.

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend