> For the complete documentation index, see [llms.txt](https://help.resouris.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.resouris.com/part-2-running-resouris/solver-scaling.md).

# Solver scaling

*v1.7.0 introduces automatic solver scaling: your roster generates the same way for small tenants and quietly picks a decomposed solve path when your candidate space gets large. No configuration required for typical use.*

## What changed for you

The ReSouris solver has always used constraint programming (CP-SAT) to build rosters. In v1.7.0 the underlying model is more efficient and, importantly, **adaptive**: when your problem is small the solver keeps doing what it always did; when your problem is large it automatically picks a decomposed solve path that stays within memory + time budgets.

There is nothing to configure. The solver picks the right path per solve, per tenant, using a candidate-count threshold.

## When it matters

The three tiers roughly correspond to:

| Approx department size                                | Threshold crossed              | Solve path                           |
| ----------------------------------------------------- | ------------------------------ | ------------------------------------ |
| Small clinical department (\~50 workers)              | Below 500,000 candidates       | Joint (legacy) solve                 |
| Mid to large trust department (\~200-500 workers)     | 500,000 – 1,000,000 candidates | Position cascade (pos=1, then pos=2) |
| Very large / nursing directorate (\~500-1000 workers) | Above 1,000,000 candidates     | Per-week sharded solve               |

*Candidate count* is a technical measure the solver computes at the start of each run. It scales roughly with `staff × slots × service lines × positions × room options`.

## Rollback

Two safety switches exist for operators, in case a customer wants to force the pre-v1.7.0 solver behaviour on their tenant.

**Per-deployment** — set the environment variable `RESOURIS_SOLVER_SCALE_MODE` to `legacy` (or `scale` to force the new path). Default is `auto`. Value is read at solve time; no worker restart needed.

**Per-tenant** — set the `tenants.solver_mode_override` column to `'legacy'` or `'scale'` for that tenant. Takes effect on the tenant's next solve; other tenants unaffected. NULL means "use the deployment default".

## Telemetry

Every solve records a row into `solver_run_stats` with the picked formulation, the candidate count, the wall clock, and the memory budget. Trust admins can query this table via psql. **Auto-roster diagnostics** (Scheduling → Auto-roster diagnostics) now covers the operator's usual question — why the last run failed, and per-pass coverage for the ones that succeeded — but it does not surface `solver_run_stats` itself, so formulation and memory-budget figures are still a psql query.

## Frequently asked

**Will my existing rosters look different after v1.7.0?** No, unless your solves cross the F7 threshold. Small departments continue on the legacy path with bit-identical output. Above threshold, coverage is preserved but the assignment set may differ (the cascade path can produce a different — but equally valid — placement).

**Do I need to reload anything?** No. The v1.7.0 tag is picked up automatically on your next deployment. No schema changes require operator input.

**Can I test the new path before enabling it tenant-wide?** Yes. Set `RESOURIS_SOLVER_SCALE_MODE=scale` on a staging deployment; every solve there uses the sparse formulation regardless of size. Compare rosters with a production side-by-side then flip the env var back to `auto`.

## Beyond sharding

For departments larger than the sharded path comfortably handles — roughly 2,000 workers and up in a single solve — the intended next step is **column generation** (Dantzig-Wolfe decomposition), on the same trigger model: automatic per-tenant, no operator configuration, reading the same telemetry table.

> ⚠️ **It is not scheduled, and this section used to say it was.** It was published as "Coming next (v1.7.1)"; v1.7.1 shipped something else entirely and the product is many releases past it. A roadmap item pinned to a version that has already gone by reads as a feature you should already have. If you are sizing a deployment, size it against the three paths above, which exist.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://help.resouris.com/part-2-running-resouris/solver-scaling.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
