Skip to content

feat: merge equivalent checks in BatchCheck (beta) - #334

Draft
Siddhant-K-code wants to merge 3 commits into
mainfrom
siddhant-k-code-optimize-relation-aliases
Draft

Siddhant-K-code wants to merge 3 commits into
mainfrom
siddhant-k-code-optimize-relation-aliases

Conversation

@Siddhant-K-code

@Siddhant-K-code Siddhant-K-code commented Nov 12, 2026 •

Copy link
Copy Markdown
Member

Adds an opt-in merge_equivalent_checks option to batch_check (beta). When it's on, checks that are certain to get the same answer are sent once, and the answer is copied back to each of them.

Description

What problem is being solved?

A batch_check often asks the same question more than once. It might check an alias like define can_view: viewer next to viewer, or repeat the same check. Each one is sent and evaluated separately, which costs server work and request size and gives no new information.

How is it being solved?

With merge_equivalent_checks on, the SDK:

  1. reads the authorization model once per client and caches it;
  2. groups checks that are certain to get the same answer;
  3. sends one check per group;
  4. copies each answer back to every check in the group.

You still get one result per check you passed in. With the option off, nothing changes.

options = {
    "authorization_model_id": "01GXSA8YR785C4FYS3C0RTG7B1",
    "merge_equivalent_checks": True,
}
response = await fga_client.batch_check(ClientBatchCheckRequest(checks=checks), options)
response.checks_sent  # how many checks were actually sent

What merges

  • Aliases, including chains such as can_share: can_view → can_view: viewer.
  • Exact repeats: the same user, relation, object, context and contextual tuples.

If the SDK can't be sure two checks match, it sends them separately.

Rules

  • Bool only. merge_equivalent_checks must be True or False. Any other value fails validation, so a typo can't silently leave it off.
  • Model ID required. Set it in the options or the configuration. Without it, the call fails before anything is sent.
  • Fallback. If the model can't be read (for example, no read access), the SDK logs a warning and sends the checks unmerged. A failed read is tried again after 60 seconds.
  • Correlation IDs must match ^[\w\d-]{1,36}$. Missing ones are generated. Duplicates are rejected.
  • Errors. If a merged check returns an error, every check in its group gets that error.
  • Order. Results come back in input order.

What changes are made to solve it?

  • Async and sync clients: the new option on batch_check, plus checks_sent on the response.
  • Model cache, one per client:
    • parallel calls share a single read;
    • holds up to 32 models;
    • a failed read is remembered for 60 seconds.
  • Telemetry (on by default):
    • fga-client.batch_check.checks_requested
    • fga-client.batch_check.checks_sent
    • fga-client.batch_check.merge_fallback
    • fga-client.model_cache.lookup, with a new fga-client.model_cache.result attribute (hit/miss)
  • Docs: a "Merge equivalent checks (beta)" section in the README, and new rows in docs/opentelemetry.md.
  • Tests:

References

Notes for reviewers

Review Checklist

  • I have clicked on "allow edits by maintainers".
  • I have added documentation for new/changed functionality in this PR or in a PR to openfga.dev [Provide a link to any relevant PRs in the references section above]
  • The correct base branch is being used, if not main
  • I have added tests to validate that the change in functionality is working as expected

@coderabbitai

coderabbitai Bot commented Nov 12, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@codecov-commenter

codecov-commenter commented Nov 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.32%. Comparing base (c5d3305) to head (5b22035).

❌ Your project status has failed because the head coverage (72.32%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #334      +/-   ##
==========================================
+ Coverage   69.99%   72.32%   +2.33%     
==========================================
  Files         142      144       +2     
  Lines       10774    11196     +422     
==========================================
+ Hits         7541     8098     +557     
+ Misses       3233     3098     -135     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Reject a non-bool merge_equivalent_checks value instead of silently
  leaving merging off.
- Use fullmatch for correlation IDs so a trailing newline is rejected.
- Test that the model read carries the caller's headers.
- README: clarify the model cache is per model.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants