Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Runtime flags

This page is for operators who run the function-wasm runtime from a Crossplane package and set its flags through a DeploymentRuntimeConfig. It lists each flag with its environment variable and default, one line each. The linked pages have the detail.

The binary has two subcommands, serve and validate. serve is the default, so function --insecure --module-dir=. and a DeploymentRuntimeConfig’s args don’t name it. validate takes the flags marked “yes” in the validate column below, with the same defaults and environment variables, so it checks a Composition against what a runtime started with those flags would admit.

Limits and sources

These flags set the ceilings that a step’s limits can’t exceed (Input reference) and where path sources come from.

flagenvdefaultvalidatepurpose
--module-dirMODULE_DIRunsetyesdirectory served for path sources; unset refuses them
--max-module-size128 MByeslargest module accepted
--module-timeout30syeswall-clock budget of one run, and the ceiling for limits.timeout
--module-memory-limit512 MByesmemory one run may use: its linear memories and tables (a host pointer per element) together, the initial memory included; also the ceiling for limits.memory
--module-stack-limitMODULE_STACK_LIMIT512 KBnocall stack one run may use. Past it the run fails with trap: call stack exhausted. No Input field narrows it
--ttl60snoTTL of responses the runtime itself produces (fatal results); a module sets its own

Concurrency

By default nothing is bounded: concurrency is the caller’s, set by Crossplane’s reconcile workers.

flagenvdefaultvalidatepurpose
--max-concurrent-runsMAX_CONCURRENT_RUNS0 (unbounded)nomodule runs executing at once; a request that can’t get a slot before its deadline is a fatal result (waiting for a run slot: deadline exceeded) and never ran
--max-total-run-memoryMAX_TOTAL_RUN_MEMORY0 (unbounded)nototal memory budget in MB across running modules, linear memories and tables together; see below
--max-concurrent-compilesMAX_CONCURRENT_COMPILES1nomodules compiled at once; a compile is heavy on CPU and memory, so further first requests wait their turn
--module-compile-timeoutMODULE_COMPILE_TIMEOUT0s (unbounded)nowall-clock bound on a cold load, the fetch and compile of a module that isn’t cached yet. Past it the request fails with cannot load module …: compile exceeded --module-compile-timeout <duration>; the compile runs to its end, keeps its compile slot until then and stores its artifact for the next request. The syntax of --module-timeout

A component reserves nothing up front. The runtime charges each memory or table growth, the initial memory included, to the --max-total-run-memory pool as the guest claims it, and a run waits under its deadline while the pool is full. A growth the pool can’t serve before the deadline fails inside the guest as a failed memory.grow, counted in function_wasm_module_memory_denials_total. See Sizing for what these bounds cost.

Caches

Compiled modules are cached in memory, and fetched modules and compiled artifacts on disk. See Cache storage for the directory.

flagenvdefaultvalidatepurpose
--enable-memory-cacheENABLE_MEMORY_CACHEtruenokeep compiled modules in memory between requests; the flag takes a value, and with --enable-memory-cache=false each request maps the compiled artifact from disk and releases it afterward
--max-cached-modulesMAX_CACHED_MODULES0 (unbounded)nomost compiled modules resident at once; past it the least recently used is dropped, freed once its last run ends
--max-cache-sizeMAX_CACHE_SIZE0 (unbounded)noMB the two on-disk caches may hold together; past it the runtime removes the least recently used entries, at startup and every ten minutes. Size the volume, or set this below its size
--warm-modulesWARM_MODULESunsetnomodules loaded before readiness; see Readiness and warm-up

Signing

These flags set which module signatures the runtime accepts. Signatures explains each mode and how they combine.

flagenvdefaultvalidatepurpose
--cosign-keyCOSIGN_KEYunsetyesPEM file of cosign public keys for key-based cosign 3 signatures
--cosign-trusted-rootCOSIGN_TRUSTED_ROOTunsetyesSigstore trusted_root.json that verifies keyless signatures offline; excludes --cosign-trust-instance
--cosign-trust-instanceCOSIGN_TRUST_INSTANCEunsetyespublic-good, staging or github: fetch that instance’s trusted root over TUF and refresh it while serving
--cosign-tuf-refreshCOSIGN_TUF_REFRESH1hnohow often --cosign-trust-instance refreshes the root, at least 1m

Policy and egress

See Operator grant policy for writing and mounting the policy and HTTP egress for the egress budgets.

flagenvdefaultvalidatepurpose
--sandbox-policy-fileSANDBOX_POLICY_FILEunsetyesCedar document holding the operator’s grant policy; unset, every sandbox capability is refused. Compiled once at startup: restart to reload
--egress-rate-limit-per-minuteEGRESS_RATE_LIMIT_PER_MINUTE0 (off)yessustained egress requests per minute per module digest, as a process-wide token bucket
--egress-rate-limit-burstEGRESS_RATE_LIMIT_BURST0 (derived)yesburst tokens for the rate limit; 0 derives max(1, requestsPerMinute)

Health and metrics

Both endpoints are plain HTTP, because the function port speaks mTLS. Readiness and warm-up covers wiring probes.

flagenvdefaultvalidatepurpose
--health-addressHEALTH_ADDRESS:8081no/livez and /readyz (503 while warming); empty disables them
--metrics-addressMETRICS_ADDRESS:8080noPrometheus /metrics (Metrics); empty disables it

The SDK’s flags --insecure, --debug, --tls-certs-dir, --address and --max-recv-message-size apply too.

Logging

--debug turns on the runtime’s own debug lines in a human-readable format: guest log records sent at debug level, the credentials withheld from a module and trap details. Everything else logs at info, so a compile under --debug doesn’t print the compiler’s per-pass lines. A set RUST_LOG replaces the flag’s filter in full.

Cache storage

The caches live under /tmp/function-wasm-cache, which isn’t configurable. Mount an emptyDir there if the pod’s root filesystem is read-only, or a volume to keep the fetched modules and manifests across pod restarts:

spec:
  deploymentTemplate:
    spec:
      template:
        spec:
          containers:
          - name: package-runtime
            volumeMounts:
            - name: cache
              mountPath: /tmp/function-wasm-cache
          volumes:
          - name: cache
            persistentVolumeClaim:
              claimName: function-wasm-cache

A volume keeps the fetched modules and the manifests, which the runtime verifies against their digest on every read. It doesn’t keep the compiled code. Each process signs the artifacts it writes under a key drawn at startup and refuses every other (trust model). A restarted pod compiles its modules again. Pods must not share a volume, because each would refuse and overwrite the other’s artifacts. Give each pod its own volume, with the runtime as its only writer. The runtime removes the compiled directories of other Wasmtime versions after a day without writes.

Opening the sandbox

Mount the Cedar --sandbox-policy-file through the same DeploymentRuntimeConfig, and put a tmpfs behind TMPDIR to bound the private /tmp:

spec:
  deploymentTemplate:
    spec:
      template:
        spec:
          containers:
          - name: package-runtime
            args:
            - --sandbox-policy-file=/etc/function-wasm/policy.cedar
            env:
            - name: TMPDIR
              value: /scratch
            volumeMounts:
            - {name: policy, mountPath: /etc/function-wasm, readOnly: true}
            - {name: scratch, mountPath: /scratch}
          volumes:
          - name: policy
            configMap: {name: function-wasm-policy}
          - name: scratch
            emptyDir: {medium: Memory, sizeLimit: 64Mi}

A fuller example with every operator-authorable option is examples/deployment-runtime-config-cedar.yaml.