---
title: "Schedule Java pipelines"
description: "Create cron, interval and one-time schedules, then inspect, pause, trigger and archive them with typed APIs."
category: "Java SDK"
---

Schedules are durable server definitions. Create one from a producer, then let any compatible worker execute its pipelines. A Java process does not need to stay alive merely to keep the schedule registered.

The [Java demo](/downloads/pipelogiq-java-demo.zip) includes `ScheduleExample.java`. Build it as described in [getting started](/docs/java/getting-started), export the API settings in each terminal, and keep `OrdersExample` or `WorkflowExample worker` running.

## Create a cron schedule

The typed API uses the same stages as an ordinary pipeline:

```java
import io.pipelogiq.sdk.Pipelogiq;
import io.pipelogiq.sdk.core.client.CatchupPolicy;
import io.pipelogiq.sdk.core.client.OverlapPolicy;
import java.math.BigDecimal;

// Inside a method using the getting-started Order and stage classes:
try (var client = Pipelogiq.connect("pipelogiq.yml")) {
  var schedule = client.schedule("weekday-orders")
      .cron("0 9 * * 1-5", "Europe/Tallinn")
      .overlapPolicy(OverlapPolicy.SKIP)
      .catchup(CatchupPolicy.ONE)
      .label("service", "orders")
      .stage(ValidateOrder.class, new Order("scheduled", new BigDecimal("10.00")))
      .stage(RecordOrder.class)
      .apply();
  System.out.println(schedule.name() + ": " + schedule.nextRunAt());
}
```

This runs at 09:00 on weekdays in `Europe/Tallinn`. Cron uses **five fields**: minute, hour, day of month, month, day of week. It is not Quartz's six-field syntax with seconds. The server interprets the IANA time zone and daylight-saving transitions. `.cron(expression)` defaults to UTC.

Equivalent CLI:

```sh
java -cp 'target/classes:target/dependency/*' example.ScheduleExample cron demo-weekdays '0 9 * * 1-5' Europe/Tallinn
```

Creation prints the schedule's status, kind and next run time. `apply()` upserts an application-scoped, case-insensitive name. Reapplying an unchanged definition preserves its cursor and definition version; use distinct names for separate schedules.

## Use an interval or one-time execution

Replace the timing method in the same draft with one of these alternatives:

```java
.every(java.time.Duration.ofMinutes(10))
```

```java
.runOnceAt(java.time.Instant.now().plusSeconds(60))
```

Intervals use whole seconds and must be at least 10 seconds. One-time schedules use an absolute instant and become archived after firing. The CLI accepts a relative delay for convenience:

```sh
java -cp 'target/classes:target/dependency/*' example.ScheduleExample interval demo-interval 60
java -cp 'target/classes:target/dependency/*' example.ScheduleExample once demo-once 60
```

Each scheduled tick creates a new pipeline. The recurring example's order payload remains the same template each time; real recurring business logic should derive its processing window or business identity from the intended job, not assume every tick receives a new order ID.

## Choose execution policies

| Setting | Choices and purpose |
| --- | --- |
| `.overlapPolicy(...)` | `SKIP`, `QUEUE`, `REPLACE`, `ALLOW`; server policy when previous work is in flight |
| `.catchup(...)` | `NONE`, `ONE`, `ALL`; server policy for missed schedule times |
| `.catchup(CatchupPolicy.ALL, max)` | Bound catch-up generation; `max` is 1–1000 |
| `.jitter(Duration)` | Whole-second dispatch jitter, from zero to one hour |

The example explicitly selects `SKIP` and `ONE`. These policies affect durable scheduling; they do not increase worker concurrency or change a stage's retry rules. Test catch-up, overlap and time-zone behavior against your server deployment before relying on them for business windows.

Stored definitions contain stages, labels and context. Request credentials and one-off request identity are not part of the reusable schedule definition.

## Inspect and operate a schedule

```sh
java -cp 'target/classes:target/dependency/*' example.ScheduleExample list
java -cp 'target/classes:target/dependency/*' example.ScheduleExample get demo-weekdays
java -cp 'target/classes:target/dependency/*' example.ScheduleExample pause demo-weekdays
java -cp 'target/classes:target/dependency/*' example.ScheduleExample trigger demo-weekdays
java -cp 'target/classes:target/dependency/*' example.ScheduleExample history demo-weekdays
java -cp 'target/classes:target/dependency/*' example.ScheduleExample resume demo-weekdays
```

`trigger` prints a pipeline ID. Observe that execution with `CreatePipelineExample wait <id> 60`. Manual triggering does not advance the regular schedule cursor. An optional typed input override replaces the first stage's input for that manual run:

```java
try (var client = Pipelogiq.connect("pipelogiq.yml")) {
  var run = client.schedules().trigger("weekday-orders",
      new Order("manual-001", new BigDecimal("20.00")));
  System.out.println(run.pipelineId());
}
```

This fragment uses the imports and `Order` class from the cron example. `get` exposes status, timing, definition version, health and last/next run information. `history` returns run outcomes and linked pipeline IDs, which can still be running when queried.

## Read paginated history

The CLI prints the first page and its next cursor. To consume all pages, use the typed response:

```java
try (var client = Pipelogiq.connect("pipelogiq.yml")) {
  String cursor = null;
  do {
    var page = client.schedules().history("weekday-orders", cursor, 50);
    for (var run : page.runs()) {
      System.out.println(run.id() + " -> " + run.pipelineId() + " / " + run.pipelineStatus());
    }
    cursor = page.hasNext() ? page.nextCursor() : null;
  } while (cursor != null);
}
```

`client.schedules().list(status, cursor, limit)` provides equivalent pagination for definitions. `list()` and `list(ScheduleStatus.ACTIVE)` cover the common first-page cases without optional arguments. Named asynchronous variants are available for management operations.

## Clean up the example schedules

Recurring schedules continue until paused or archived. Archive both recurring examples when finished:

```sh
java -cp 'target/classes:target/dependency/*' example.ScheduleExample archive demo-weekdays
java -cp 'target/classes:target/dependency/*' example.ScheduleExample archive demo-interval
java -cp 'target/classes:target/dependency/*' example.ScheduleExample get demo-once
```

Archive the one-time schedule too if it has not fired and you want to cancel its future tick. Archiving retains the definition and history; it does not cancel already-created pipelines. Use `client.pipelines().cancel(id)` for those.
