---
title: Recurring Settings
description: Configure recurring job catch-up and registration sync behavior.
order: 36
---

# Recurring Settings

Recurring settings control how DurableStack initializes and maintains recurring schedule definitions over time.

## Key options

- `Recurring.CatchUpPolicy`: missed slot behavior (`SkipMissed` or `CatchUp`).
- `Recurring.RegistrationSync.ExistingJobBehavior`: behavior when code and stored schedule definitions differ.
- `Recurring.RegistrationSync.OrphanedJobBehavior`: behavior when stored recurring definitions are no longer in code.

## Example

```csharp
using DurableStack.Core.Options;

builder.Services.AddDurableStackPostgres(connectionString, options =>
{
    options.Recurring.CatchUpPolicy = RecurringCatchUpPolicy.SkipMissed;
    options.Recurring.RegistrationSync.ExistingJobBehavior = ExistingRecurringJobBehavior.KeepDatabase;
    options.Recurring.RegistrationSync.OrphanedJobBehavior = OrphanedRecurringJobBehavior.Disable;
});
```

## Runtime behavior

- Startup initializer upserts recurring definitions.
- Scheduler computes next due slot per schedule.
- Due slots are materialized into job runs.
- Admin operations can disable/enable/run-now/update cron/time zone.

## Registration sync behavior details

Registration sync runs at startup and reconciles recurring job definitions in code with records already stored in the provider.

### `ExistingJobBehavior`

This option applies when a recurring job exists in both places:

- code definition exists
- database recurring record already exists

Available values:

- `KeepDatabase` (default): keep existing stored cron/time-zone/enabled settings as-is.
- `UpdateFromCode`: overwrite stored recurring definition fields from current code attributes/registration.

When to use:

- Use `KeepDatabase` when runtime/admin-updated schedules should remain source of truth.
- Use `UpdateFromCode` when code should be authoritative for schedule shape at startup.

### `OrphanedJobBehavior`

This option applies when a recurring job exists in the database but no longer exists in code.

Available values:

- `Disable` (default): disable the orphaned recurring record so it no longer materializes runs.
- `Ignore`: leave orphaned recurring records untouched.

When to use:

- Use `Disable` for safer cleanup when jobs are removed or renamed in code.
- Use `Ignore` only when you intentionally manage some recurring definitions outside application code.

## Rename/removal note

Renaming a recurring job name is treated as:

- old job becomes orphaned
- new job is a new definition

With default settings (`KeepDatabase` + `Disable`), the old record is disabled and the new one is created.

## Operational guidance

- Use `SkipMissed` for most production systems to avoid downtime catch-up bursts.
- Keep `ExistingJobBehavior = KeepDatabase` unless code should be authoritative.
- Keep `OrphanedJobBehavior = Disable` for safer cleanup when jobs are removed.
