Redpoint Best Practices Documentation

Use cases: Workflow prioritization

Overview

Workflow prioritization lets you control how many interactions run at the same time and, once that limit is reached, which ones run first. It’s useful whenever unmanaged concurrency causes a problem; either too many workflows hitting the database at once, or overlapping workflows undermining a per-contact rule.

The video below reviews workflow prioritization and walks through how to use the prioritization feature in the Interaction Designer.

This topic includes two example use cases of this feature:

  • Limit to one workflow at a time: enforce a per-contact frequency rule (e.g., no more than one message per person per day). This is best if you run a low volume of workflows daily. Check out the first use case for details.

  • Throttle database load: use workflow prioritization to cap concurrency so a surge (especially right after a maintenance window) doesn't overwhelm the database, and lets critical sends jump the queue. Refer to the second use case to learn more.

The section below explains how the feature works; the two use cases then show it in practice.

Make this part of a Version 7 upgrade. The feature is new in Version 7 and arrives enabled with a default cap of 100. A v7 upgrade is the natural trigger to review whether the environment needs a lower cap; especially high-volume deployments and any with scheduled maintenance windows (Use Case 2). Add a "review the Workflow Prioritization cap" step to the upgrade checklist so it's tuned proactively rather than after a load problem appears.

How it works

In order to use the workflow prioritization feature, you’ll need to set up two parts that work together:

  • Cap the concurrency in Helm (the back end): the environment sets the maximum number of interactions allowed to run at once. This is configured in the deployment's Helm values and is turned on by default with a cap of 100.

  • Set up per-interaction priority (in RPI): for each interaction, use the Prioritization tab on a trigger to set that workflow's priority to Urgent, Normal, or Low (plus queue-time and maintenance overrides).

Priority only matters once the cap is reached. The Prioritization tab is always available, but setting a priority has no visible effect until concurrent activity actually hits the cap set in the back end. With the default cap of 100, an environment running fewer than 100 interactions at once won't see any difference from changing priorities.

Configuring the concurrency cap

Because the feature is turned on by default, you only need to access these settings to change the cap or turn off the feature. The settings live under the executionservice key in your Helm overrides:

YAML
executionservice:
  jobExecution:
    workflowPrioritization:
      enabled: true
      maxConcurrentWorkflowActivities: 1
      maximumQueueTime: "24:00:00"

Setting

Default

What it does

enabled

true

Master switch for queuing/prioritization. On by default; set to false only to disable the feature.

maxConcurrentWorkflowActivities

100

Maximum number of interactions allowed to run at the same time. This is the value that does the real work. Despite "Activities" in the name, it counts whole running interactions, not steps within one.

maximumQueueTime

"24:00:00"

How long an interaction may wait in the queue before it is released regardless of the limit. Raise it if interactions can in your tenant get backed up for longer than a day.

  • You won't find jobExecution/workflowPrioritization in the sample values.yaml, as that file only shows the common options. As per the chart's guidance, you override any setting by placing it under the matching top-level key (executionservice) in your own overrides file, exactly as above. You can browse every available key and its default in the Reference tab of the RPI Helm Assistant.

  • Behind the scenes the chart renders these into environment variables on the ExecutionService pod (RPIExecution__WorkflowPrioritization__Enabled, etc.), which is why there's no appsettings.json to edit; the Helm values are the correct, durable place to set this.

The cap is applied per tenant, not globally across the whole installation. Because these are back-end settings, they are applied by cloud engineering; on a client-hosted deployment, the client's own cloud-engineering team makes the change. After the values are applied (helm upgrade or a GitOps sync), the ExecutionService restarts and the new cap takes effect immediately.

How queuing and priority behave at runtime

  • If the cap is never reached, all triggered interactions simply run concurrently; priority has no effect until the limit is hit.

  • When the cap is reached, a newly triggered interaction is placed in a Queued state instead of running immediately.

  • As running interactions finish, queued ones are released. At equal priority, queued items are released in scheduled-date order (first-come-first-served).

  • Urgent interactions bypass the queue and run immediately, even when the limit is reached; reserve this for genuinely time-critical work.

  • An Urgent Deadline can auto-promote a Normal/Low interaction to Urgent at a set time.

A useful mental model: the cap creates the constraint; priority decides who wins under that constraint. If everything can run at once, priority has nothing to act on.

Use Case 1: Limit execution to one workflow at a time (frequency capping)

When to use it

When you need to enforce a per-contact frequency rule. For example, ensuring no individual receives more than one message per day and overlapping workflows would otherwise undermine it.

Why it works

When multiple workflows fire simultaneously, a frequency or suppression rule can't be reliably enforced: two workflows could each send before either checks the rule. Limiting execution to one interaction at a time means each run completes its validation ("has this person already been messaged today?") before the next begins, so the rule holds.

What to configure

Set maxConcurrentWorkflowActivities: 1 in the Helm chart. In RPI, priorities can be left at the default Normal; serialization itself does the work, and queued items run first-come-first-served.

This use case works for low volume only. Cap = 1 is a suitable approach for low-volume campaigns running within a single day or time window. It doesn’t make sense for large-volume campaign execution. Serializing everything means campaigns back up behind one another and may not finish in time (and can hit the maximumQueueTime release). For higher volume, use a concurrency cap greater than 1 (see Use Case 2) and/or an audience/channel-level contact policy for frequency control.

Monitor the queue. Whenever you use prioritization—a cap of 1 or any lowered cap—monitor queuing to make sure campaigns are still executing in a timely fashion. Watch how much is queued and how long items are waiting, and raise the cap if work is backing up.

Use Case 2: Throttle database load (especially after a maintenance window)

When to use it

When you have a large number of workflows that fire at once and overwhelm the database or RPI server. This is most acute right after a maintenance window: when RPI is paused and then resumed, everything held or scheduled during the window tends to fire at the same time. The same overload occurs in any high-volume environment running hundreds of workflows in a tight window.

Why it works

Lowering the concurrency cap from its default of 100 to a number the environment can sustain lets RPI throttle itself on resume (and in general) instead of running everything simultaneously. Within that cap, priority then lets you:

  • Order the queue so more important workflows run sooner (Normal vs. Low), and let smaller low-priority tasks through rather than blocking them wholesale.

  • Flag mission-critical workflows as Urgent so they bypass the queue entirely (e.g., a purchase or shipping confirmation that must go out regardless of how many campaigns are queued behind it).

What to configure

Lower maxConcurrentWorkflowActivities to a sustainable value in the Helm chart (see Sizing the cap), leave standard campaigns at Normal/Low, and set genuinely time-critical workflows to Urgent. If you are managing around scheduled maintenance, combine this with the Maintenance Mode Buffer settings on the Prioritization tab in RPI, which control how far ahead of a maintenance window activities are placed on the wait queue; the wind-down complement to the cap's throttled ramp-up afterward.

Sizing the cap

There is no universal number. The right cap depends on the environment and its constraints — database capacity, server headroom, and the shape of the surge. Arrive at it iteratively:

  • Observe under the worst case: when coming out of a maintenance window (when the backlog fires at once), watch active database queries and DB/server load as workflows resume.

  • Find the breaking point: identify the level of concurrent activity at which load becomes too much.

  • Reduce the cap: lower maxConcurrentWorkflowActivities so fewer interactions run at once.

  • Re-test and repeat: observe again under the same conditions and adjust until load stays within the environment's limits without starving throughput more than necessary.

The result is tuned to that specific environment; revisit it if the workload profile or infrastructure changes.

Monitor the queue here too. After lowering the cap, keep an eye on queue depth and how long interactions wait, so throttling for load doesn't quietly turn into missed send windows.

Prioritization tab fields

The fields on the Prioritization tab and how they relate to the behavior above:

Field

What it does

Priority (Urgent / Normal / Low; default Normal)

Sets the priority of the workflow's activities. Takes effect once the concurrency cap is reached; Urgent bypasses the queue.

Urgent Deadline

A time at which the workflow's activities are automatically promoted to Urgent priority. Blank by default.

Override Maximum Queue Time + Maximum Queue Time Override

Per-interaction override of how long an activity may wait on the queue before release (system default 1 day, matching the maximumQueueTime setting).

Override Maintenance Mode Buffer + Maintenance Mode Buffer Override

Controls how far ahead of scheduled maintenance activities are placed on the wait queue (default 5 minutes). Useful alongside the concurrency cap when managing maintenance windows (Use Case 2).

The concurrency cap (maxConcurrentWorkflowActivities) that actually enforces the limit is a back-end Helm setting and is not shown on this tab.

Quick reference


Use Case 1 — One at a time

Use Case 2 — Throttle DB load

Goal

Enforce a per-contact frequency / suppression rule

Mitigate DB load (esp. after maintenance) + protect critical sends

maxConcurrentWorkflowActivities

1

A sustainable cap below 100, tuned iteratively per environment

Priority usage

Minimal—leave at Normal; the cap does the work

Order the queue; mark critical work Urgent

Suitable for

Low-volume campaigns in a single day/time window—not large-volume execution

High-volume environments and post-maintenance surges

Additional references

Last updated: