Skip to main content

Functions

Functions are one of the Quave ONE app types. They are serverless-style applications on Quave ONE that automatically scale based on incoming traffic, including the ability to scale to zero when idle. They are powered by Knative and are ideal for event-driven workloads, APIs with variable traffic, webhooks, and background processors that don't need to run continuously.

How Functions Work

Unlike regular apps that maintain a fixed number of containers, functions dynamically adjust:

  • Scale to zero: When no requests are received for a configurable idle period, the function scales down to zero containers, saving costs.
  • Scale up on demand: When a request arrives, a container is started automatically (cold start). Subsequent requests are handled by active containers.
  • Concurrency-based scaling: New containers are added when the number of concurrent requests per container exceeds the configured threshold.

Prerequisites

  • The deployment region must support functions

If you want to run in a region where it's not available, please contact us.

Creating a Function App

Via the Web UI

  1. Navigate to Apps in your account
  2. Click Add function
  3. Choose the Use image deployment method
  4. Provide the Docker image URL for your function
  5. Select a region that supports functions
  6. Click Create

Via the API

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "my-function",
"accountId": "YOUR_ACCOUNT_ID",
"port": 8080,
"dockerPreset": "FUNCTION",
"useImage": true,
"image": "docker.io/myorg/my-function:latest"
}' \
https://api.quave.cloud/api/public/v1/app

Via CLI (build from source)

Create the app in the web UI or API, then deploy code directly:

quaveone deploy --user-token <token> --env <env name> \
--dir ./my-function

Quave ONE builds the Docker image from your Dockerfile and deploys it as a Knative function.

Via MCP

Ask your AI agent:

"Create a function app called my-function on port 3000 with a Dockerfile for CLI deployment"

Or with a pre-built image:

"Create a function app called my-function on port 8080 using image docker.io/myorg/my-function:latest"

The create-app MCP tool supports dockerPreset: "FUNCTION" for creating function apps, with either isCliDeployment: true (build from source) or useImage: true (pre-built image).

Function Configuration

Each function environment has a functionConfig that controls scaling and timeout behavior. You can configure these settings via the web UI, API, CLI, or MCP.

Configuration Fields

FieldTypeDescriptionDefault
containerConcurrencyIntegerMaximum number of concurrent requests per container instance. When exceeded, new containers are started.Knative default
timeoutSecondsIntegerMaximum time in seconds a request can take before being terminated.Knative default
idleTimeoutSecondsIntegerMinimum last-pod retention after the autoscaler decides to scale to zero. MCP accepts 300 or more; the account minimum defaults to 900. Requires the operator update below.Account default
responseStartTimeoutSecondsIntegerMaximum time in seconds to wait for the first byte of a response.Knative default
minScaleIntegerMinimum number of container instances to keep running. Set to 0 to allow scale-to-zero.0
maxScaleIntegerMaximum number of container instances. Subject to account-level maximum.Account default

Updating via the API

Use the dedicated function config endpoint:

curl -X PATCH \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appEnvId": "YOUR_APP_ENV_ID",
"containerConcurrency": 80,
"timeoutSeconds": 300,
"idleTimeoutSeconds": 900,
"minScale": 0,
"maxScale": 5,
"applyImmediately": true
}' \
https://api.quave.cloud/api/public/v1/app-env/function-config

You can also update function config through the general update endpoint (PUT /api/public/v1/app-env) by including a functionConfig object in the request body.

Updating via CLI

Pass function flags during deployment:

quaveone deploy --user-token <token> --env <env name> \
--fn-container-concurrency 80 \
--fn-timeout 300 \
--fn-idle-timeout 900 \
--fn-min-scale 0 \
--fn-max-scale 5

Updating via MCP

Ask your AI agent:

"Set the max scale to 5 and idle timeout to 900 seconds for my production function"

The update-function-config MCP tool handles all function configuration changes.

Deploying Functions

Functions support two deployment methods: building from source (recommended) or deploying a pre-built Docker image. Both methods support an environment-level startup command override.

Build from Source (CLI)

Deploy your code directly and let Quave ONE build the Docker image for you:

quaveone deploy --user-token <token> --env <env name> \
--dir ./my-function

You can combine code deployment with function config updates:

quaveone deploy --user-token <token> --env <env name> \
--dir ./my-function \
--fn-timeout 300 --fn-min-scale 0 --fn-max-scale 5

You can also override the function image's startup command without changing the build:

quaveone deploy --user-token <token> --env <env name> \
--dir ./my-function \
--command "bun run start:function"

Build from Source (MCP)

Use the code upload flow: request-deploy-storage-key to get an upload URL, upload your code archive, then notify-code-upload to trigger the build. Quave ONE builds the image and deploys it to Knative. The final tool can also receive startupConfig or clearStartupConfig.

Deploy a Pre-Built Image (CLI)

If you already have a Docker image, deploy it directly:

quaveone deploy --user-token <token> --env <env name> \
--image docker.io/myorg/my-function:v1.2.3

You can combine image deployment with function config updates:

quaveone deploy --user-token <token> --env <env name> \
--image docker.io/myorg/my-function:v1.2.3 \
--fn-timeout 300 --fn-min-scale 0 --fn-max-scale 5

The same pre-built image can use a different command in this function environment:

quaveone deploy --user-token <token> --env <env name> \
--image docker.io/myorg/my-function:v1.2.3 \
--command "bun run start:function"

Startup configuration is persistent for the environment and is separate from Knative scaling and timeout settings. Use --clear-command to return to the image defaults.

Deploy a Pre-Built Image (API)

Use the deploy-image endpoint:

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"appEnvId": "YOUR_APP_ENV_ID",
"image": "docker.io/myorg/my-function:v1.2.3",
"startupConfig": {
"command": "bun run start:function",
"shell": true
}
}' \
https://api.quave.cloud/api/public/v1/app-env/deploy-image

Function apps can use the deploy-image endpoint without needing useImage=true on the app.

Deploy a Pre-Built Image (MCP)

Ask your AI agent:

"Deploy image docker.io/myorg/my-function:v1.2.3 to my production function and start it with bun run start:function"

Scaling Behavior

Cold Starts

When a function is scaled to zero and a request arrives, a new container must start before it can handle the request. This introduces a cold start delay. To minimize cold starts:

  • Set minScale to 1 or higher to keep at least one container warm
  • Optimize your container startup time (keep the image small, minimize initialization work)
  • Use responseStartTimeoutSeconds to configure how long to wait for the first response byte

Scale-to-Zero

Knative autoscaling can reduce a Function to zero containers when idle, provided minScale is zero and scale-to-zero is enabled. On upgraded operators, idleTimeoutSeconds retains the final pod after the autoscaler decides to scale to zero; see the rollout prerequisite below.

  • The MCP input minimum for idleTimeoutSeconds is 300 seconds. The account's functionMinIdleTimeoutSeconds defaults to 900 seconds (15 minutes); lower submitted values are raised to that account minimum. For example, requesting 600 with the default account minimum stores 900, not 600.
  • Scale-to-zero can be disabled at the account level by setting functionScaleToZero to false

Concurrency-Based Scaling

Knative monitors the number of concurrent requests per container. When the containerConcurrency limit is approached, new containers are started to handle the load, up to the maxScale limit.

Differences from Regular Apps

AspectRegular AppsFunctions
ScalingFixed containers or HPA autoscalingKnative concurrency-based, scale to zero
DomainStandard app domainDedicated function domain
BillingStandard per-container pricing3x multiplier on function pod time
PodsRecent pods shownLast 20 pods shown regardless of status
RegionsAll enabled regionsOnly regions with function domain support
Persistent StorageSupported (volumes)Not supported

Billing

Function pods are billed at 3x the standard per-container rate. This multiplier accounts for the Knative infrastructure overhead and the scale-to-zero capability. When your function is scaled to zero, you are not billed for container time. See Pricing details for how this relates to the standard zCloud rate.

Observability

Functions support the same observability tools as regular apps:

  • Logs: View function logs via the web UI, API (GET /logs), CLI, or MCP (get-logs)
  • Requests: Open the Function environment's Requests tab in the web UI to inspect recent HTTP request volume, status codes, and latency from ingress access logs.
  • Pods: View function pods via the web UI, API (GET /app-env/pods), or MCP (get-app-env-pods). Functions show the last 20 pods regardless of termination status
  • History: View deployment history via the web UI, API (GET /app-env/history), or MCP (get-app-env-history)
  • Status: Check function status via the web UI, API (GET /app-env/status), or MCP (get-app-env-status)

Note: Traditional CPU and memory metrics are not collected for functions since containers are ephemeral.

Managing Functions via MCP

The following MCP tools are useful for managing functions:

ToolDescription
create-appCreate a function app with dockerPreset: "FUNCTION" (supports both isCliDeployment and useImage)
update-function-configUpdate function scaling and timeout settings
request-deploy-storage-keyGet upload URL for code deployment (Step 1 of build from source)
notify-code-uploadTrigger build after code upload and optionally update or clear startupConfig
deploy-app-env-imageDeploy a pre-built Docker image and optionally update or clear startupConfig
get-app-envView function configuration (includes functionConfig and isFunction flag)
get-app-env-statusCheck function runtime status
get-app-env-podsView function pod details
get-logsView function logs
stop-app-envStop a function environment
start-app-envStart a stopped function environment

Limitations

Current migration and timeout limitations

Protected App-to-Function conversion requires the routing and timeout operator update tracked in infra issue #1015. Confirm that update is deployed in your target region before converting private content; staging qualification does not imply production availability.

On upgraded clusters, all published default and custom hostnames share the platform Basic Auth and TLS ingress. The Function backend is cluster-local, so the wildcard Function route cannot bypass authentication. Certificates are issued and renewed by cert-manager independently of Function pods, including while the Function is scaled to zero. Explicitly stopping an environment is different: it removes the public route and suspends its automatic certificate renewal.

App/Function type conversion through update-app preserves the existing image or Dockerfile deployment source. It does not enable changing a Function's source mode or bypass region/account restrictions. Persistent volumes, TCP, extra-port paths, SockJS affinity, and custom ingress auth/snippet overrides are not supported. Verify authentication on every public endpoint after conversion.

timeoutSeconds is the overall request deadline; the first-byte deadline is bounded by that overall deadline. idleTimeoutSeconds controls Knative's scale-to-zero pod retention: the minimum time the last pod remains after the autoscaler decides to scale to zero. It is not an exact timer from the last request, nor Knative's response-byte idle timeout. Older operators do not correctly enforce these settings.

Other limitations

  • Dockerfile required: Functions must have a Dockerfile for building from source. Docker presets that auto-generate Dockerfiles are not supported for functions.
  • No persistent volumes: Functions cannot use persistent storage (useVolume is not supported).
  • Region restrictions: Functions are only available in regions that have a function domain configured.
  • No traditional autoscaling: Functions use Knative's concurrency-based scaling instead of the HPA autoscaling available for regular apps. The update-app-env-scaling-options and scale-app-env-containers tools do not apply to functions.
  • Startup command support: Functions support the same shell, direct, args-only, working-directory, and reset behavior as regular Apps.