Skip to content
Back to skills

Scheduled Events And Queues

ASecurity

Scheduled events (Mendix's cron) and task queues in MDL — the eight repeat variants and the fields each takes, and what a queue does and does not throttle. Use when running a microflow on a schedule, or bounding how many background tasks run at once.

  • 128 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 26, 2026
ai-agentsgojavabashsqlnodeexpressapidocumentation

Works with

  • cli
  • api

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add mendixlabs/mxcli --skill scheduled-events-and-queues --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Scheduled Events And Queues?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Scheduled Events And Queues
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mendixlabs-scheduled-events-and-queues/badge)](https://www.skillsdirectory.com/skills/mendixlabs-scheduled-events-and-queues)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: scheduled-events-and-queues
description: "Scheduled events (Mendix's cron) and task queues in MDL — the eight repeat variants and the fields each takes, and what a queue does and does not throttle. Use when running a microflow on a schedule, or bounding how many background tasks run at once."
---

# Scheduled Events and Task Queues

## When to Use This Skill

Use this skill when the user wants to:
- Run a microflow on a schedule ("every night at 4", "hourly", "cron", "batch job")
- Inspect or change an existing scheduled event
- Limit how many background tasks run at once (a task queue)
- Run a microflow or Java action call on a queue (`IN QUEUE`)

**These two features are unrelated.** A scheduled event does **not** go through a
task queue. Its own concurrency control is `OnOverlap`.

## Scheduled Events

Mendix's cron: run a microflow on a repeating schedule.

```sql
mdl 1;
-- Inspect
list scheduled events;
list scheduled events in Ops;
describe scheduled event Ops.NightlyCleanup;   -- re-executable MDL

-- Create
create scheduled event Ops.NightlyCleanup (
  Microflow: Ops.SE_Cleanup,
  Repeat: Daily,
  HourOfDay: 4,
  MinuteOfHour: 0,
  TimeZone: Server,
  Enabled: true
);

drop scheduled event Ops.NightlyCleanup;
```

`Microflow` and `Repeat` are **always required**. `show` is a synonym for `list`.

### Pick the Repeat first, then use only its fields

Mendix stores the repeat rule as one of eight types, and they differ in **which
fields they carry** — not just in their values. Naming a field from another
repeat is an error, not a no-op:

```
Error: Repeat Daily does not have Multiplier — it takes HourOfDay, MinuteOfHour
```

| Repeat | Fields | Means |
|--------|--------|-------|
| `Minutely` | `Multiplier` | every N minutes |
| `Hourly` | `Multiplier`, `MinuteOffset` | every N hours, at :MM past |
| `Daily` | `HourOfDay`, `MinuteOfHour` | every day at HH:MM (**no multiplier**) |
| `Weekly` | `Weekdays`, `HourOfDay`, `MinuteOfHour` | on the named days at HH:MM |
| `MonthlyByDate` | `Multiplier`, `MonthOffset`, `DayOfMonth`, `HourOfDay`, `MinuteOfHour` | the Dth of every N months |
| `MonthlyByWeekday` | `Multiplier`, `MonthOffset`, `DaySelector`, `Weekday`, `HourOfDay`, `MinuteOfHour` | the last Friday of every N months |
| `YearlyByDate` | `Month`, `DayOfMonth`, `HourOfDay`, `MinuteOfHour` | every 2 January |
| `YearlyByWeekday` | `Month`, `DaySelector`, `Weekday`, `HourOfDay`, `MinuteOfHour` | the first Monday of March |

Field values:

| Field | Value |
|-------|-------|
| `Multiplier` | 1 or more (defaults to 1) |
| `MinuteOffset` | 0–59 |
| `MonthOffset` | 0-based: which month of a multi-month cycle fires |
| `HourOfDay` / `MinuteOfHour` | 0–23 / 0–59 |
| `DayOfMonth` / `Month` | 1–31 / 1–12 |
| `Weekdays` | quoted list: `'Monday, Friday'` (case-insensitive) |
| `DaySelector` | `First`, `Second`, `Third`, `Fourth`, `Last` |
| `Weekday` | `Sunday` … `Saturday` |

Optional on any repeat:

| Property | Values | Default |
|----------|--------|---------|
| `Enabled` | `true` / `false` | `false` — **a new event does not run until you enable it** |
| `OnOverlap` | `DelayNext` / `SkipNext` | `DelayNext` |
| `TimeZone` | `UTC` / `Server` | `UTC` |
| `StartDateTime` | RFC 3339, e.g. `'2026-01-01T04:00:00Z'` | none |
| `Documentation` | free text | none |

`SkipNext` drops a run that would overlap the previous one; `DelayNext` waits.

### More examples

```sql
mdl 1;
-- Every two hours, 23 minutes past
create scheduled event Ops.HourlyPing (
  Microflow: Ops.SE_Ping,
  Repeat: Hourly,
  Multiplier: 2,
  MinuteOffset: 23
);

-- Mondays and Fridays at 09:30
create scheduled event Ops.WeeklyReport (
  Microflow: Ops.SE_Report,
  Repeat: Weekly,
  Weekdays: 'Monday, Friday',
  HourOfDay: 9,
  MinuteOfHour: 30
);

-- The last Friday of every third month, 18:00
create scheduled event Ops.QuarterEnd (
  Microflow: Ops.SE_Close,
  Repeat: MonthlyByWeekday,
  Multiplier: 3,
  MonthOffset: 2,
  DaySelector: Last,
  Weekday: Friday,
  HourOfDay: 18
);
```

## Task Queues

A task queue bounds how many queued calls run at once. Binding a call to it
is a separate step — see [`IN QUEUE`](#binding-a-call-to-a-queue--in-queue).

```sql
mdl 1;
list task queues;
describe task queue Ops.OrderProcessing;

create task queue Ops.OrderProcessing ( Parallelism: 3, ClusterWide: true );
create task queue Ops.Mail;                     -- defaults: parallelism 1, per-instance

create or modify task queue Ops.OrderProcessing ( Parallelism: '$MyModule.Workers' );
drop task queue Ops.Mail;
```

| Property | Meaning | Default |
|----------|---------|---------|
| `Parallelism` | how many run at once — an **expression**, not a number | `1` |
| `ClusterWide` | `true` = across the cluster, `false` = per runtime instance | `false` |

Mendix stores parallelism as an expression string, so `3` and `'3'` are the same
thing and an arbitrary expression is legal.

## Common Mistakes

| Mistake | Symptom | Fix |
|---------|---------|-----|
| `Multiplier` on a `Daily` repeat | `Repeat Daily does not have Multiplier` | Daily has no multiplier — use `HourOfDay`/`MinuteOfHour`, or switch to `Hourly` |
| Forgetting `Enabled: true` | The event is in the model but never runs | Set `Enabled: true` (the default is false) |
| `TimeZone: server` | `has the wrong casing — Mendix stores it as "Server"` | Use the exact spelling: `Server`, `UTC`, `DelayNext`, `SkipNext`, `Last`, `Friday` |
| `HourOfDay: 24` | `it must be between 0 and 23` | Hours are 0–23; midnight is `0` |
| Expecting a queue to throttle a scheduled event | Nothing changes | They are unrelated — use `OnOverlap` |

## Binding a Call to a Queue — `IN QUEUE`

The queue document only *defines* the concurrency limit. What actually runs work
in the background is the binding on the **call activity**, and Mendix allows it
on exactly two: *Call microflow* and *Call Java action*. In MDL that is a
trailing `in queue` clause, in the same position on both — after the argument
list, before any `on error`:

```sql
mdl 1;
create or modify microflow Ops.ACT_Enqueue ()
begin
  call microflow Ops.ACT_Process(Order = $Order) in queue Ops.OrderProcessing;
  call java action Ops.RefreshData(Url = $Url)   in queue Ops.OrderProcessing;
end;
```

`describe microflow` renders the clause back, so the binding round-trips.

### Three traps, verified on mxbuild 11.13.0 (the microflow one on 11.12.0)

**A queued microflow must return nothing.** A `call microflow … in queue …` whose
target declares `returns …` fails the build with **CE7033** *"A microflow used for
background execution must have a Microflow return type of 'Nothing'."*, reported at
the call activity. `mxcli check` reports it as **MDL088** — without a project when
the script creates the microflow, and under `--references` for one already stored.
Drop the `returns` clause (and the `return` value) from the worker microflow:

```sql
mdl 1;
create microflow Ops.ACT_Work ($Note: String)   -- no `returns`
begin
  log info node 'Ops' 'working';
end;
```

**A queued Java action must return Nothing.** Anything else fails the build with
**CE7038** *"A Java action used for background execution must have a return type
of 'Nothing'."* mxcli's default return type for `create java action` is
**Boolean**, so `returns void` is required, not optional:

```sql
mdl 1;
create java action Ops.RefreshData(Url: string not null) returns void
as $$ return; $$;
```

**The queue must exist.** A missing one is **CE1613** *"The selected task queue
… no longer exists"*, reported against the **call activity** — it names the
activity, not the script, so a typo is expensive to trace from the build log.
`mxcli check --references` resolves the name first and reports it against the
statement instead.

That CE1613 is also the proof the binding is real: drop the queue on a project
mxcli wrote and the error appears, naming both the queue and the activity.

### A Rewrite Must Restate the Queue

`create or modify microflow` rebuilds the microflow from the statement,
so a binding the script does not restate is gone. mxcli refuses rather than drop
it:

```
Error: microflow Ops.ACT_Caller has 1 call(s) bound to a task queue that this
script does not restate (Ops.MyQueue), and rewriting it would silently drop the
binding.
```

Add `in queue Ops.MyQueue` to the call and the rewrite goes through. Without the
refusal the binding was written back as null and the project then looked
*healthier* than before — `mx check` stopped reporting CE1613, because the
configuration the error was about had been deleted.

One thing is still refused: a **retry policy** on a queued call
(`Queues$QueueFixedRetry` / `Queues$QueueExponentialRetry`). MDL has no syntax
for it, so a rewrite cannot preserve it — change that microflow in Studio Pro.

### When a Java Action Is the Better Tool

The activity property gives queueing and nothing else. The runtime API, reachable
from a Java action, gives queueing *and* retry, and can queue a Java action
directly with no wrapper microflow:

```java
Core.userActionCall("Ops.RefreshData")
    .withParams(url)
    .withExponentialRetry(5, Duration.ofSeconds(2), Duration.ofMinutes(2))
    .executeInBackground(ctx, "Ops.OrderProcessing");
```

Use `Core.microflowCall(...)` when the unit of work really is a microflow.

## Placing Them in Folders

Both take a `folder` clause on `create`, straight after the qualified name:

```mdl
mdl 1;
create scheduled event Ops.SE_Nightly folder 'Private/Scheduled events'
  ( Microflow: Ops.ACT_Nightly, Repeat: Daily, StartDateTime: '2026-01-01T02:00:00Z' );

create task queue Ops.Q_Imports folder 'Private/Queues' ( Parallelism: 3 );
```

On `create or modify` the clause moves an existing document; omitting it leaves
placement alone. See `organize-project`.

## Validation Checklist

Before presenting a script:

```bash
mxcli check script.mdl                       # catches wrong-repeat fields (MDL-SCHED01)
mxcli check script.mdl -p app.mpr --references
```

- [ ] Every scheduled event has `Microflow` and `Repeat`
- [ ] Only that repeat's fields are used
- [ ] `Enabled: true` if it is meant to run
- [ ] Enum values spelled exactly (`Server`, `DelayNext`, `Last`, `Monday`)
- [ ] The target microflow exists and takes no parameters

## Querying and Linting

Both document types are in the catalog after `refresh catalog`:

```sql
-- Anything that fires more often than once a minute
select QualifiedName, RepeatDescription, Microflow
from CATALOG.SCHEDULED_EVENTS
where Enabled = 1 and IntervalSeconds < 60;

select QualifiedName, Parallelism, ClusterWide from CATALOG.QUEUES;
```

A scheduled event counts as a caller of the microflow it runs, so
`list callers of Ops.SE_Cleanup` lists it and the lint rule for orphaned
microflows (QUAL004) does not flag it. `IntervalSeconds` is derived from the
schedule, not from the legacy `Interval`/`IntervalType` pair Mendix also stores.

Starlark lint rules can iterate both: `scheduled_events()` yields
`repeat`, `interval_seconds`, `on_overlap`, `time_zone`, `enabled`, and
`microflow_name`; `queues()` yields `parallelism` (a string) and `cluster_wide`.

## Related

- `mxcli syntax scheduled-event`, `mxcli syntax queue` — full syntax reference
- `write-microflows` — writing the microflow the event calls
- `project-settings` — after-startup / before-shutdown microflows

## Scheduled events — Mendix's cron (LIST/DESCRIBE/CREATE [OR MODIFY]/DROP). `Repeat:` names one of the eight `ScheduledEvents$*Schedule` variants and only that variant's fields are accepted; a field from another repeat is refused by `mxcli check` (MDL-SCHED01) and by exec, which call the same function. The document shape is pinned by re-serializing three whole Studio Pro-authored events (Workflow Commons 4.11.0, OIDC SSO 4.6.0, SAML 4.2.1) element by element — `modelsdk/gen` is **wrong** about two properties here

the integers are stored as int64 (gen says int32, the #585 mismatch) and `StartDateTime` is a BSON datetime (gen says string), so both engines share one raw-BSON codec in `mdl/scheduledevents`. `Interval`/`IntervalType` are legacy siblings of `Schedule` that Studio Pro writes and does not keep in sync — derived on CREATE, carried through untouched on MODIFY. Only the Day and Hour variants have a Studio Pro reference; the other six are metamodel-derived and verified to load. Both are in the catalog (`CATALOG.SCHEDULED_EVENTS`, `CATALOG.QUEUES`) and a scheduled event emits a `schedule` edge into `CATALOG.REFS` — without it a microflow run only by a scheduled event was reported as dead by `list callers`, `GRAPH_DEAD_ASSETS` and lint rule QUAL004.

## Task queues (LIST/DESCRIBE/CREATE [OR MODIFY]/DROP TASK QUEUE). `Config.ParallelismExpression` is a **string** and the sibling int32 `Parallelism` is not written — matching all four Studio Pro queues in Business Events 3.12.1. Binding a *call* to a queue is not yet authorable, so `CREATE OR REPLACE|MODIFY MICROFLOW` is **refused** when the stored microflow has a queued call (guard-don't-drop, ADR-0005)

the rebuild used to write `QueueSettings` back as null, which made `mx check` go from CE1613 to 0 errors by deleting the user's configuration

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…