# Support boundaries and limits (/docs/core/reference/limitations)



Kysoql models SOQL `SELECT` queries. It is Kysely-inspired, not a drop-in Kysely
implementation, and it does not try to represent every Salesforce API feature.

## Outside the builder [#outside-the-builder]

Kysoql does not provide DML/CRUD, SOSL, SQL joins, `SELECT *`, live runtime schema
loading, automatic schema refresh, Bulk API exports, or Apex execution.

Use `soql.raw()` only for trusted SOQL syntax that the typed builder does not yet
model. Raw fragments deliberately opt out of normal structural safeguards.

## Common validated limits [#common-validated-limits]

| Feature                 | Kysoql boundary                                                            |
| ----------------------- | -------------------------------------------------------------------------- |
| `LIMIT`                 | Non-negative safe integer, with extra rules where Salesforce requires them |
| Root `OFFSET`           | `0..2000`                                                                  |
| Child `OFFSET`          | Pilot API only and immediate parent must have literal `LIMIT 1`            |
| Parent paths            | Up to five child-to-parent levels in typed references                      |
| Nested child subqueries | Up to four levels below the root builder                                   |
| Query relationships     | Up to 20 parent-to-child and 55 child-to-parent relationships              |
| Semi and anti-joins     | At most two at the root `WHERE` level                                      |
| ROLLUP and CUBE         | Up to three grouping fields                                                |
| Data categories         | Up to three conditions with distinct category groups                       |
| `FOR UPDATE`            | Apex record queries only, without `ORDER BY` or `ALL ROWS`                 |
| `TYPEOF`                | Cannot be mixed with aggregate/grouping or conflicting selections          |

Filtered codegen objects cannot use `selectFields(...)`. Explicit selections are
still available. See [field filtering](/docs/codegen/field-filtering).

## Object-specific rules [#object-specific-rules]

Some Salesforce objects have stricter query shapes. Kysoql catches the cases it
can identify from the query and generated metadata.

<Accordions type="single">
  <Accordion title="Knowledge and feeds">
    `KnowledgeArticleVersion` and concrete `__kav` article versions require a root
    filter on `PublishStatus` or `Id`. `UserProfileFeed` requires `withUserId()`.
    Feed relationship-path ordering is restricted. See [Knowledge and feeds](/docs/core/advanced/knowledge-and-feeds).
  </Accordion>

  <Accordion title="UserRecordAccess">
    Queries require a user filter plus a record filter. Record ID lists are
    limited to 200 IDs, and selected access fields have matching ordering rules.
  </Accordion>

  <Accordion title="Custom metadata">
    `__mdt` filtering supports a narrower set of operators and boolean shapes.
    Metadata relationship fields can be selected and filtered where Salesforce
    supports them, but are not available for relationship-path ordering.
  </Accordion>

  <Accordion title="External objects">
    `__x` objects reject several aggregate, grouping, function, tracking, and
    filtering features that are available on normal CRM objects. Bare `COUNT()`
    remains available. Salesforce Connect can impose additional runtime rules.
  </Accordion>

  <Accordion title="Data 360">
    Generated DLO and DMO capabilities control `SET OPTIONS` and related query
    restrictions. See [Data 360 and query options](/docs/core/advanced/data-360).
  </Accordion>
</Accordions>

## Salesforce still has the final say [#salesforce-still-has-the-final-say]

Generated types are a snapshot. They cannot guarantee current sharing, CRUD/FLS,
package licensing, feature enrollment, selectivity, governor limits, or the
behaviour of every API version.

The bundled executors validate Salesforce response envelopes and paging metadata,
but they do not runtime-validate every selected field value against your generated
TypeScript schema. A `CompiledQuery` is also not a server-validated query plan.

Native REST can iterate root pages and records with explicit budgets and
cancellation. `execute()` collects root pages into memory. The JSforce adapter
handles root pagination but does not recursively drain child query locators in
the same way as the native REST adapter. See [REST execution](/docs/rest/execution)
and [JSforce](/docs/jsforce).

## Experimental and versioned features [#experimental-and-versioned-features]

Some features depend on Salesforce API version, org type, or feature enrollment.
The compiler does not negotiate these for you. Check the target org when using
beta or pilot features, external objects, Data 360, or Apex-specific syntax.

See [beta and pilot features](/docs/core/advanced/experimental) for the opt-in
APIs and the [Salesforce reference map](/docs/core/reference/salesforce) for the
upstream documentation.
