Get started
R2DB DOCUMENTATION / DATA BROWSER

Data browser

The console's Data browser shows your tables, their columns and declared indexes, the rows in any table, and a query editor that completes from your own schema.

It is **read-only**. There is no path in the console that writes to your database.

Everything it runs is a real, billed read

Opening a table posts a query to the same endpoint your application's exec posts to, with the same per-call ceilings. That is deliberate: a browser that quietly read under a different policy would be the one place you could not learn what your store actually does. Refusals show up here exactly as your application would receive them.

The consequence is that browsing costs credits. So nothing polls and nothing refreshes on a timer: opening the page reads only your schema, which is free, and rows arrive when you open a table.

Your browsing does **not** go into the slow query log — that page is about your application's traffic, and the two are told apart by how they authenticate rather than by a setting.

Rows are ordered by the primary key, and that is not a cosmetic choice

r2db never builds an index. An ordering or filter that no declared index covers does not fail —

it scans, one storage fetch at a time, until the fetch ceiling refuses it.

The primary key is the one ordering every table is guaranteed to have, so that is what the row list uses. Paging is a **keyset cursor** — the next page starts after the last row's key — rather than an offset, which would re-read every row it skipped.

In the column list each column is marked:

  • **INDEXED** — a declared index leads with this column, so a filter or sort on it seeks.
  • **scans** — nothing leads with it. You can still query it, and on a small table you will not

notice; on a large one it is refused. Declare an index, or sort on a column that has one.

That marking is the same rule your queries live under, surfaced before you run one rather than after it fails.

The query editor

It is the real r2db query builder, not a lookalike, and it completes from your database's own catalog — so it cannot offer you a table, column or relationship that your query would then fail to resolve. Press <kbd>ctrl</kbd>+<kbd>space</kbd> for suggestions.

q.task
  .where(task.done(eq(false)))
  .orderBy("id", "asc")
  .limit(25)

Your chain compiles to a query in your browser; only the compiled query is sent. The editor shows errors as you type without sending anything, and The query that was sent under each result is the exact payload, so you can copy it into your own code or into r2db explain.

What it does not do

  • **No related collections.** A chain with sub(...) has nothing to resolve here, because an r2db

schema declares tables, columns and indexes but not relationships — so the editor offers none and a query that names one will not compile. Query each table on its own, or build the related read in your own code where your schema object has the relationships.

  • **No writes, no row editing, no schema changes.** Use r2db create for schema and the SDK's

write or readModifyWrite for data.

  • **No row counts.** Counting a table means reading all of it, which is the one thing this storage

charges most for. The row list tells you how many rows it has fetched, not how many exist.

  • **No SQL.** Your schema in TypeScript is the source of truth and the query builder is the query

language; see the application API.