Skip to content

exec and check get slower per statement as the project grows #1842

Open

Description

@mkrouwel

mxcli: v0.31.0
Mendix: 11.12.4 (small project) and 10.24.11 (large project)

What happens

The time exec and check spend per statement grows roughly in step with the size of the project, not with the size of the statement. The same kind of statement, a create or modify microflow that replaces one retrieve with a call, costs about 0.3 s in a small project and 2–3 s in a project about seven times larger. The fixed cost per run is small in both projects, so almost all of the time is per-statement work.

Measurements

Each run was a separate process, one at a time, with Studio Pro closed and a valid catalog. Each script was first checked with check --references --format json, then executed with exec --force --no-check.

Small project Large project Factor
Size of mprcontents/ 1,121 units, 436 microflows, 24 MB 7,707 units, 3,911 microflows, 165 MB ~7× (units)
check, new microflows (create microflow), per statement 0.04 s (41 in 1.8 s) 0.26–0.39 s (100 in 26–39 s) ~8×
exec, new microflows, per statement 0.10 s (41 in 3.9 s) 0.41–0.47 s (100 in 41–47 s) ~4–5×
check, updates (create or modify microflow), per statement 0.13 s (31 in 4.2 s) 0.8–1.5 s (100 in 82–152 s) ~8–10×
exec, updates, per statement 0.31 s (31 in 9.7 s) 2.1–3.2 s (100 in 206–323 s) ~7–10×
Fixed cost per run check 0.8 s, exec 2–3 s (a script of 5 move statements) about 1–5 s (from the 51- vs 100-statement batches) small

In the small project, durations are measured exactly around each process. In the large project, they come from the start times of consecutive commands, so they include up to about a second of the calling tool's own work.

In the large project, about 850 updates in batches of 100 took 56 minutes in total: 29 minutes of exec and 27 minutes of check. The 851 new microflows took 10 minutes.

Expected

The cost of a statement depends on the statement: the size of the flow it creates or splices and the references it resolves. It should not depend on how many other units the project holds. If some project-wide work is needed, such as loading, indexing or validating references, it should happen once per run, not once per statement.

Notes

  • The two projects also differ in Mendix version (11.12.4 and 10.24.11). I haven't separated that effect from project size.
  • An update with drop + create in the same script costs about the same as a splice.
  • With v0.29, the large project also showed very uneven speeds per module (1 to 5 s per statement) and one unexplained timeout. Those didn't recur with v0.31.

Activity

  1. mkrouwel commented on Nov 12, 2026

    @mkrouwel
    Author

    Controlled follow-up: same machine, same Mendix version (11.12.4) and mxcli v0.31.0, one scratch project grown step by step with filler microflows (6 activities each). At each size the same workload was run: 20 new microflows (create microflow), then 20 updates of existing flows (create or modify microflow, one log text changed, spliced in place). Each script was checked with check --references --format json and executed with exec --force --no-check, one process at a time.

    Project size (20 statements each):

    Units in mprcontents/ check new (s) exec new, per statement check updates (s) exec updates, per statement
    1,335 1.0 0.08 s 1.2 0.23 s
    2,355 1.6 0.09 s 1.8 0.47 s
    3,375 2.4 0.14 s 2.4 0.72 s
    5,395 3.8 0.13 s 4.0 1.33 s

    Batch size (at 5,400–5,800 units):

    Statements check new (s) exec new, per statement check updates (s) exec updates, per statement
    10 3.5 0.20 s 3.5 1.32 s
    25 3.4 0.12 s 3.7 1.25 s
    50 3.6 0.09 s 4.3 1.21 s
    100 3.8 0.09 s 6.2 1.25 s
    200 4.5 0.08 s 7.4 1.35 s

    What this shows:

    • exec of an update (splice of an existing flow) costs time linear in the project size: about +0.27 s per statement per 1,000 extra units, for the same small flow. At ~7,700 units that predicts ~2 s, which matches the 2–3 s in the original report.
    • The cost is per statement: it does not depend on the batch size and does not build up within a run.
    • exec of a new microflow grows only slightly (0.08 → 0.13 s).
    • check mostly has a fixed cost per run that grows with the project (≈ 1 s → 3.5 s); per statement it is small.

    So the part to look at is whatever a splice does per statement that touches the whole project (for example, scanning all units for references, or rewriting an index of all units).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions