Monorepos with 3+ million lines of code have specific properties that make out-of-the-box code review automation configuration inadequate. The style graph for a large monorepo isn't one graph — it's a collection of subgraphs with different convention densities, different language mixes, different team ownership models, and often years of accumulated style drift between subsystems. Getting Replixa to produce useful signal on a codebase of this size requires a phased onboarding approach, not a single-step configuration.
This guide is written for an engineering team onboarding Replixa to a monorepo that includes 5–15 distinct product or infrastructure modules, multiple programming languages, and cross-team ownership. The total size assumption is 2–8 million lines of code. Below that, the standard quickstart process works without modification. Above 8 million, contact us directly — there are infrastructure considerations specific to very large repositories that the standard onboarding doesn't cover.
Phase 1: Scope analysis before configuration
The first step is understanding your monorepo's structure before writing any configuration. You need to answer four questions:
- How many distinct style subgraphs does this codebase need? A monorepo where all modules use the same framework, language, and conventions can be treated as a single graph. A monorepo with a Go backend, a TypeScript frontend, a Python data pipeline, and a Rust SDK needs at minimum four language-distinct subgraphs — and likely more if teams have developed different conventions within the same language.
- Which modules have stable, high-density patterns? These are the modules that will produce the most reliable and highest-value style graph suggestions immediately. Modules that have been in active development for 2+ years with a consistent team have patterns the graph can learn from quickly.
- Which modules have low pattern stability or are under active refactoring? These should be excluded from style graph review initially. A module where the architecture is changing every sprint will produce an inconsistent graph, which produces inconsistent suggestions, which trains developers to dismiss the suggestion channel.
- Which cross-boundary PR patterns are common? If 30% of your PRs modify code in multiple modules, you need to understand what the cross-boundary review experience will look like. A PR modifying a shared library and three consuming services should receive suggestions calibrated to the library's conventions for the library changes, and to each service's conventions for the service changes.
Phase 2: Initial path scoping — start narrow
Don't onboard the entire monorepo at once. Start with 2–3 modules that meet these criteria: stable patterns, single-language or simple language mix, active PR volume (at least 5–10 PRs per week per module), and a team that's interested in piloting the tooling.
A sample initial configuration for a monorepo with a services/ directory containing multiple Go microservices:
# replixa.yml — Phase 1 initial scope
version: 2
review:
include:
- "services/auth/**"
- "services/billing/**"
exclude:
- "**/*_gen.go" # Generated protobuf/gRPC files
- "**/vendor/**"
- "services/*/testdata/**"
suggestion_threshold: 0.78 # Start conservative
teams:
- name: auth
paths: ["services/auth/**"]
suggestion_threshold: 0.75
- name: billing
paths: ["services/billing/**"]
suggestion_threshold: 0.78
Run with this scope for 2–3 weeks. In that period, you're looking for: are developers applying the suggestions (acceptance rate > 50%), are suggestions appearing on the right kinds of deviations (no obvious false positives), and are there categories of suggestions that the team finds noisy and wants suppressed?
Phase 3: Module expansion and subgraph partitioning
Once the pilot modules are producing useful signal, expand to the next tier of modules. Add 3–5 more modules per expansion wave, prioritizing by pattern stability and PR volume. Each expansion wave gives you 2–3 weeks of calibration time before the next wave.
At this stage, you'll also need to make explicit decisions about how cross-module boundaries are handled. The key configuration option is graph_partition_by:
# replixa.yml — Phase 3 partitioned graph configuration
version: 2
graph:
# Partition style graph by top-level module directory
# Each partition builds an independent subgraph
partition_by: top_level_directory
# Alternatively, partition by explicit path groups
# (useful if top-level structure doesn't map cleanly to style boundaries)
# partition_by: explicit
# partitions:
# - name: go-services
# paths: ["services/**/*.go"]
# - name: typescript-frontend
# paths: ["frontend/**/*.ts", "frontend/**/*.tsx"]
# - name: python-data
# paths: ["data/**/*.py"]
review:
include:
- "services/**"
- "frontend/**"
- "lib/shared/**"
exclude:
- "**/*_gen.*"
- "**/vendor/**"
- "**/node_modules/**"
- "data/migrations/**"
- "infra/**" # Terraform/config files — separate review toolchain
Graph partitioning controls whether the style graph learns cross-boundary patterns or keeps subgraphs independent. For most monorepos, partition-by-module produces better results because it prevents conventions from one module from "leaking" into suggestions for another module that has intentionally different conventions.
Phase 4: Progressive threshold tuning
After 6–8 weeks on a fully expanded scope, you have enough acceptance rate and dismissal rate data to tune thresholds module by module. The calibration heuristic:
- Acceptance rate > 80%: threshold may be too high. Consider lowering by 0.03–0.05 to surface more suggestions.
- Acceptance rate 50–80%: healthy range. Leave the threshold or make small adjustments based on developer feedback.
- Acceptance rate 30–50%: threshold is likely too low, generating noise. Raise by 0.05 or investigate which suggestion categories have low acceptance and suppress them.
- Acceptance rate < 30%: something is structurally wrong — either the graph quality is poor for that module (low pattern stability), or the module has strong conventions that the graph isn't capturing correctly. Run a graph quality diagnostic.
Handling cross-boundary PRs
The most common complaint during monorepo onboarding: a PR that touches both a stable, well-reviewed module and a newly-onboarded module with an immature graph generates mixed-quality suggestions. The stable module suggestions are good; the immature module suggestions are noisy.
The solution is per-module threshold overrides in the teams configuration, combined with time-boxing the immature module's review scope. Set a higher threshold for immature modules — 0.85 or 0.90 — until the graph matures. This means fewer suggestions from those modules, but higher precision on the ones that do appear.
For cross-boundary PRs where you want to ensure that suggestions from Module A don't contaminate the review experience for Module B changes in the same PR, the graph partitioning configuration ensures each module's suggestions are independently calibrated. A PR modifying 40 files across 4 modules generates suggestion threads scoped to each module's graph independently — not a single blended-graph review.
Performance and scale considerations
For repositories above 3 million lines, initial graph construction takes 15–25 minutes and runs on Replixa's infrastructure during onboarding. Per-PR incremental updates to the graph run in 8–15 seconds. Suggestion generation after graph update runs in 45–90 seconds. The total time from PR open to first suggestions is under 2 minutes for typical-size PR diffs against a fully initialized graph.
For very active monorepos with concurrent PRs updating the same modules simultaneously, Replixa uses a read-consistent snapshot of the graph at PR-open time — each PR's suggestions are generated against the graph state at the moment the PR was opened, rather than a continuously-updated live graph. This prevents race conditions where one PR's merge updates the graph mid-review for another PR. The tradeoff is that a PR opened immediately after a major refactor merge won't see the new graph until the next time the PR's review is triggered (e.g., a new commit push).