Skip to main content
Standard / StatefulCronServerless
Allow multiple containers
Scale to Zero
Must expose one HTTP port
Allow no exposed ports
Allow multiple exposed ports
Unable to expose any ports
Custom Domain requests have the HOST header of the custom domain
Fast switching update between versions
Rolling update between versions
Autoscale by CPU
Autoscale by requests per second
Autoscale by concurrent requests
Autoscale by request latency
Runs on a schedule and is expected to complete
Readiness/liveness probes default to TCP check of container port
Readiness/liveness probes default to disabled

Standard

Standard workloads have greater flexibility in network exposure, but may not scale to zero. Standard workloads may:
  • Expose no network endpoint.
  • Serve traffic on multiple ports.
Standard workloads may not:
  • Scale to zero.

Stateful

Stateful workloads provide stable replica identities and persistent storage, making them ideal for databases, message queues, and other applications that require durable state. Each replica maintains a consistent identity across restarts and can be addressed individually. Stateful workloads may:
  • Expose no network endpoint.
  • Serve traffic on multiple ports.
  • Mount volume sets for persistent storage.
Stateful workloads may not:

Overview

Stateful workloads are similar to standard and serverless workloads in many ways. Much of the base functionality, including Universal Cloud Identity, metrics, logs, audit trail, etc. remains the same.

Replica-Direct Endpoints

By default, stateful workloads (like other types) receive load-balanced endpoints. To enable one endpoint per replica, set spec.loadBalancer.replicaDirect to true. Enable this when clients need to target a specific replica directly—for example, connecting to a particular database node or routing requests to a designated leader in a clustered application. Click here to see the endpoint format.

Capacity AI

Stateful workloads do not support Capacity AI. To optimize costs specify minCpu and minMemory

Autoscaling

Stateful workloads do not support concurrency-based horizontal autoscaling.

Cost Optimization

To reduce costs when using a stateful workload, set minCpu and minMemory to a low value. These values are used to reserve resources on Control Plane. In Kubernetes parlance, these values are the resource requests. Control Plane bills based on reserved resources, so lower minimum values directly reduce your costs when actual usage is below the maximum.

minCpu

  • minCpu and cpu can be at most 4000m apart
  • The ratio between minCpu and cpu must be at least 1:4

minMemory

  • minMemory and memory can be at most 4096Mi apart
  • The ratio between minMemory and memory must be at least 1:4

Key Features

Stable Replica Identities

Each replica has a permanent identity. If a replica is rescheduled, restarted, or recreated for any reason, its identity will remain constant. Identities are of the form - e.g. for a workload called my-workload, the replica identities would be:
  • my-workload-0
  • my-workload-1
  • etc.

Stable Local Hostnames

Each replica has a hostname corresponding to its identity. Hostnames are of the form {replicaIdentity}.{workloadName} e.g. for a workload called my-workload, the replica hostnames would be:
  • my-workload-0.my-workload
  • my-workload-1.my-workload
  • etc.
These hostnames are only accessible within the same location. They cannot be exposed publicly or accessed from other locations. To enable cross-location and public access to individual replicas, set spec.loadBalancer.replicaDirect to true (see Replica-Direct Endpoints). To make an HTTP request to a specific replica within the same location: curl http://my-workload-1.my-workload:8080 from another workload running on Control Plane

Persistent Storage

Stateful workloads can mount a volume set as a volume in one or more of its containers. To do this, simply add a volume to a container’s list of volumes of the form:
YAML
uri: cpln://volumeset/my-volume-set
path: /some/mount/directory

Considerations When Using Persistent Storage

  • Volume sets are GVC scoped.
  • A workload can only use volume sets in the same GVC.
  • A volume set can be used by at most one workload, unless you use the shared file system type, which provisions a single volume per location that multiple workloads can access simultaneously.
  • A workload may use any number of volume sets.
  • The volume set uri must begin with cpln://volumeset/.

Examples

PostgreSQL

This example demonstrates how to run a simple postgresql instance on Control Plane.

NATS

This example demonstrates how to run NATS on Control Plane.

Minimal Example

YAML
kind: workload
name: my-database
spec:
  type: stateful
  containers:
    - name: db
      image: postgres:16
      cpu: "1"
      minCpu: "250m"
      memory: 1Gi
      minMemory: 256Mi
      ports:
        - number: 5432
          protocol: tcp
      volumes:
        - uri: cpln://volumeset/my-data
          path: /var/lib/postgresql/data
  defaultOptions:
    autoscaling:
      minScale: 1
      maxScale: 3
  loadBalancer:
    replicaDirect: true

Cron

Cron workloads should be used when you need to perform a background task on a regular schedule. Cron workloads may not:
  • Serve traffic.
  • Scale to zero.
  • Include a container that runs indefinitely.
Cron workloads must:
  • Exit upon completion of the task at hand. Control Plane will start a new replica of your workload at the next scheduled execution time.

Cron Configuration

Cron workloads are always deployed to all locations within their GVC. Unlike workloads of other types, there is no way to provide location-specific configuration overrides.
  • job.schedule
  • job.concurrencyPolicy
    • This determines what Control Plane will do when a prior execution of your workload is still running when the next scheduled execution time arrives.
      • Forbid: subsequent executions will be forgone until the running execution completes.
      • Replace: the running execution will be stopped so that a new execution can begin.
      • Allow: subsequent executions will be allowed to proceed as normal.
  • job.historyLimit
    • An integer between 1 and 10 representing the number of prior executions to be retained for reference.
  • job.restartPolicy
    • Either Never or OnFailure. This determines whether your workload will be restarted when it fails on execution.
  • job.activeDeadlineSeconds
    • Optional: By default there is no deadline. Job executions are allowed to run indefinitely.
    • If this property is set, this is the maximum number of a seconds a job execution can run. If the job does not exit in the allotted time, Control Plane will remove it.

Run Now

Cron workloads can be run on-demand even when they are suspended.
When running a cron workload on-demand the job.concurrencyPolicy field is ignored.
Cron workloads can be run on-demand by submitting a runCronWorkload command via POST https://api.cpln.io/org/my-org/gvc/my-gvc/workload/my-cron-workload/-command
runCronWorkload Command
type: runCronWorkload
spec:
  location: aws-us-west-2
  containerOverrides:
    - name: my-container
      command: '/bin/sh'
      cpu: '25m'
      memory: '32Mi'
      image: 'ubuntu:latest'
      args:
        - '-c'
        - sleep 10
      env:
        - name: MY_ENV_VAR
          value: some-new-value

runCronWorkload Spec

  • location
    • The name of the location as specified in your GVC configuration.
  • containerOverrides
    • Optional: A list of objects that override specific parts of a container’s configuration.
  • containerOverrides[].name
    • The name of the container to override in the workload specification.
  • containerOverrides[].command
    • A new command for the container during this execution only. This field corresponds to workload.containers[].command in the workload specification.
  • containerOverrides[].cpu
    • A new CPU configuration for the container during this execution. This field corresponds to workload.containers[].cpu in the workload specification.
  • containerOverrides[].memory
    • A new memory allocation for the container during this execution. This field corresponds to workload.containers[].memory in the workload specification.
  • containerOverrides[].image
    • A new image for the container during this execution. This field corresponds to workload.containers[].image in the workload specification.
  • containerOverrides[].args
    • A new list of arguments for the container during this execution only. This field corresponds to workload.containers[].args in the workload specification.
  • containerOverrides[].env
    • A new list of environment variables for the container during this execution only. This field corresponds to workload.containers[].env in the workload specification.

Run via the CLI

Run a cron workload using the cpln CLI via cpln workload cron start. e.g.
If you do not specify a location using —location, the CLI will run the workload everywhere it has been deployed.
The —file parameter should contain a list of containerOverrides.
CLI Example
echo '[{"name":"my-container","command":"/bin/bash","args":["-c","sleep 10"],"env":[{"name":"MY_ENV_VAR","value":"some-new-value"}]}]' | cpln workload cron start cron --gvc my-gvc --org my-org --file -

Job History

A cron workload retains up to job.historyLimit job executions in its history. Each job execution will be in one of the following statuses:
  • Invalid
  • Active
  • Success
  • Failure
  • Removed

The Removed Status

The Removed status indicates that a job execution was deleted before it could finish execution. There are several reasons this can happen, but the most common are:
  • The job.concurrencyPolicy is Replace and while the job was still executing, job.Schedule dictated that the job should begin again.
  • The job.activeDeadlineSeconds limit was exceeded.

Serverless

Serverless workloads should be used for web applications that serve traffic on a single port, but may not need to run 100% of the time. Serverless workloads may:
  • Scale to zero.
Serverless workloads may not:
  • Serve traffic on multiple ports.
Serverless workloads must:
  • Expose a network endpoint.