Skip to content

perf(syncer): batch concurrent Okta reads and reuse group scans#543

Merged
somethingnew2-0 merged 4 commits into
mainfrom
pcollins/syncer-concurrent-batching-028220
Jul 16, 2026
Merged

perf(syncer): batch concurrent Okta reads and reuse group scans#543
somethingnew2-0 merged 4 commits into
mainfrom
pcollins/syncer-concurrent-batching-028220

Conversation

@somethingnew2-0

@somethingnew2-0 somethingnew2-0 commented Jul 16, 2026

Copy link
Copy Markdown
Collaborator

What & why

The group membership and ownership sync passes issued one Okta list call per group, serially, so a sync run's wall-clock scaled linearly with the number of groups — the dominant cost of a run. This makes those per-group Okta reads concurrent.

Each pass now fetches a batch of groups' member/owner lists concurrently via asyncio.gather, then reconciles each result against the DB sequentially. The serial reconciliation is deliberate: the syncer shares a single AsyncSession, which must never be used concurrently, so only the network reads fan out. Batching in bounded groups (rather than prefetching every group at once) keeps peak memory to one batch of lists and keeps the number of concurrent Okta requests modest, so rate-limit pressure stays low (the SDK still retries any transient errors). A per-group fetch failure is captured and skipped rather than aborting the batch.

The batch size is set by the sync command's --group-batch-size flag (default 10, minimum 1).

Supporting changes in the sync command:

  • Pool one Okta client (and its aiohttp connector) for the whole run so the concurrent fan-out reuses connections.
  • Fetch the group-rule listing and the group listing once each, reused across the membership and ownership passes.

sync_groups keeps its own group-list fetch on purpose — in authoritative mode it creates/deletes groups in Okta, so the shared snapshot is taken after it runs to keep the later passes' behavior identical. sync_group_memberships / sync_group_ownerships take the shared groups and group-rule data as optional parameters (defaulting to fetching them) plus a required batch_size, so standalone and test callers are unaffected.

🤖 Generated with Claude Code

Comment thread api/syncer.py Outdated
@somethingnew2-0
somethingnew2-0 marked this pull request as ready for review July 16, 2026 18:41
somethingnew2-0 and others added 3 commits July 16, 2026 12:02
The group membership and ownership syncs fetch each batch of
SYNC_GROUP_BATCH_SIZE (10) groups' Okta member/owner lists concurrently
via asyncio.gather, then reconcile each against the DB sequentially so
the shared AsyncSession is never used concurrently. Batching bounds both
Okta rate-limit pressure and the peak memory held to one batch of lists
at a time; per-group fetch failures are captured and skipped rather than
aborting the batch.

The sync CLI command now pools one Okta client (and its aiohttp
connector) for the whole run, and fetches the group-rule listing once
and the group listing once (after sync_groups) for reuse across the
membership and ownership passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a SYNC_GROUP_BATCH_SIZE setting (default 10, minimum 1) and a
--group-batch-size flag on the sync command that overrides it per run.
sync_group_memberships and sync_group_ownerships take an optional
batch_size that falls back to the configured value.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per review feedback: sync_group_memberships and sync_group_ownerships
now take a required keyword-only batch_size instead of resolving a None
default against settings themselves. The sync command resolves the
--group-batch-size flag against SYNC_GROUP_BATCH_SIZE once and passes the
concrete value down.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Jeff-Rowell
Jeff-Rowell previously approved these changes Jul 16, 2026
@somethingnew2-0
somethingnew2-0 force-pushed the pcollins/syncer-concurrent-batching-028220 branch from a666b34 to 5fa8d22 Compare July 16, 2026 20:38
…ly flag

Remove the SYNC_GROUP_BATCH_SIZE config setting; the group batch size is
now purely the sync command's --group-batch-size flag, which defaults to
10. sync_group_memberships / sync_group_ownerships still take a required
batch_size, supplied by the CLI flag or by callers directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@somethingnew2-0
somethingnew2-0 enabled auto-merge (squash) July 16, 2026 20:48
@somethingnew2-0
somethingnew2-0 merged commit e241100 into main Jul 16, 2026
6 checks passed
@somethingnew2-0
somethingnew2-0 deleted the pcollins/syncer-concurrent-batching-028220 branch July 16, 2026 21:18
somethingnew2-0 added a commit that referenced this pull request Jul 17, 2026
The value is a bound on how many group member/owner list fetches run
concurrently, not a chunk size, so rename it to match: the CLI flag
--group-batch-size becomes --group-fetch-concurrency and the batch_size
parameters become concurrency. The old flag is dropped (it shipped only
days ago in #543).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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