RegScale Orchestration Hub

Sizing, scaling, upgrades and operational runbooks for a self-hosted deployment

This guide covers operating the Orchestration Hub after installation: sizing, scaling, upgrading, and resolving common failures. Complete the Orchestration Hub installation guide first.

Audience: platform and infrastructure engineers who own the cluster hosting the Orchestration Hub.

Section
1. Resource sizingCPU and memory settings
2. ScalingWorker replicas, autoscaling, job splitting
3. VersionsWhich version you are running, and compatibility
4. UpgradingProcedure, timings, rollback
5. TroubleshootingDiagnosis and resolution by symptom

1. Resource sizing

1.1 Size the database first

Plan capacity properly. When running a job execution that will synchronize more than 100,000 records from an integration, use the Parallel Job Splitting feature and/or modify the frequency of scheduled jobs to decrease the size of each execution. Increasing workers will not decrease the job's execution time. It may over-saturate the RegScale instance, further increasing duration.

Size the RegScale database for both write throughput and storage. Storage exhaustion affects every user of the RegScale instance, not only Orchestration Hub's jobs.

1.2 Use the chart defaults

The chart's default cli_tasks worker settings are the recommended configuration. No action is required to adopt them:

workers: queues: cli_tasks: resources: limits: {cpu: 4, memory: 4Gi} requests: {cpu: 2, memory: 2Gi}

Limits and requests differ deliberately: the limit is the ceiling a job may reach, and the request is what is reserved for scheduling.

Leave the application tier, the scheduler and the coordinator, priority and celery worker pools at chart defaults. They are not the constraint during ingestion.

1.3 Memory requirements

Worker CPU stays within a 4 core limit. Memory tracks the size of the synchronization, and is lower when a job is split.

Peak worker memory by volume:

Records per syncUn-splitSplit
5,000450 MiB360 MiB
10,000580 MiB420 MiB
20,000690 MiB420 MiB
50,0001,330 MiB810 MiB
100,000did not complete1,270 MiB

To size your own deployment, find your largest routine synchronization in the table, take the figure for the mode you run it in, and add headroom. The chart's 4 GiB limit covers every value in the table, which is why it is the recommended starting point.

1.4 Adjusting the defaults

IfThen
Synchronizations stay at or below 20,000 records1 CPU / 1 GiB is sufficient. Reduce only if cluster capacity requires it; a 690 MiB peak against a 1 GiB limit leaves little margin
Synchronizations exceed 20,000 records, or the workload is mixed or growingKeep the chart defaults
Synchronizations exceed 100,000 recordsKeep the chart defaults and split the job
Workers are terminated during large jobsRaise the memory limit. See 5.1

These conditions raise the figures a deployment can sustain:

ConditionEffect
A faster RegScale database tierLarger single jobs complete, and additional replicas contribute before contention sets in
More database storage and a shorter retention periodMore ingestion before cleanup is required
A connector that transforms rather than forwards dataWorker CPU begins to matter, and a larger CPU limit pays off

Measure your own peak usage before changing the default:

kubectl top pods --namespace regscale -l roh.regscale.com/queue=cli_tasks

2. Scaling

2.1 What replica count controls

Each worker pod runs one job at a time, so the replica count is the number of synchronizations writing to RegScale concurrently. Two replicas is a sensible floor.

Additional replicas do not make an individual synchronization faster. While the database is the constraint, they add contention.

2.2 Queue-depth threshold

Worker autoscaling is driven by job queue depth. Approximately one worker starts per queueLength queued items, up to max:

workers: queues: cli_tasks: queueLength: 4 # about one worker per 4 queued items min: 0 # scales to zero when idle max: 20 gracePeriod: 15300 # 4h15m; drains running jobs before removing a worker

2.3 Splitting a synchronization

Splitting divides one synchronization into independently processed parts. Use it to complete a load a single job cannot, not to make a load faster.

Records per sync
Below 10,000Do not split. Splitting is slower than a single job at this volume
20,000 to 50,000Split on a busy RegScale instance; a lightly loaded one handles this range unsplit
Above 50,000Split
Above 100,000Always split. Unsplit synchronizations do not complete at this size

3. Versions

3.1 Two version numbers

VersionIdentifies
Chart versionThe chart packaging
appVersionThe Orchestration Hub release the chart deploys

List both before upgrading:

helm repo update helm search repo regscale/regscale-orchestration-hub --versions

3.2 Chart and application version coupling

image.tag defaults to empty and resolves to the chart's appVersion, so upgrading the chart upgrades the application. There is no second version to set.

Setting image.tag explicitly overrides this. The pinned tag persists across later chart upgrades and will hold the application back, so clear it once a chart carrying the fix is available.

The web interface is built into the application image. There is no separate interface version.

3.3 Compatibility with RegScale

The Orchestration Hub delegates authentication to the core RegScale application and calls its API to read and write records, so the two are coupled at runtime. Follow these practices to keep them aligned:

  1. Keep RegScale at or above the version current when your Orchestration Hub release was published.
  2. Upgrade RegScale first, then the Orchestration Hub.
  3. Run one small job end to end afterwards.

3.4 Check what is deployed

curl -fsS https://roh.example.com/api/v1/version
{ "name": "RegScale Orchestration Hub", "version": "6.33.0.0", "commit": "...", "frontend_version": "..." }

version must match the APP VERSION of the chart release you deployed. If it does not, either the rollout has not finished or image.tag is pinned.

helm list --namespace regscale helm history roh --namespace regscale

4. Upgrading

No outage window is required. No component that serves users goes offline during an upgrade.

4.1 Before you start

Take a database backup or snapshot, and confirm it completed. This is your rollback mechanism. See 4.4.

Then:

4.2 Upgrade

helm repo update helm upgrade roh regscale/regscale-orchestration-hub \ --namespace regscale \ -f my-values.yaml \ --timeout 30m

Set --timeout 30m. Helm's 5 minute default applies to the schema migration, which is allowed 30 minutes. A migration taking longer than 5 minutes will report a timeout on an upgrade that is succeeding.

Do not use --atomic. It rolls the release back on failure or timeout. The migration has already committed by that point, and an automatic rollback produces the failure in 4.4.

If the command reports a timeout, check the migration before concluding it failed:

kubectl get jobs --namespace regscale kubectl logs --namespace regscale job/<migration-job-name>

4.3 Component availability during upgrade

The schema migration runs first, as a pre-upgrade hook. The upgrade does not proceed unless it succeeds. Workloads then roll:

ComponentInterruptionNotes
Application (API and interface)NoneA replacement replica passes its readiness probe before a current one is removed
cli_tasks and coordinator workersNoneRunning jobs finish. Each is allowed 4h15m to drain
priority and celery workersNone2 minute drain
SchedulerBrief pause in job dispatchReplaced rather than rolled, because two schedulers would dispatch every job twice. Scheduled jobs start late; they are not skipped or duplicated
Migration jobNot user-facing30 minute limit

With --wait, the command also waits for the worker drain, which can extend it by up to 4h15m. Upgrade when the job queue is quiet if you need it to finish promptly.

4.4 Rolling back

Rolling back requires restoring the database as well as reverting the chart. helm rollback reverts the Kubernetes objects only. Where the upgrade applied a schema migration, the database is then ahead of the restored image and the pods do not start, reporting Can't locate revision identified by <revision>.

To roll back:

  1. Scale the Orchestration Hub deployments to zero, or uninstall the release.
  2. Restore the database to the pre-upgrade snapshot.
  3. helm rollback to the previous revision.

Restore the database and revert the chart together. Doing either alone leaves them out of step.

A rollback without a database restore is safe only if the upgrade applied no migration. If you cannot confirm that, restore the database.

Prefer rolling forward. Where the goal is to fix a problem rather than return to a specific version, a later release avoids the database restore entirely.

4.5 After upgrading

4.6 Multiple versions

Upgrade one minor chart version at a time. A single large jump applies every accumulated migration in one 30 minute window, with nothing to fall back to except the database snapshot.

5. Troubleshooting

Resource names carry the Helm release name, so these commands select by label. Substitute your namespace for regscale.

kubectl get pods --namespace regscale -l app.kubernetes.io/name=regscale-orchestration-hub kubectl get pods --namespace regscale -l app.kubernetes.io/component=worker kubectl get pods --namespace regscale -l roh.regscale.com/queue=cli_tasks kubectl get scaledobjects --namespace regscale kubectl logs --namespace regscale -l app.kubernetes.io/component=app --tail=200

Check the RESTARTS column first when a job has failed with no apparent error. A worker that restarted during a job did not complete it.

5.1 Worker pod restarts during a job

Cause. The worker exceeded its memory limit and was terminated.

Confirm it. Check the pod directly; the Orchestration Hub job record does not reflect a kernel termination:

kubectl describe pod --namespace regscale <pod-name> | grep -A5 "Last State"

Reason: OOMKilled with Exit Code: 137 confirms it.

Fix. Raise the memory limit for the affected queue:

workers: queues: cli_tasks: resources: limits: {cpu: 4, memory: 8Gi} requests: {cpu: 2, memory: 2Gi}

Splitting the job is the alternative, and reduces peak memory per worker.

Raise the limit before re-running. Interrupted parts are re-dispatched a limited number of times. Parts that exhaust those attempts do not recover when the parent job is re-run.

5.2 Workers do not scale up

Cause. The autoscaling threshold, not the replica maximum, governs how many workers start.

Confirm.

kubectl get pods --namespace keda kubectl get scaledobjects --namespace regscale kubectl describe scaledobject --namespace regscale <name>

KEDA must be installed, and READY and ACTIVE should both be True for a queue with work waiting.

Fix. Lower queueLength, per 2.2. Raising max alone will not change the behavior. Confirm the database can absorb the added concurrency first.

5.3 Reported success with missing records

Cause. A split job's status reflects the parent job's completion. Individual parts can fail independently.

Confirm. Compare the record count in RegScale against the source system, then check the per-part results in the job's execution.

Fix. Re-run with fewer, larger parts. Verify the record count after any synchronization that matters.

5.4 Large jobs fail while smaller ones succeed

Cause. RegScale's database applies a time limit to a single write transaction. The threshold depends on database load, so the same job size can succeed on a quiet database and fail on a busy one.

Confirm. The job runs for several minutes, then fails against the write to RegScale rather than the read from the source. Smaller synchronizations of the same type succeed.

Fix. Keep a single unsplit synchronization to approximately 20,000 records on a busy RegScale instance, and split above that.

5.5 Long-running job restarts repeatedly

Cause. A single task that runs beyond approximately 90 minutes is recycled and restarted, so a synchronization that cannot finish inside that window restarts indefinitely and cannot complete as a single unit. Additional CPU or memory does not extend the window.

Confirm. The job's start time moves at roughly 90 minute intervals while the worker shows no memory pressure and the database shows no strain.

Fix. Split the job so each part completes inside the window. Increasing worker resources does not help.

5.6 Users cannot log in, or the environment is unresponsive

The cause is usually an Orchestration Hub job consuming the shared database's storage.

Cause. The RegScale database has reached its storage limit. Logins fail and API calls time out for every user of the instance. The Orchestration Hub shares this database with RegScale, so sustained ingestion consumes storage RegScale depends on.

Confirm. Check consumed size against the configured maximum using your database platform's tooling. Do not diagnose from application logs; a log buffer can retain storage errors from an earlier incident.

Fix. Raise the storage allocation first, then reduce consumption. A database at its limit can be too full to delete from.

Prevent.

5.7 Stopping a job overloading the database

Cancel it through the Orchestration Hub, in the interface or the API:

curl -fsS -X POST https://roh.example.com/api/v1/executions/<execution-id>/cancel \ -H "Authorization: Bearer <token>"

Canceling a split job also cancels its parts. Deleting the job cancels any running execution.

Then confirm database write activity has stopped. Cancellation is not instantaneous; work already submitted continues until those transactions complete, which can take minutes on a large job. Watch database activity rather than the job's status.

Do not delete worker pods to stop a job. Terminated work is re-dispatched, so this restarts the work rather than ending it, and risks the permanent part loss in 5.1.

5.8 Job appears stuck with no progress

Cause. An execution was left running after an interruption, such as a worker being replaced mid-job.

Fix. The Orchestration Hub reconciles stuck executions hourly, resolving those running more than four hours or pending more than one. To act sooner, cancel the execution per 5.7 and re-run it.

Before re-running, rule out the two causes that will otherwise recur: worker memory (5.1) and the 90 minute task window (5.5).