Scheduled Jobs API
Jobs schedule exported definitions automatically after application readiness. See the Jobs guide for setup, deployment and troubleshooting, and the contract for behavior rules. This page is the complete field reference.
defineJob
Omitted optional fields can use defaults; invalid explicit values cannot. A disabled definition still requires a valid schedule and handler. Unknown top-level fields are rejected. defineJob() validates and freezes the top-level object, adding an internal recognition marker; plain objects do not substitute for definitions. Nested docs/tags are not deeply frozen.
Handler context
VextJobsConfig
Configure jobs in src/config/default.ts or the selected profile. Application startup validates configuration; discovery and Redis initialization occur before HTTP listening. Normal configuration merge order applies.
Namespace normalization removes leading @, converts slash/backslash to dots, replaces unsupported characters with hyphens, collapses repeated separators and trims edge separators. It permits letters, digits and _ . : -. For example @team/my-app:production:production becomes team.my-app:production:production. Unreadable/invalid package name falls back to vextjs-app; an empty normalized namespace does too. Check for normalization collisions when separate applications share Redis.
The default logical prefix is vext:<namespace>:job:. See multi-replica deployment for actual keys, retained markers and Redis Cluster. Jobs does not borrow Session/cache/rate-limit configuration. Environment URL alone does not activate coordination; configure redis: {} to use it.
Documentation source
openapi.docs.code.jobs: true inherits jobs.dir/include/exclude. Explicit Docs fields override their corresponding defaults; false only disables documentation scanning. Disabled definitions can still be documented. Jobs details show declared schedule, timezone fallback, switches and static parse state, not live runtime status. See Docs and MCP for configuration, JSDoc precedence and static boundaries.
Errors and execution boundaries
VextJobDefinitionError: invalid definition/import, selected file without a defineJob export, or no representable future point.VextJobDuplicateNameError: duplicate loaded names, including disabled definitions.- Invalid configuration or active Cluster without Redis refuses startup; check the field path in the error.
- Configured Redis for active tasks is checked for connection, PING and Lua EVAL during initialization; failure refuses startup.
- Overlap skips; exceptions are logged. No queue, automatic retry, downtime catch-up or immediate startup execution.
- Close waits within the total shutdown.timeout budget and requests cancellation; it cannot interrupt a function that ignores signal.
- Shared healthy Redis coordinates a planned point; it does not guarantee exactly-once business effects.
Testing entry point
Import createTestJobScheduler, CreateTestJobSchedulerOptions and TestJobScheduler from vextjs/testing. Explicit tick(Date) uses the real scheduling rules without timers or project discovery. Ordinary createTestApp does not load Jobs either. See the testing API and acceptance workflow.