Identify and fix performance bottlenecks in authorization checks. Use this guide if:
  • Authorization checks consistently take >500 ms
  • Timeouts occur during peak traffic
  • CPU usage in your authorization service is high
  • Users notice slow page loads tied to permission checks

Common causes of slow queries

1. Too many authorization paths

Problem: Multiple rules grant the same permission, forcing Oso to evaluate every path. Example: A user can edit a document if they are:
  • Document owner
  • Folder admin (recursive check)
  • Organization admin with public access
Each path adds processing time.

2. Complex relationship chains

Problem: Deep hierarchies and multiple conditions increase processing time. Example: Access check involves folder parents, team memberships, and role inheritance in a single request.

Common performance bottlenecks

Deep folder hierarchies

Scenario: File sharing app with nested folders
# Checking parent folders recursively
allow(user: User, "read", folder: Folder) if
    has_role(user, "reader", folder);

allow(user: User, "read", folder: Folder) if
    parent_folder(folder, parent) and
    allow(user, "read", parent);
Performance impact:
  • 10-level deep folders = 10 database queries
  • Global admins trigger expensive “list all” operations
When risky:
  • 5 levels of nesting
  • Users with access to many folders
  • Frequent bulk “list all” queries

Multiple recursive relationships

Scenario: Document access through both folder hierarchy and team membership
allow(user: User, "read", doc: Document) if
    folder(doc, folder) and
    allow(user, "read", folder);

allow(user: User, "read", doc: Document) if
    team_member(user, team) and
    team_access(team, doc);
Performance impact: Each document check evaluates both folder AND team paths.

Complex condition chains

Scenario: Admin access to public documents
allow(user: User, "edit", doc: Document) if
    has_role(user, "admin", _) and
    is_public(doc) and
    in_organization(user, org) and
    document_organization(doc, org);
Performance impact: Four separate conditions must ALL be true:
  1. Check admin role
  2. Verify document is public
  3. Get user’s organization
  4. Match document’s organization
Optimization: Combine checks or add indexes on frequent condition sets.

Broad access patterns

Scenario: Super admin listing all accessible documents. Performance impact:
  • Evaluates thousands of resources
  • Large DB scans
  • Query optimizer struggles with atypical access patterns
When risky:
  • Global admin roles with organization-wide access
  • Service accounts with broad permissions
  • Bulk operations across many resources

Optimization strategies

1. Limit recursive depth

  • Flatten hierarchies - Keep folder nesting ≤5 levels
  • Cache permissions - Cache computed permissions per level
  • Use direct permissions - Grant direct permissions for frequently used resources
allow(user: User, "read", doc: Document) if
    has_role(user, "reader", doc);  # Direct permission

2. Reduce authorization paths

  • Consolidate roles - Merge similar toles
  • Prioritize paths - Put most common rules first
  • Remove redundant rules - Eliminate overlapping permission grants

3. Optimize for common queries

  • Profile query patterns - Identify your most common authorization checks
  • Add targeted facts - Pre-compute permissions for frequent queries
  • Use Local Authorization - Query your database directly

4. Handle broad access carefully

  • Separate admin interfaces - Don’t mix admin and end-user queries
  • Paginate results - Limit bulk operations
  • Cache admin permissions - Store broad access patterns
allow(user: User, action, resource) if
    has_role(user, "super_admin", _) and
    admin_action(action);  # Limit to admin-specific actions

Monitor and test performance

Track key metrics

  • Average response time - Target <100ms for simple queries
  • 95th percentile latency - Identify slow outliers
  • Query frequency - Identify optimization targets
  • Error rates - Spot timeouts

Use Oso Cloud logs

  1. Open the Logs page
  2. Filter for slow queries
  3. Identify patterns by user, resource, or rule

Load test scenarios

  • Typical user
  • Admin with broad access
  • Bulk operations
  • Deep hierarchy navigation

How Oso processes a query

  1. Policy Compilation - Convert your policy to internal format (cached)
  2. Policy Evaluation - Identify required data
  3. Data Query - Execute SQL against your facts
  4. Result Assembly - Return allow/deny decision
Time breakdown: ~90% in data query phase ~10% in policy processing