Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions documentation/configuration/cairo-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -844,6 +844,78 @@ every window function execution.
Prevents stack overflow errors when evaluating complex nested SQL. The value
is the approximate number of nested SELECT clauses allowed.

## Memory limits

These limits cap how much native memory a single workload may allocate, so a
runaway query, materialized view refresh, or WAL apply batch is stopped at its
source before it can drive the whole server toward out-of-memory. Each workload
has its own independent limit: a runaway in one does not draw against another's
budget, nor against the process-wide RSS limit (`ram.usage.limit.bytes` /
`ram.usage.limit.percent`).

All three default to `0`, which means unlimited, so behavior matches a server
without limits until you opt in. Set each limit as a byte count or a size with a
`K`, `M`, or `G` suffix, for example `512M` or `2G`. The limits are reloadable:
edit `server.conf` and call
[`reload_config()`](/docs/query/functions/meta/#reload_config), and the new value
applies to every workload that starts afterward, with no restart. A workload
already running keeps the limit it started with.

When a workload exceeds its limit, QuestDB raises an out-of-memory error at the
allocation that crossed the line and aborts that workload, while unrelated
workloads keep running. A user query fails with the error, a materialized view
refresh is invalidated, and a WAL apply suspends the affected table. The message
names the workload so you can tell it apart from a process-wide breach:

```
query memory limit exceeded [workload=QUERY, queryId=..., limit=..., used=..., size=..., memoryTag=...]
```

:::note

Coverage is best-effort. A limit constrains the allocation sites that grow with
data volume: hash and GROUP BY tables, sorts, joins, window partition buffers,
set operations, `LATEST BY`, SAMPLE BY fill, and Parquet decode buffers. Memory
that is structurally bounded, or that lives for the life of a process or session
(page-frame buffers, JIT buffers, table readers and writers, symbol tables,
connection buffers, memory-mapped pages), is accounted only against the global
RSS limit. Treat a workload limit as a guard against common runaway patterns,
not a hard ceiling on every allocation.

:::

Live usage and the effective limit for each running query are exposed by the
[`query_activity`](/docs/query/functions/meta/#query_activity) view through its
`memory_used` and `memory_limit` columns. QuestDB Enterprise can additionally set
a memory limit per user, group, or service account, which overrides this workload
limit for a principal's queries. See
[role-based access control](/docs/security/rbac/#memory-limits).

### cairo.mat.view.refresh.memory.limit.bytes

- **Default**: `0`
- **Reloadable**: yes

Maximum native memory a single materialized view refresh may allocate. `0`
disables the limit.

### cairo.query.memory.limit.bytes

- **Default**: `0`
- **Reloadable**: yes

Maximum native memory a single user SQL query may allocate. `0` disables the
limit. Subqueries and other nested work share the top-level query's budget
rather than each acquiring their own.

### cairo.wal.apply.memory.limit.bytes

- **Default**: `0`
- **Reloadable**: yes

Maximum native memory a single WAL apply batch may allocate. `0` disables the
limit.

## Batch operations

### cairo.create.as.select.retry.count
Expand Down
3 changes: 3 additions & 0 deletions documentation/configuration/materialized-views.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ These settings control materialized view SQL support and the background refresh
job. Materialized views can use dedicated worker threads or share the server's
common pool.

To cap the native memory a single refresh may allocate, see
[`cairo.mat.view.refresh.memory.limit.bytes`](/docs/configuration/cairo-engine/#memory-limits).

## cairo.mat.view.enabled

- **Default**: `true`
Expand Down
3 changes: 3 additions & 0 deletions documentation/configuration/wal.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ These settings control the Write-Ahead Log (WAL) subsystem, including parallel
apply threads, segment rollover, commit squashing, and cleanup of applied WAL
files.

To cap the native memory a single WAL apply batch may allocate, see
[`cairo.wal.apply.memory.limit.bytes`](/docs/configuration/cairo-engine/#memory-limits).

## cairo.wal.apply.parallel.sql.enabled

- **Default**: `true`
Expand Down
4 changes: 4 additions & 0 deletions documentation/getting-started/capacity-planning.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ For relatively small datasets i.e 4-40GB, and a read-heavy workload, performance
can be improved by maximising use of the OS page cache. Users should consider
increasing available RAM to improve the speed of read operations.

To bound how much native memory a single query, materialized view refresh, or
WAL apply may allocate, so one runaway workload cannot exhaust the server's RAM,
see [memory limits](/docs/configuration/cairo-engine/#memory-limits).

### Memory page size configuration

With frequent out-of-order (O3) writes over a large number of columns/tables,
Expand Down
19 changes: 14 additions & 5 deletions documentation/query/functions/meta.md
Original file line number Diff line number Diff line change
Expand Up @@ -224,18 +224,27 @@ Returns metadata on running SQL queries, including columns such as:
- query_start - timestamp of when query started
- state_change - timestamp of latest query state change, such as a cancellation
- state - state of running query, can be `active` or `cancelled`
- memory_used - native memory currently allocated by the query, in bytes. Only
the allocation sites covered by the
[per-query memory limit](/docs/configuration/cairo-engine/#memory-limits) are
counted
- memory_limit - effective native memory limit for the query, in bytes, or
`null` when the query runs unlimited. On QuestDB Enterprise a set principal
[memory limit](/docs/security/rbac/#memory-limits) overrides the configured
workload limit; the workload limit applies only when the principal has none
- query - text of sql query

**Examples:**

```questdb-sql
SELECT * FROM query_activity();
SELECT query_id, username, state, memory_used, memory_limit, query
FROM query_activity();
```

| query_id | worker_id | worker_pool | username | query_start | state_change | state | query |
| -------- | --------- | ----------- | -------- | --------------------------- | --------------------------- | ------ | --------------------------------------------------------- |
| 62179 | 5 | shared | bob | 2024-01-09T10:03:05.557397Z | 2024-01-09T10:03:05.557397 | active | select \* from query_activity() |
| 57777 | 6 | shared | bob | 2024-01-09T08:58:55.988017Z | 2024-01-09T08:58:55.988017Z | active | SELECT symbol,approx_percentile(price, 50, 2) from trades |
| query_id | username | state | memory_used | memory_limit | query |
| -------- | -------- | ------ | ----------- | ------------ | ---------------------------------------------------------- |
| 62179 | bob | active | 262144 | null | SELECT \* FROM query_activity() |
| 57777 | bob | active | 8388608 | 536870912 | SELECT symbol, approx_percentile(price, 50, 2) FROM trades |

## reader_pool

Expand Down
76 changes: 76 additions & 0 deletions documentation/query/sql/acl/alter-group.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: ALTER GROUP reference
sidebar_label: ALTER GROUP
description:
"ALTER GROUP SQL keywords reference documentation. Applies to RBAC in QuestDB
Enterprise."
---

import { EnterpriseNote } from "@site/src/components/EnterpriseNote"

<EnterpriseNote>
RBAC provides fine-grained database permissions management.
</EnterpriseNote>

`ALTER GROUP` modifies group settings.

For full documentation of the Access Control List and Role-based Access Control,
see the [RBAC operations](/docs/security/rbac) page.

---

## Syntax

```questdb-sql title="Set or clear memory limit"
ALTER GROUP groupName SET MEMORY LIMIT { size | UNLIMITED };
```

```questdb-sql title="Add or remove external alias"
ALTER GROUP groupName { WITH | DROP } EXTERNAL ALIAS externalAlias;
```

## Description

- `ALTER GROUP groupName SET MEMORY LIMIT size` - caps the native memory that
queries of the group's members may allocate. `size` is a byte count or a size
with a `K`, `M`, or `G` suffix, such as `512M` or `2G`.
- `ALTER GROUP groupName SET MEMORY LIMIT UNLIMITED` - removes the limit. `SET
MEMORY LIMIT 0` does the same.
- `ALTER GROUP groupName WITH EXTERNAL ALIAS externalAlias` - maps an external
OIDC or LDAP group to this group.
- `ALTER GROUP groupName DROP EXTERNAL ALIAS externalAlias` - removes an external
group mapping.

A group limit applies to a member only when that member has no limit of its own;
a user's own limit always takes priority. When several of a user's groups set a
limit, the most restrictive (smallest positive) one applies. A set limit
overrides the configured
[`cairo.query.memory.limit.bytes`](/docs/configuration/cairo-engine/#memory-limits)
workload limit and binds even when larger. Setting a group limit requires the
`SET MEMORY LIMIT` permission. See
[memory limits](/docs/security/rbac/#memory-limits) for how per-principal and
workload limits resolve.

For external group mapping with OIDC or LDAP, see the
[OpenID Connect (OIDC) integration](/docs/security/oidc/) guide.

## Examples

### Set memory limit

```questdb-sql
-- cap queries of the group's members at 2 GiB of native memory
ALTER GROUP analysts SET MEMORY LIMIT 2G;
-- remove the limit
ALTER GROUP analysts SET MEMORY LIMIT UNLIMITED;
```

The configured value can be verified with `SHOW GROUPS`, which reports it in the
`memory_limit` column.

### Map an external group

```questdb-sql
ALTER GROUP analysts WITH EXTERNAL ALIAS 'CN=Analysts,OU=Users,DC=example,DC=com';
ALTER GROUP analysts DROP EXTERNAL ALIAS 'CN=Analysts,OU=Users,DC=example,DC=com';
```
30 changes: 30 additions & 0 deletions documentation/query/sql/acl/alter-service-account.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ ALTER SERVICE ACCOUNT serviceAccountName DROP TOKEN TYPE
{ JWK | REST [token] };
```

```questdb-sql title="Set or clear memory limit"
ALTER SERVICE ACCOUNT serviceAccountName SET MEMORY LIMIT { size | UNLIMITED };
```

## Description

- `ALTER SERVICE ACCOUNT serviceAccountName ENABLE` - enables service account.
Expand All @@ -56,6 +60,20 @@ ALTER SERVICE ACCOUNT serviceAccountName DROP TOKEN TYPE
adds REST token to the service account.
- `ALTER USER serviceAccountName DROP TOKEN TYPE REST token` - removes REST
token from the service account.
- `ALTER SERVICE ACCOUNT serviceAccountName SET MEMORY LIMIT size` - caps the
native memory the service account's queries may allocate. `size` is a byte
count or a size with a `K`, `M`, or `G` suffix, such as `512M` or `2G`.
- `ALTER SERVICE ACCOUNT serviceAccountName SET MEMORY LIMIT UNLIMITED` - removes
the limit. `SET MEMORY LIMIT 0` does the same.

A user who assumes the service account runs under its memory limit. A set limit
overrides the configured
[`cairo.query.memory.limit.bytes`](/docs/configuration/cairo-engine/#memory-limits)
workload limit — binding even when larger — and the workload limit applies only
when the service account has none. Group limits are never merged into a service
account. Setting it requires the `SET MEMORY LIMIT` permission. See
[memory limits](/docs/security/rbac/#memory-limits) for how per-principal and
workload limits resolve.

## Examples

Expand Down Expand Up @@ -165,3 +183,15 @@ SHOW SERVICE ACCOUNT client_app;
| Password | true |
| JWK Token | false |
| REST Token | false |

### Set memory limit

```questdb-sql
-- cap the service account's queries at 1 GiB of native memory
ALTER SERVICE ACCOUNT ingest SET MEMORY LIMIT 1G;
-- remove the limit
ALTER SERVICE ACCOUNT ingest SET MEMORY LIMIT UNLIMITED;
```

The configured value can be verified with `SHOW SERVICE ACCOUNTS`, which reports
it in the `memory_limit` column.
31 changes: 31 additions & 0 deletions documentation/query/sql/acl/alter-user.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { EnterpriseNote } from "@site/src/components/EnterpriseNote"
For full documentation of the Access Control List and Role-based Access Control,
see the [RBAC operations](/docs/security/rbac) page.

---

## Syntax

```questdb-sql title="Enable / disable"
Expand All @@ -37,6 +39,10 @@ ALTER USER userName DROP TOKEN TYPE
{ JWK | REST [token] };
```

```questdb-sql title="Set or clear memory limit"
ALTER USER userName SET MEMORY LIMIT { size | UNLIMITED };
```

## Description

- `ALTER USER username ENABLE` - enables user account.
Expand All @@ -54,6 +60,19 @@ ALTER USER userName DROP TOKEN TYPE
REST token to user account.
- `ALTER USER username DROP TOKEN TYPE REST token` - removes REST token from
user account.
- `ALTER USER username SET MEMORY LIMIT size` - caps the native memory the
user's queries may allocate. `size` is a byte count or a size with a `K`, `M`,
or `G` suffix, such as `512M` or `2G`.
- `ALTER USER username SET MEMORY LIMIT UNLIMITED` - removes the limit. `SET
MEMORY LIMIT 0` does the same.

The limit applies to the user's queries on both the primary and replicas. A set
limit takes priority over the user's groups and overrides the configured
[`cairo.query.memory.limit.bytes`](/docs/configuration/cairo-engine/#memory-limits)
workload limit, binding even when larger. Setting it requires the
`SET MEMORY LIMIT` permission. See
[memory limits](/docs/security/rbac/#memory-limits) for how per-principal and
workload limits resolve.

## Examples

Expand Down Expand Up @@ -160,3 +179,15 @@ SHOW USER john;
| Password | true |
| JWK Token | false |
| REST Token | false |

### Set memory limit

```questdb-sql
-- cap the user's queries at 512 MiB of native memory
ALTER USER john SET MEMORY LIMIT 512M;
-- remove the limit
ALTER USER john SET MEMORY LIMIT UNLIMITED;
```

The configured value can be verified with `SHOW USERS`, which reports the
effective limit in the `memory_limit` column.
Loading
Loading