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

# Query Modes

> Understand the difference between execute and plan mode.

Every request to `POST /v1/query` runs in one of two modes, controlled by the `mode` field in the request body.

## Execute Mode

`"mode": "execute"` is the default. The engine parses, plans, optimizes, and then runs the query — fetching rows from DynamoDB and returning them in the response.

* **Consumes DynamoDB RCUs** charged to your AWS account.
* **Required scope:** `query`
* Returns a `data` payload with rows, column metadata, and timing fields.

## Plan Mode

`"mode": "plan"` parses and optimizes the query without fetching any data.

* **Does NOT consume DynamoDB RCUs.**
* **Required scope:** `query`
* Returns a human-readable plan tree, an optimizer weight (cost estimate), and the normalized SQL string.

Plan mode is useful for:

* **Debugging slow queries** — check whether the optimizer selected an index or fell back to a scan.
* **Validating SQL in CI/CD** — catch syntax errors and unsupported features without consuming capacity.
* **Previewing query structure** — understand how the engine will execute a query before running it against production tables.

## Understanding the Response Fields

### `weight`

The optimizer's relative cost estimate. Lower is cheaper. A weight of `0` means no cost estimate was computed — for example, when the query has no index candidates and the optimizer produces a simple scan plan.

### `planTime`

Present in both modes. Covers parse + plan + optimize only. It does **not** include any DynamoDB I/O.

### `execTime`

Present in execute mode only. Total elapsed time from request receipt to response, including all DynamoDB I/O. Always `>= planTime`.

## Example

**Plan mode request:**

```json theme={null}
{
  "sql": "SELECT id, total FROM myschema.orders WHERE status = 'pending' LIMIT 10",
  "mode": "plan"
}
```

**Plan mode response:**

```json theme={null}
{
  "success": true,
  "data": {
    "plan": "Limit(10)\n  Scan(myschema.orders)\n    Filter(status = 'pending')",
    "weight": 0,
    "normalizedSql": "SELECT id, total FROM myschema.orders WHERE status = 'pending' LIMIT 10",
    "planTime": 3
  }
}
```

The plan tree shows the engine will perform a full `Scan` with a `Filter` applied — no index was matched. If you have a GSI on `status`, check that the schema metadata is registered correctly in the portal so the optimizer can see it.

<Tip>
  If you see `Scan(...)` in the plan for a query that should use an index, run the query in plan mode first and inspect the tree before paying DynamoDB RCU costs for a scan.
</Tip>

**Execute mode request (same query):**

```json theme={null}
{
  "sql": "SELECT id, total FROM myschema.orders WHERE status = 'pending' LIMIT 10",
  "mode": "execute"
}
```

**Execute mode response:**

```json theme={null}
{
  "success": true,
  "data": {
    "columns": ["id", "total"],
    "data": [
      ["ord-001", 59.99],
      ["ord-002", 120.00]
    ],
    "firstRowIdx": 0,
    "planTime": 3,
    "execTime": 47
  }
}
```
