# Default MySQL prepared-statement forecasts

MySQL databases automatically receive a separate forecast in
`metrics.mysqlPreparedStatementForecasts`. No enable switch is required.
The model is hosted only: source, fitted parameters and historical artifacts
are not downloadable. The forecast never changes CPU, latency, throughput,
cost, connection pressure, HTTP errors, failures or scaling and never injects
an actual MySQL error.

## Simulation, API and MCP

Use `POST /api/simulations` (API key or x402) or the matching browser
`POST /api/ui/simulations`, then the normal simulation step/metrics routes.
MCP callers use `simulation.create`, `simulation.step`, `simulation.metrics`.
Full results retain `metrics.mysqlPreparedStatementForecasts`; compact MCP
results preserve `mysqlPreparedStatementForecasts` at the top level.
`POST /api/simulations/stateless` also returns top-level `mysqlPreparedStatementForecasts`.

Supply explicit engine identity and supplemental forecast inputs on each
database's `characteristics`. This example describes assumed inputs, not a
validated topology or measured connection profile:

```json
{
  "databaseEngineIdentity": "mysql",
  "mysqlPreparedStatementForecast": {
    "timeOrigin": "seconds since first workload launch",
    "horizonSeconds": 1200,
    "initialPreparedStatementCount": 100,
    "initialOpenConnections": 10,
    "maxConnections": 100,
    "maxPreparedStatementCount": 10000,
    "provenance": {
      "baseline": "assumed",
      "connections": "assumed",
      "schedule": "planned",
      "source": "Caller-supplied illustrative assumptions; not holdout evidence"
    },
    "schedule": [{
      "startSeconds": 0,
      "stopSeconds": 1200,
      "offeredRps": 100,
      "rampSeconds": 300,
      "currentOpenConnections": 20,
      "rungRps": 100
    }]
  }
}
```

The supplemental schedule is used only for forecasting: it does not replace
the simulator's traffic configuration. It represents the offered exposure
for this database, not accepted/completed HTTP work. Pool budgets are not
open connections. When using a pool-budget assumption, supply that assumption
explicitly and label `connections: "assumed"` with its source.

Engine identity is explicit (`databaseEngineIdentity`, supported exact engine
identity, or an authoritative MySQL service family), never a substring in a
resource name. Generic databases do not qualify merely because they are named
MySQL. Non-AWS MySQL databases execute the same forecast but are extrapolations.

## Results and limits

Each per-database result includes `modelVersion`, `hostedExecution`,
`validationScope`, `provenance`, `missingInputs`, `timeOrigin`,
`horizonSeconds`, `pollEverySeconds`, `trajectory` and `firstCrossing`.
`status` is `crossing`, `no_crossing_within_horizon`, or `unavailable`.
Missing cap, baseline state, schedule, origin, horizon, provenance or open
connection profile is reported explicitly rather than using universal
24,630-cap or 928-statement defaults. Invalid stored legacy inputs also yield
unavailable; invalid new inputs are rejected at intake.

`firstCrossing.elapsedSeconds` is seconds from the supplied origin, not an
engine step index. `elapsedFromRungStartSeconds` is seconds into its explicitly
labeled rung. Without a `rungRps` label, both rung fields are null and this is
only a time-based forecast. Windows are half-open `[startSeconds, stopSeconds)`,
evaluated on a 15-second grid from each window's start. Gaps advance elapsed
time but add no offered requests and have no evaluated polls. A bounded
no-crossing result says nothing about times beyond the finite horizon.
At most 64 windows, 4096 polls and 604800 elapsed seconds are accepted.

`trajectory` and `firstCrossing.evaluatorForecast` preserve exact, unrounded
internal evaluator outputs. The immutable evaluator's historical
`candidateOnly`, `enabledByDefault: false`, and `published: false` flags refer
to its original frozen report; current availability is separately reported
as `hostedExecution: "default_server_side"`. They do not disable execution.

## Validation scope

Given the measured rung start times, CWM predicted the load step in which
MySQL first hits its prepared-statement limit, for this topology, cap and
schedule. The cap and schedule were chosen using earlier development runs.

The independent holdout covers 2× m5.large + db.r5.large, MySQL 8.0,
max_connections 500, max_prepared_stmt_count 24,630. Both repetitions
predicted and first observed 1461 in the 700 RPS rung. Forecasts were 720/645 s
into that rung, versus first-observed 337/359 s: onset minus forecast
−383/−286 s. The cap was hit earlier than forecast; these forecasts were late.
Poll times are not exact continuous onset times. Timing error was descriptive,
not part of the rung verdict. This is not a timing pass, a validation of every
MySQL topology, or a new aggregate accuracy score.

[Pinned results](https://github.com/canvascloudai/cwm-bench/blob/f0e1c2286f6f9b57f34021a5185f70da49e28d6c/typical/dbsat-pscap24630-2x-v1/RESULTS.md)
· [Accuracy evidence](/accuracy#mysql-prepared-statement-trajectory-v3)