Benchmarks dashboard
The page draws every chart at build time from the run files. Each chart has a table view under it. The design colors are the same everywhere: A tuple core, B policy first, C compiled model. The engine comparison report is the prose summary of these numbers. The decision record explains how these measurements informed the architecture.
The charts use PG 18 (docker, optimized) on Apple M4, 10 CPU, 24 GB; container cpus=4 mem=6g: Postgres 18.6, the latest run for each design, scale and shape. This is the primary series, and we chose it on purpose. It is Docker, the newest Postgres version, and the optimized designs when their runs exist (otherwise the newest Docker series, then local). Cedar (E) comes from its own tagged run (tag p9). 4 pgbench clients, 10 s for each workload. Docker runs cover only the large default, medium deep and medium wide configurations. A figure never mixes environments or tags. The data has these series: PG 16 (docker); PG 16 (docker, optimized); PG 17 (docker); PG 17 (docker, optimized); PG 18 (docker); PG 18 (docker, optimized); PG 18 (docker, opt2); PG 18 (docker, opt3); PG 18 (docker, p5); PG 18 (docker, p6); PG 18 (docker, p6check); PG 18 (docker, p9); PG 16 (local). Compare Postgres versions on the Postgres versions page. Compare the runs before and after the optimization pass on the Optimizations page. All latencies are in milliseconds. There is one run for each configuration, so differences under about 20% are noise. The run files are in bench/baselines/data.
Design comparison for each workload
Section titled “Design comparison for each workload”Latency by workload and design
The bar is the p50 and the whisker is the p95, in milliseconds on a log axis. Pick a data scale and a team shape.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
- p95 whisker
large default
Table view: large default
| Workload | A p50 | B p50 | C p50 | D p50 | A p95 | B p95 | C p95 | D p95 |
|---|---|---|---|---|---|---|---|---|
| RBAC: single check | 0.30 | 0.27 | 0.24 | 0.22 | 0.56 | 0.41 | 0.33 | 0.36 |
| RBAC: first page | 0.76 | 0.73 | 0.67 | 0.72 | 1.44 | 1.10 | 0.91 | 1.81 |
| RBAC: count visible | 0.78 | 0.78 | 0.73 | 0.77 | 1.07 | 0.99 | 0.93 | 1.55 |
| RBAC: update one row | 0.47 | 0.47 | 0.36 | 0.28 | 0.65 | 0.68 | 0.50 | 0.44 |
| RBAC: assign a role | 0.15 | 0.14 | 0.17 | 0.14 | 0.23 | 0.22 | 0.24 | 0.22 |
| Sharing: list visible ids | 0.29 | 0.29 | 0.25 | 0.54 | 0.38 | 0.43 | 0.36 | 0.71 |
| Sharing: first page | 1.03 | 1.00 | 0.93 | 1.29 | 1.35 | 1.29 | 1.27 | 3.34 |
| Sharing: share one document | 0.15 | 0.14 | 0.17 | 0.23 | 0.23 | 0.21 | 0.25 | 0.35 |
| Parents, projection: first page | 1.33 | 1.15 | 1.05 | 1.66 | 2.62 | 1.55 | 1.57 | 2.61 |
| Parents, projection: count visible | 8.42 | 8.20 | 7.88 | 8.92 | 14.7 | 12.4 | 9.97 | 11.0 |
| Parents, single branch: first page | 45.6 | 13.7 | 4.94 | 1.40 | 66.3 | 16.8 | 6.55 | 9.45 |
| Parents, single branch: count visible | 75.1 | 21.6 | 11.9 | 8.44 | 92.4 | 27.6 | 15.5 | 16.0 |
| Nesting: nest a team | 0.15 | 0.62 | 57.7 | 0.24 | 0.27 | 0.78 | 77.2 | 0.50 |
| Nesting: check through a nested team | 0.31 | 0.32 | 0.30 | 0.41 | 0.48 | 0.42 | 0.45 | 0.64 |
medium default
Table view: medium default
| Workload | E p50 | E p95 |
|---|---|---|
| RBAC: single check | 0.31 | 0.47 |
| RBAC: first page | 0.49 | 0.70 |
| RBAC: count visible | 0.40 | 0.61 |
| RBAC: update one row | 0.58 | 1.08 |
| RBAC: assign a role | 0.26 | 0.42 |
| Sharing: list visible ids | 0.39 | 0.62 |
| Sharing: first page | 0.79 | 1.30 |
| Sharing: share one document | 0.26 | 0.47 |
| Parents, projection: first page | 0.93 | 1.61 |
| Parents, projection: count visible | 1.27 | 2.23 |
| Parents, single branch: first page | 0.84 | 1.88 |
| Parents, single branch: count visible | 1.19 | 2.41 |
| Nesting: nest a team | 1.17 | 1.76 |
| Nesting: check through a nested team | 0.37 | 0.52 |
| Per row: first page, every row checked (Cedar only) | 97.5 | 139 |
small default
Table view: small default
| Workload | E p50 | E p95 |
|---|---|---|
| RBAC: single check | 0.30 | 0.52 |
| RBAC: first page | 0.37 | 0.69 |
| RBAC: count visible | 0.32 | 0.61 |
| RBAC: update one row | 0.52 | 0.84 |
| RBAC: assign a role | 0.26 | 0.45 |
| Sharing: list visible ids | 0.35 | 0.50 |
| Sharing: first page | 0.56 | 0.90 |
| Sharing: share one document | 0.26 | 0.62 |
| Parents, projection: first page | 0.67 | 1.15 |
| Parents, projection: count visible | 0.66 | 1.06 |
| Parents, single branch: first page | 0.59 | 0.99 |
| Parents, single branch: count visible | 0.57 | 0.83 |
| Nesting: nest a team | 1.10 | 1.81 |
| Nesting: check through a nested team | 0.35 | 0.63 |
| Per row: first page, every row checked (Cedar only) | 35.1 | 47.5 |
medium deep
Table view: medium deep
| Workload | A p50 | B p50 | C p50 | D p50 | A p95 | B p95 | C p95 | D p95 |
|---|---|---|---|---|---|---|---|---|
| RBAC: single check | 0.29 | 0.27 | 0.24 | 0.22 | 0.40 | 0.36 | 0.32 | 0.36 |
| RBAC: first page | 0.44 | 0.46 | 0.42 | 0.41 | 0.56 | 0.57 | 0.57 | 0.70 |
| RBAC: count visible | 0.35 | 0.37 | 0.32 | 0.32 | 0.48 | 0.48 | 0.41 | 0.53 |
| RBAC: update one row | 0.48 | 0.46 | 0.35 | 0.28 | 0.66 | 0.58 | 0.46 | 0.45 |
| RBAC: assign a role | 0.15 | 0.14 | 0.18 | 0.14 | 0.23 | 0.21 | 0.24 | 0.21 |
| Sharing: list visible ids | 0.31 | 0.32 | 0.28 | 0.78 | 0.41 | 0.40 | 0.37 | 1.02 |
| Sharing: first page | 0.76 | 0.72 | 0.66 | 1.18 | 1.00 | 0.89 | 0.90 | 1.50 |
| Sharing: share one document | 0.15 | 0.14 | 0.17 | 0.23 | 0.22 | 0.20 | 0.23 | 0.31 |
| Parents, projection: first page | 1.00 | 0.83 | 0.73 | 1.79 | 1.26 | 1.14 | 1.00 | 2.74 |
| Parents, projection: count visible | 1.25 | 1.14 | 0.99 | 2.09 | 1.47 | 1.40 | 1.18 | 2.84 |
| Parents, single branch: first page | 7.41 | 4.52 | 2.83 | 1.23 | 9.76 | 5.54 | 3.80 | 2.40 |
| Parents, single branch: count visible | 6.40 | 3.74 | 2.10 | 1.54 | 8.06 | 6.01 | 2.69 | 2.52 |
| Nesting: nest a team | 0.15 | 0.63 | 75.1 | 0.23 | 0.23 | 0.73 | 115 | 0.31 |
| Nesting: check through a nested team | 0.34 | 0.34 | 0.30 | 0.43 | 0.47 | 0.44 | 0.41 | 0.54 |
medium wide
Table view: medium wide
| Workload | A p50 | B p50 | C p50 | D p50 | A p95 | B p95 | C p95 | D p95 |
|---|---|---|---|---|---|---|---|---|
| RBAC: single check | 0.29 | 0.28 | 0.24 | 0.21 | 0.40 | 0.37 | 0.35 | 0.31 |
| RBAC: first page | 0.44 | 0.46 | 0.44 | 0.40 | 0.56 | 0.59 | 0.61 | 0.61 |
| RBAC: count visible | 0.36 | 0.36 | 0.33 | 0.31 | 0.48 | 0.45 | 0.43 | 0.46 |
| RBAC: update one row | 0.49 | 0.48 | 0.38 | 0.27 | 0.63 | 0.95 | 0.49 | 0.48 |
| RBAC: assign a role | 0.15 | 0.14 | 0.18 | 0.14 | 0.23 | 0.24 | 0.26 | 0.25 |
| Sharing: list visible ids | 4.44 | 8.41 | 3.41 | 17.8 | 5.57 | 15.8 | 3.87 | 37.1 |
| Sharing: first page | 14.4 | 17.8 | 8.20 | 26.2 | 17.0 | 24.2 | 16.5 | 49.5 |
| Sharing: share one document | 0.15 | 0.16 | 0.17 | 0.23 | 0.22 | 0.40 | 0.24 | 0.32 |
| Parents, projection: first page | 15.0 | 15.1 | 8.73 | 38.6 | 18.3 | 21.7 | 18.8 | 51.1 |
| Parents, projection: count visible | 13.2 | 13.4 | 6.33 | 36.1 | 16.5 | 18.1 | 7.17 | 42.5 |
| Parents, single branch: first page | 14.7 | 13.7 | 8.06 | 23.6 | 19.2 | 20.0 | 10.7 | 34.9 |
| Parents, single branch: count visible | 13.3 | 12.2 | 6.61 | 21.6 | 16.6 | 17.5 | 7.48 | 27.6 |
| Nesting: nest a team | 0.15 | 1.47 | 61.2 | 0.23 | 0.21 | 1.81 | 73.3 | 0.30 |
| Nesting: check through a nested team | 0.37 | 0.34 | 0.31 | 0.45 | 0.48 | 0.61 | 0.44 | 0.96 |
Takeaway. At large/default: the RBAC workloads are equal on all designs (rbac_check p50 0.22 to 0.30 ms across designs); the single-branch parents page takes 1.40 ms on D and 45.6 ms on A (33x); a nest of a team takes 0.15 ms on A but 57.7 ms on C. The designs differ on sharing, parents and nesting, not on RBAC.
Raw report: COMPARISON.md (local PG 16, before optimization), per-run reports
Scale from small to large
Section titled “Scale from small to large”Scale from 10k to 1M documents
PG 18 (docker, optimized): p50 latency, default shape, log axis. The x axis is the number of documents in the table.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
RBAC: single check
rbac_check
Sharing: first page
share_select_page
Parents, projection: first page
parents_proj_select_page
Parents, single branch: first page
parents_select_page
Nesting: nest a team
write_nest_team
Nesting: check through a nested team
nest_check
Takeaway. From 10k to 1M documents, the sharing page grows slowly (). The single-branch parents page follows the number of visible ids and grows with it (). The RBAC workloads stay almost flat.
Table view
| Workload (p50 ms) | A small | A medium | A large | B small | B medium | B large | C small | C medium | C large | D small | D medium | D large | E small | E medium | E large |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RBAC: single check | n/a | n/a | 0.30 | n/a | n/a | 0.27 | n/a | n/a | 0.24 | n/a | n/a | 0.22 | 0.30 | 0.31 | n/a |
| Sharing: first page | n/a | n/a | 1.03 | n/a | n/a | 1.00 | n/a | n/a | 0.93 | n/a | n/a | 1.29 | 0.56 | 0.79 | n/a |
| Parents, projection: first page | n/a | n/a | 1.33 | n/a | n/a | 1.15 | n/a | n/a | 1.05 | n/a | n/a | 1.66 | 0.67 | 0.93 | n/a |
| Parents, single branch: first page | n/a | n/a | 45.6 | n/a | n/a | 13.7 | n/a | n/a | 4.94 | n/a | n/a | 1.40 | 0.59 | 0.84 | n/a |
| Nesting: nest a team | n/a | n/a | 0.15 | n/a | n/a | 0.62 | n/a | n/a | 57.7 | n/a | n/a | 0.24 | 1.10 | 1.17 | n/a |
| Nesting: check through a nested team | n/a | n/a | 0.31 | n/a | n/a | 0.32 | n/a | n/a | 0.30 | n/a | n/a | 0.41 | 0.35 | 0.37 | n/a |
Raw report: COMPARISON.md (local PG 16)
Default, deep and wide shapes
Section titled “Default, deep and wide shapes”Default, deep and wide team shapes (medium data)
PG 18 (docker, optimized): p50 latency, log axis. In deep, the teams are in chains 9 levels deep. In wide, each user is in 50 teams and each team has 50 shares.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
Sharing: first page
share_select_page
Sharing: list visible ids
share_list_objects
Parents, projection: first page
parents_proj_select_page
Nesting: check through a nested team
nest_check
Takeaway. Medium data, PG 18 (docker, optimized): in the wide shape the designs differ most: A 14.4, B 17.8, C 8.20 ms (1.8x between A and C).
Table view
| Workload (p50 ms) | A default | B default | C default | D default | E default | A deep | B deep | C deep | D deep | E deep | A wide | B wide | C wide | D wide | E wide |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Sharing: first page | n/a | n/a | n/a | n/a | 0.79 | 0.76 | 0.72 | 0.66 | 1.18 | n/a | 14.4 | 17.8 | 8.20 | 26.2 | n/a |
| Sharing: list visible ids | n/a | n/a | n/a | n/a | 0.39 | 0.31 | 0.32 | 0.28 | 0.78 | n/a | 4.44 | 8.41 | 3.41 | 17.8 | n/a |
| Parents, projection: first page | n/a | n/a | n/a | n/a | 0.93 | 1.00 | 0.83 | 0.73 | 1.79 | n/a | 15.0 | 15.1 | 8.73 | 38.6 | n/a |
| Nesting: check through a nested team | n/a | n/a | n/a | n/a | 0.37 | 0.34 | 0.34 | 0.30 | 0.43 | n/a | 0.37 | 0.34 | 0.31 | 0.45 | n/a |
Raw report: COMPARISON.md (local PG 16, before optimization)
Read against write
Section titled “Read against write”Read cost against write cost
PG 18 (docker, optimized). Each point is one design. The x axis is the read of the sharing page (share_select_page p50). The y axis is a nest of a team of 1,000 members (write_nest_team p50). Both axes are in ms on a log scale. A point nearer the bottom left is better.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
Medium, wide shape
Large, default shape
Takeaway. No design wins on both axes. In the medium, wide shape, A reads the sharing page in 14.4 ms and nests a team in 0.15 ms. C reads in 8.20 ms (1.8x faster), but a nest costs 61.2 ms (410x slower), because C writes membership rows under a global lock.
Table view
| Configuration | Design | share_select_page p50 | write_nest_team p50 |
|---|---|---|---|
| Medium, wide shape | A | 14.4 | 0.15 |
| Medium, wide shape | B | 17.8 | 1.47 |
| Medium, wide shape | C | 8.20 | 61.2 |
| Medium, wide shape | D | 26.2 | 0.23 |
| Large, default shape | A | 1.03 | 0.15 |
| Large, default shape | B | 1.00 | 0.62 |
| Large, default shape | C | 0.93 | 57.7 |
| Large, default shape | D | 1.29 | 0.24 |
Raw report: COMPARISON.md (local PG 16, before optimization: Nesting)
Parents: projection against single branch
Section titled “Parents: projection against single branch”Parents: two-arm projection against single-branch policy
PG 18 (docker, optimized): first page p50, default shape, ms on a log axis shared by the 3 panels.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
Small (10k documents)
Medium (100k documents)
Large (1M documents)
Takeaway. The policy shape costs more than the design. At 1M documents the single-branch page is 34x slower than the projection on A (1.33 to 45.6 ms), 12x on B and 4.7x on C (1.05 to 4.94 ms). The reason is that the design must materialize every visible id.
Table view
| Scale | Policy | A p50 | B p50 | C p50 | D p50 | E p50 |
|---|---|---|---|---|---|---|
| small | projection | n/a | n/a | n/a | n/a | 0.67 |
| small | single branch | n/a | n/a | n/a | n/a | 0.59 |
| medium | projection | n/a | n/a | n/a | n/a | 0.93 |
| medium | single branch | n/a | n/a | n/a | n/a | 0.84 |
| large | projection | 1.33 | 1.15 | 1.05 | 1.66 | n/a |
| large | single branch | 45.6 | 13.7 | 4.94 | 1.40 | n/a |
Raw report: COMPARISON.md (local PG 16, before optimization: policy shape)
Seed time and storage
Section titled “Seed time and storage”Seed time and storage, per phase
Left: native-API load time for each phase (seconds, log axis). Right: size of the permissions tables after each phase (cumulative MB, after VACUUM FULL). Proj. is parents seeded through the folder_id projection. Links is a parent row for each document.
- A Tuple core
- B Policy first
- C Compiled model
- D Per-model tables
- E Cedar
large default
Seed time
seconds per phase, log axis
Storage
cumulative MB after each phase
Table view: large default
| Phase | A seed s | B seed s | C seed s | D seed s | A MB | B MB | C MB | D MB |
|---|---|---|---|---|---|---|---|---|
| RBAC | 5.14 | 4.31 | 4.95 | 4.86 | 7.00 | 7.40 | 5.30 | 5.40 |
| Sharing | 0.65 | 1.00 | 1.93 | 1.84 | 18.7 | 19.6 | 21.3 | 16.1 |
| Parents (proj.) | 0.08 | 0.11 | 0.34 | 0.10 | 19.6 | 20.6 | 22.3 | 16.8 |
| Parents (links) | 31.0 | 44.8 | 17.6 | 33.8 | 404 | 378 | 182 | 285 |
| Nesting | 0.05 | 0.02 | 0.04 | 0.03 | 404 | 378 | 183 | 285 |
medium default
Seed time
seconds per phase, log axis
Storage
cumulative MB after each phase
Table view: medium default
| Phase | E seed s | E MB |
|---|---|---|
| RBAC | 0.80 | 4.20 |
| Sharing | 8.19 | 40.8 |
| Parents (proj.) | 0.15 | 42.2 |
| Parents (links) | 3.90 | 66.7 |
| Nesting | 0.02 | 66.7 |
small default
Seed time
seconds per phase, log axis
Storage
cumulative MB after each phase
Table view: small default
| Phase | E seed s | E MB |
|---|---|---|
| RBAC | 0.10 | 1.50 |
| Sharing | 1.15 | 7.80 |
| Parents (proj.) | 0.08 | 8.10 |
| Parents (links) | 0.54 | 10.6 |
| Nesting | 0.02 | 10.6 |
medium deep
Seed time
seconds per phase, log axis
Storage
cumulative MB after each phase
Table view: medium deep
| Phase | A seed s | B seed s | C seed s | D seed s | A MB | B MB | C MB | D MB |
|---|---|---|---|---|---|---|---|---|
| RBAC | 0.60 | 0.48 | 0.81 | 0.46 | 3.60 | 3.90 | 2.90 | 3.00 |
| Sharing | 0.36 | 0.48 | 1.08 | 0.89 | 9.50 | 10.1 | 15.0 | 8.70 |
| Parents (proj.) | 0.04 | 0.06 | 0.15 | 0.05 | 10.0 | 10.6 | 15.5 | 9.00 |
| Parents (links) | 2.14 | 3.97 | 1.57 | 3.18 | 48.6 | 46.5 | 31.5 | 35.9 |
| Nesting | 0.02 | 0.02 | 0.06 | 0.02 | 48.6 | 46.5 | 33.1 | 35.9 |
medium wide
Seed time
seconds per phase, log axis
Storage
cumulative MB after each phase
Table view: medium wide
| Phase | A seed s | B seed s | C seed s | D seed s | A MB | B MB | C MB | D MB |
|---|---|---|---|---|---|---|---|---|
| RBAC | 0.58 | 0.51 | 0.84 | 0.45 | 3.60 | 3.90 | 2.90 | 3.00 |
| Sharing | 5.88 | 12.6 | 24.7 | 13.3 | 97.4 | 105 | 192 | 81.4 |
| Parents (proj.) | 0.04 | 0.35 | 0.20 | 0.05 | 97.9 | 106 | 192 | 81.8 |
| Parents (links) | 2.32 | 13.0 | 1.65 | 3.18 | 136 | 142 | 208 | 109 |
| Nesting | 0.04 | 0.02 | 0.04 | 0.01 | 136 | 142 | 209 | 109 |
Takeaway. Per-document parent links are the largest part of both costs at large/default: A 31.0 s and +385 MB, B 44.8 s and +357 MB, C 17.6 s and +160 MB, D 33.8 s and +268 MB. The two-arm projection needs none of them. The other phases are small in comparison.
Raw report: COMPARISON.md (local PG 16, before optimization: storage and seed cost)
What each workload measures
Section titled “What each workload measures”The names and the descriptions come from the header of each workload SQL file in
pg_permissions/bench/workloads/ and pg_permissions/bench/designs/c/workloads/. The three designs use the same workload names and the same intent.
| Workload | What it measures | Kind |
|---|---|---|
rbac_checkRBAC: single check | One permission check in the user's home org (the per-row path for writes). | read |
rbac_select_pageRBAC: first page | First page of the user's documents through RLS (typical list view). | read |
rbac_select_countRBAC: count visible | Count every document the user can see through RLS (worst case: touches every visible row). | read |
rbac_update_oneRBAC: update one row | Update one document in the user's home org by primary key (single-row write under RLS). | write |
write_assign_roleRBAC: assign a role | Admin write: assign a role to a new user in a random org. | write |
share_list_objectsSharing: list visible ids | Sharing: every document the user can view through direct grants and nested teams. | read |
share_select_pageSharing: first page | Sharing: first page through the two-branch RLS policy (org roles or shares). | read |
write_shareSharing: share one document | Sharing admin write: share a random document with a random user (1 tuple, no lock). | write |
parents_proj_select_pageParents, projection: first page | Parents, two-arm projection: first page through the policy from seed_parents.sql (shares by id, org roles and folder viewers projected onto folder_id; no hand-written org_id branch). | read |
parents_proj_select_countParents, projection: count visible | Parents, two-arm projection: count every document visible through the policy from seed_parents.sql (worst case: touches every visible row). | read |
parents_select_pageParents, single branch: first page | Parents, single branch: first page through the policy from seed_parent_docs.sql (one engine call returns every visible document id: org roles and folder viewers through the document's parent link, plus shares). | read |
parents_select_countParents, single branch: count visible | Parents, single branch: count every document visible through the policy from seed_parent_docs.sql (worst case: touches every visible row). | read |
write_nest_teamNesting: nest a team | Admin write where Design C pays most: nest the 1,000-member team md5('nest-src') (seeded by seed_sharing.sql) into a random team of the nested tree. | write |
nest_checkNesting: check through a nested team | Read side of nesting: one check for a user who reaches a document only through a nested team. | read |
plain_list_objectsConditions: list visible ids, unconditioned twin | Conditions, twin without: every document the user can view through `viewer` (shares, nested teams, parent folders), on the data of the conditions phase. | read |
cond_list_objectsConditions: list visible ids through conditioned teams | Conditions: every document the user can view through `cviewer`, the conditioned copy of `viewer` (seed_conditions.sql: a condition on every team membership and team grant). | read |
cond_select_pageConditions: first page through conditioned teams | Conditions: first page through the policies after seed_conditions.sql (the FGA policy on `cviewer`, org roles through seed_rbac.sql's RBAC policy). | read |
cond_nest_checkConditions: check through a nested, conditioned team | Conditions: one Check through a nested, conditioned team. | read |
plain_list_usersConditions: list users, unconditioned twin | Conditions, twin without: ListUsers (the admin API, fga_list_users) for the users who can view a document shared with a random team, through `viewer`. | read |
cond_list_usersConditions: list users through conditioned teams | Conditions: ListUsers for the same documents as plain_list_users, through `cviewer` (every membership and grant on the way carries the condition). | read |
block_list_objectsNot monotone: list ids on viewer but not blocked | Not monotone: ListObjects on `can_view: viewer but not blocked` (seed_blocklist.sql), the set-based difference. | read |
block_or_mute_list_objectsNot monotone: list ids on viewer but not (blocked or muted) | Not monotone: ListObjects on `can_view_unmuted: viewer but not (blocked or muted)` (seed_blocklist.sql), a union under the subtract. | read |
intersect_list_objectsNot monotone: list ids on editor and viewer | Not monotone: ListObjects on `can_edit: editor and viewer` (seed_blocklist.sql), an intersection. | read |
row_select_pagePer row: first page, every row checked (Cedar only) | read |