All Stories
2026-10-05•15 min read

Release · Pixeltable · Changelog · CLI · Schema · Pixeltable Cloud · Production AI

Pixeltable August–September 2026 release: the backend agents build with

v0.7.0 through v0.7.12: your coding agent writes a multimodal AI app's backend as Python classes, changes it the way it changes code, with a plan to review before each update to the tables, routes, and hosted database, and runs the same app on Pixeltable Cloud (Limited Beta).

Pixeltable Team

Pixeltable Team

Pixeltable Team

A coding agent can build the first version of a multimodal AI app in an afternoon. What takes your time afterward is keeping the app working on real data while you keep changing it: a new model every month, a new feature every week.

That app usually sits on a stack you assemble yourself:

  • Postgres for the app's rows
  • object storage for the media files
  • a vector database like Pinecone for search
  • job scripts or Airflow to run the model calls
  • an API server for the endpoints

Or it sits on an app backend like Supabase or Convex, with the AI processing built somewhere else.

With this release, Pixeltable is the backend your agent builds with. Your agent writes the storage, the AI steps, and search as Python classes, and declares the API's routes against them in the same file. The Pixeltable CLI makes the running app match that file: it shows the plan for each change, applies it, and runs the same app on your laptop or on Pixeltable Cloud.

What's new:

  • Start from a working app, and write the backend as Python classes. pxt init makes the project, and pxt service example writes an app file to start from. Tables, AI steps, and search indexes are classes, routes are declared against them, and pxt schema update and pxt service update build and serve them.
  • Change your backend the way you change code. Your agent edits the file, diff shows the plan, and update applies it to your tables (pxt schema), your routes (pxt service), and your hosted database (pxt db), with nothing destructive applied without your OK.
  • Run your routes with the same CLI. pxt service checks, diffs, updates, and prunes the services your file defines, and restarts only the ones that changed. It replaces pxt serve.
  • Run the same app on your laptop and in production. On Pixeltable Cloud (Limited Beta), the same commands take a pxt:// target.
  • Install the plugin in Claude, Cursor, and ChatGPT. The skill teaches your agent to write the app and apply it with the CLI. In Claude Code and Cursor it also adds a schema designer, a debugger, and commands to start a project and add a model.
  • Start from the same definitions as your agent. The Multimodal AI Glossary defines one term per entry, for you and your coding agent.

Upgrade with:

bash

[serve] adds FastAPI and uvicorn, which pxt service needs. This cycle is 13 releases and 168 PRs. A few changes may need you to update existing code; they're listed at the end. The full changelog and the compare view have everything.

Write the backend as Python classes#

In an assembled stack, each piece is a service you stand up and connect before the app does anything. In this release, two commands give you and your agent a working app to start from:

bash

The example has a table with a generated key and two computed columns, and routes that insert, update, and compute rows. From there, the backend is Python classes in your app. A class says what's stored and which AI steps run on it. A step can call a hosted model API or a local model, call any other API, transform media, or run your own function:

python

In a project made with pxt init, one command creates the tables from the file. (The Whisper step needs pip install openai-whisper.)

bash

Once the file declares routes, shown below, pxt service update app.py my_app serves them.

Search indexes go on the class too, in __indexes__. As before, each step runs on every video your app inserts, a step you add fills in for the videos already stored, and indexes stay current as videos are inserted, updated, and deleted. As of v0.7.12, whisper.transcribe() returns a typed result, so an index on a new transcript column's text needs no cast.

Your agent works in one app instead of wiring services together.

Sources: Quickstart · #1434 · #1466 · #1518 · #1693

Change your backend the way you change code#

Your app file is the source of truth, and the CLI makes the running app match it. Your agent edits the file, diff shows the plan, and update applies it. The first deploy and every change after it use the same commands:

bash

The same loop covers each layer of the backend, with the same verbs and exit codes:

  • pxt schema for your tables, computed columns, and indexes
  • pxt service for the routes your frontend calls
  • pxt db for a hosted database's code, environment, and size

What you and your agent can rely on, new in this cycle:

  • update is safe to repeat: running it again with nothing to do changes nothing.
  • A schema plan with anything destructive applies nothing without --allow-destructive, so an update drops no data without your OK. Tables the file no longer defines go only through a separate, confirmed pxt schema prune.
  • Exit codes tell an agent where it stands without parsing text: 0 in agreement, 2 changes pending, 3 refused, 1 error. --json returns the plan, and --json-schema describes its shape.
  • A CI step can run pxt schema diff against production and fail on exit 2 when production has drifted from the committed file.
  • To promote from dev to prod, apply the same file to the production target.
  • pxt recompute --errors-only reruns only the rows whose step failed, and everything built on them.

They work with what was already there. With on_error='ignore', a batch keeps going when model calls fail and records each failure on its row, and on a table with a primary key, pxt errors lists those rows. pxt revert undoes a change one table at a time. In a shell with no terminal, a command that needs confirmation refuses instead of waiting on a prompt.

pxt schema update can also change the expression behind a computed column, as long as the column's type stays the same. It leaves the stored values as they are and prints the pxt recompute command to run. To try a new model, add it as a new column instead, so no column mixes results from two models.

Sources: CLI reference · #1466 · #1479 · #1491 · #1542 · #1568 · #1589 · #1600

Run your routes with the same CLI#

Your frontend, or another agent, sends media in and needs results back. Routes now take your table classes, so the API is declared in the same file as the tables it serves. As before, an insert route stores an upload, runs your AI steps on it, and returns the results, and a compute route runs the steps and stores nothing:

python

What's new is how the routes run. pxt service replaces pxt serve and its [[service]] TOML config. pxt service diff shows what a change will do to the routes, and pxt service update starts the services the file defines and restarts only the ones that changed. A restarted local service keeps its port, so callers keep their address.

Sources: HTTP serving · #1510 · #1542 · #1579 · #1586 · #1694

Run the same app on your laptop and in production#

Pixeltable runs locally with nothing else to install, because the database is embedded. Pixeltable Cloud, new in Limited Beta, runs the same app on a hosted database with the same schema and service commands. Before pxt db diff, add the hosted database to the pixeltable.toml that pxt init wrote. If the project already has a pyproject.toml, pxt init writes there instead, and the hosted entry is [[tool.pixeltable.database]]. pixeltable.toml wins when both files exist. Wait for pxt db status to show it AVAILABLE; the Cloud guide shows the entry.

bash

pxt db diff brings the same check to the hosted database: it shows what an update will change in the project files, the image, and the database's size, and exits with code 2 when something is pending. pxt login works over SSH, and picks your organization when you belong to only one. pxt secret stores API keys for the whole organization or one database, and pxt secret list marks the database secrets that override an organization's. Local files your app inserts upload to the database's home bucket. You can start free on the Community plan.

Your coding agent can also reach your hosted databases through Pixeltable Cloud MCP, a hosted MCP server at https://www.pixeltable.com/mcp/cloud. After a browser sign-in, it lists your databases and services, reads schemas, up to 25 rows at a time, and recent logs, and can start and stop databases, restart services, and set secrets. Stopping, restarting, and setting a secret return a preview first and run only when the agent confirms. It can't delete anything, run arbitrary queries, or call your services, and ?read_only=true limits a connection to the read tools.

The prototype you tested is the app you deploy.

Sources: Deploy to Pixeltable Cloud · CLI reference · #1493 · #1544 · #1545 · #1568 · #1588 · #1604 · #1609 · #1610 · #1657 · #1684 · #1695

Install the plugin in Claude, Cursor, and ChatGPT#

The Pixeltable skill teaches your coding agent to write the app in this post and apply it with the CLI. The plugin packages that skill for Claude, Cursor, and ChatGPT.

bash

On Claude Code and Cursor, the full plugin adds what the agent needs around the skill:

  • A pipeline architect that designs the schema: tables, views, computed columns, and indexes.
  • A debugger that finds why a step errors or returns empty results.
  • Two commands: one starts a project, and one adds a model provider as a computed column.
  • On Claude Code, a check that flags deprecated APIs in every Python file your agent writes or edits.

Your agent then writes the same app file the rest of this post describes.

Sources: pixeltable-skill · AI coding skills guide

Start from the same definitions as your agent#

When you evaluate a stack, on your own or with a coding agent, a term like "agent memory," "multimodal database," or "view" can mean different things to each of you, and sorting that out costs time and turns. The Multimodal AI Glossary defines one term per entry in a sentence or two, across multimodal data, retrieval, video, documents, audio, vision, agents, storage, versioning, serving, cost, and evaluation. Point your agent at it, and you both start from the same definitions.

Also in August and September#

Improvements#

  • Table, column, and database names are now case-insensitive.
  • The CLI remembers a working directory per terminal session (pxt cd / pxt pwd).
  • --json-schema prints the JSON schema of the diff, list, and status output, so an agent knows its shape up front.
  • ConfigVar lets a table model read a value that differs per environment, e.g., a media destination.
  • pxt service update keeps a restarted service on the port callers already use.
  • pxt service check and update see routes you add with app.include_router(...) on FastAPI 0.137.2 and newer.
  • The dashboard shows local and hosted catalogs in one window, with lineage and history following the catalog you select.
  • Pixeltable works with pgvector 0.5.0.
  • Secret names starting with PIXELTABLE_ are reserved.
  • Hosted services' OpenAPI schemas declare the API key header, type file responses as binary, and include job polling, for generating typed TypeScript clients.
  • Each database in pixeltable.toml can set its own media destinations.
  • pxt db delete asks for confirmation, or needs -f.
  • The CLI stops right away on an invalid TOML config.
  • pxt login picks your organization when you belong to only one.
  • An app file that fails to load names the exception type, e.g., error loading app.py: AssertionError.
  • Run inside a project, pxt service stop looks only in that project, and stops with an error on an ambiguous name.
  • pxt secret list shows each secret's scope.
  • On Pixeltable Cloud, inserts bundle small media, array, and binary files into uploads of about 100 MB.
  • A missing API key gets an error message written for the CLI.

Fixes#

  • update_all() and pxt schema update resolve @query references in your models.
  • SAM 3 segmentation returns masks shaped to the input image even when it finds nothing.
  • A transaction retries when the PostgreSQL server terminates its connection as the transaction starts.
  • document_splitter closes PDFs after it reads them.
  • insert() and create_table(source=...) work with a query that includes a join.
  • pxt.Array slices are now typed correctly, including dimension count, scalar results, and null values.
  • An insert with on_error='ignore' records a failed media save instead of raising an error.
  • Routes serve a model whose computed column calls a @pxt.query.
  • Aggregate queries handle variables correctly.

Migration and breaking changes#

  • Schema types are non-nullable by default. A bare type specifier is now non-nullable, and nullability is explicit. pxt.Int means a required column; write pxt.Int | None for one that accepts nulls. Schemas that relied on bare types being nullable need updating:
    python
  • pxt.Required is deprecated. It marked a column that rejects nulls, as in pxt.Required[pxt.String]. A bare type does that now, so write pxt.String. Existing uses still work and emit a warning until the wrapper is removed.
  • Python 3.10 is no longer supported. The minimum runtime is now Python 3.11. Move your environment to 3.11 or newer before you update Pixeltable.
  • B-tree indexes are no longer created automatically. Creating a table or column used to add a B-tree index for you. Pixeltable no longer does; add one with Table.add_btree_index() where you need it. Tables created before this change keep their default indexes. The create_default_idxs argument is now has_default_idxs, and it defaults to False; pass has_default_idxs=True for the old behavior.
  • pxt serve and pxt deploy are gone. They and their [[service]] and [[deployment]] TOML config are replaced by pxt service update with an app file, and by pxt db update for hosted databases.
  • poetry.lock is no longer a lockfile pxt db update installs. A project with only that file builds an image that contains Pixeltable and nothing else. Declare dependencies in uv.lock or requirements.txt.
  • Names are case-insensitive and ASCII-only. Table, column, and database names are folded to lowercase. The upgrade stops if two existing names differ only by case, if a name is not ASCII, or if a column folds onto a reserved name or a Python keyword (Count becomes count). Imports fail on column names that collide after lowercasing.
  • get_metadata() keys are renamed. indices is now indexes, and is_versioned is now is_data_versioned.
  • Table models list their indexes in __indexes__. If you defined indexes on a TableModel with the old syntax, move them to __indexes__.
  • The Reve provider is gone. The built-in Reve integration was removed ahead of Reve's API sunset. Move any Reve calls to another provider.
  • sentence_transformers 5.4 or newer is required. Upgrade the package if you pinned an older version.
  • The OpenAI integration needs the OpenAI SDK 3 or newer. Upgrade the openai package if you pinned an older version.

Get started#

If you're new, start in the docs. The AI coding skills guide lists every way to install the plugin.

Questions and projects are welcome in Discord, and you can file issues, open PRs, or star the repo on GitHub.

Thank you to everyone who wrote code, reviewed it, tested it, documented it, and got v0.7.0 through v0.7.12 out the door.

Happy app building!

Declarative. Multimodal. Incremental.

Focus on innovation, not infrastructure.

10-minute tutorial · Join community