> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chardb.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Vectors

> Write and search organization vectors through Vectorize.

Vector columns are an opt-in organization feature. CharDB stores an opaque logical handle in SQLite and delivers the vector to Cloudflare Vectorize after the transaction commits.

## Declare the vector

The property name supplies the SQL column name, so the string overload is unnecessary here.

```ts src/schema.ts theme={null}
import { vector } from "@chardb/core/server";

export const messages = cdbTable("messages", {
  // ordinary message columns
  embedding: vector({
    dim: 768,
    binding: "VECTORS",
    metric: "cosine",
  }),
});
```

Add the matching native binding to `wrangler.toml`, create the index, then prepare CharDB's required metadata index.

```toml wrangler.toml theme={null}
[[vectorize]]
binding = "VECTORS"
index_name = "my-app-vectors"
remote = true
```

```bash theme={null}
bunx wrangler vectorize create my-app-vectors --dimensions 768 --metric cosine
bunx @chardb/core vectorize prepare
```

Vectorize has no local emulator. `remote = true` makes local Wrangler development use the Cloudflare index.

## Write and delete

Your application computes the embedding values. This release does not call an embedding model for you.

```ts src/api.ts theme={null}
export const putMessage = api.mutation({
  ref: "messages#put",
  authority: "organization",
  partitionKey: "organizationId",
  args: z.object({
    organizationId: z.string(),
    id: z.string(),
    body: z.string(),
    values: z.array(z.number()).length(768),
  }),
  handler: (ctx, args) => {
    const embedding = ctx.vector.set(messages.embedding, args.id, args.values);
    ctx.db.insert(messages).values({ id: args.id, body: args.body, embedding }).run();
    return { id: args.id };
  },
});

ctx.vector.delete(messages.embedding, args.id);
ctx.db.delete(messages).where(eq(messages.id, args.id)).run();
```

Keep `ctx.vector.delete()` and the row deletion in the same mutation.

## Search

```ts src/queries.ts theme={null}
export const searchMessages = api.query({
  ref: "messages#search",
  args: z.object({
    organizationId: z.string(),
    values: z.array(z.number()).length(768),
    limit: z.number().int().min(1).max(100),
  }),
  query: (_db, args) => searchVector(messages.embedding, args),
});
```

Search returns `{ rowPk, score }`. CharDB rejects stale, cross-organization, and policy-hidden Vectorize results against SQLite. Delivery and deletion are eventually consistent. A settled vector change invalidates the matching live search query and causes it to refetch.
