Skip to content

Events

OJS defines a standard event vocabulary that enables monitoring, auditing, and reactive automation. Events are emitted by the backend as jobs progress through their lifecycle.

The event format is inspired by CloudEvents, providing a consistent envelope that works across delivery mechanisms (Pub/Sub, LISTEN/NOTIFY, webhooks, WebSocket, gRPC streaming).

Every OJS event follows this structure:

{
"specversion": "1.0",
"id": "evt_01961234-5678-7abc-def0-123456789abc",
"type": "job.completed",
"source": "/ojs/backend/redis",
"time": "2026-02-15T10:30:00Z",
"subject": "01961234-5678-7abc-def0-123456789abc",
"data": {
"job_id": "01961234-5678-7abc-def0-123456789abc",
"job_type": "email.send",
"queue": "default",
"attempt": 1,
"duration_ms": 245
}
}
FieldTypeDescription
specversionstringEvent format version ("1.0")
idstringUnique event identifier
typestringEvent type (dot-namespaced)
sourcestringBackend identifier URI
timestringRFC 3339 timestamp in UTC
subjectstringJob ID this event relates to
dataobjectEvent-specific payload
Event TypeTriggerData Fields
job.enqueuedJob submitted to queuejob_id, job_type, queue, priority
job.startedWorker begins processingjob_id, job_type, queue, attempt, worker_id
job.completedHandler returns successjob_id, job_type, queue, attempt, duration_ms
job.failedHandler returns errorjob_id, job_type, queue, attempt, error, duration_ms
job.retryingJob scheduled for retryjob_id, job_type, queue, attempt, next_attempt_at, delay_ms
job.discardedRetries exhausted, discardedjob_id, job_type, queue, attempt, error
job.cancelledJob cancelled by clientjob_id, job_type, queue, cancelled_by
job.scheduledDelayed job enqueuedjob_id, job_type, queue, scheduled_at
Event TypeTriggerData Fields
worker.registeredWorker connects to backendworker_id, hostname, queues, concurrency
worker.heartbeatPeriodic heartbeatworker_id, active_jobs, state
worker.quietWorker entering quiet modeworker_id
worker.terminatedWorker shutting downworker_id, reason
Event TypeTriggerData Fields
queue.pausedQueue pausedqueue, paused_by
queue.resumedQueue resumedqueue, resumed_by
Event TypeTriggerData Fields
workflow.startedWorkflow beginsworkflow_id, workflow_type, total_steps
workflow.step_completedWorkflow step finishesworkflow_id, step, total_steps
workflow.completedAll steps completeworkflow_id, duration_ms
workflow.failedWorkflow step fails terminallyworkflow_id, step, error
Event TypeTriggerData Fields
cron.triggeredCron schedule firescron_name, job_id, next_at
cron.skippedOverlap policy prevents executioncron_name, reason, next_at

OJS events can be consumed through multiple channels:

MechanismDescriptionUse Case
Redis Pub/SubSubscribe to ojs.events.* channelsReal-time monitoring
PostgreSQL LISTEN/NOTIFYListen on ojs_events channelExisting Postgres infrastructure
NATS subjectsSubscribe to ojs.events.>NATS-native consumers
Kafka topicsConsume from ojs.events topicEvent streaming pipelines
WebSocketConnect to /ojs/v1/events/wsBrowser-based dashboards
WebhooksRegister HTTP callback endpointsExternal system integration
  • Level 0: Implementations MAY emit events.
  • Level 1: Implementations SHOULD emit job lifecycle events (job.enqueued, job.started, job.completed, job.failed).
  • Level 2+: Implementations SHOULD emit scheduling and workflow events.