A runtime is a backend program that Fluffy starts for your application. It might answer HTTP requests, wait for queued work, or receive scheduled invocations. Its declaration connects the program's executable image to its resource permissions and execution policy.
You write the program. Fluffy builds or acquires its artifact, supplies the runtime environment and sidecar, and starts it in the selected local or cloud environment.
#Understand artifacts and runtimes
An artifact describes what Fluffy builds or acquires. For a runtime, that result is an OCI image archive with an executable entrypoint. A runtime refers to the artifact and declares the resources, incoming requests, or messages that program needs.
Several runtimes can refer to the same artifact while keeping separate access contracts. The runtime manifest has no command override: executable startup behavior belongs to the image. Database migration and seed tasks have their own explicit command fields because they are separate lifecycle tasks.
#Choose the lifetime your program needs
An HTTP service can wait for a request and may be allowed to scale to zero. A pull worker actively asks for messages, so it needs CPU and an instance available even when no HTTP request is arriving. A scheduled runtime receives a verified invocation at the chosen times.
These are execution requirements, not merely names. Calling a type worker does not keep it running; the selected product's capacity settings do that. Messaging shows a Cloud Run pull-worker policy with an always-running instance.
#A listening port does not implement a route
A program that accepts HTTP must listen on the declared port on 0.0.0.0. Fluffy can route traffic to it, but your program must implement the path and method being requested. A correct deployment with no GET /hello handler still returns a 404 for that request.
Direct HTTP ingress, a private service edge, browser exposure, push delivery, and schedules are different ways traffic can reach a runtime. Connect services and Authentication explain the access boundaries.
#Configure a runtime
#Declare the artifact and runtime
The runnable start example includes this artifact recipe and API declaration:
artifacts:
api-image:
builder: golang@sha256:53eeac89074db483fdf0ab3be1df32bf6e47562263d2d0d6baa7f26acb4957dd
exec: [sh, ./build/run.sh, runtime, api]
runtimes:
api:
artifact: api-image
port: 8080
ingress: {http: true}The recipe is runnable in that example because build/run.sh and its Go image builder are included there. It compiles runtimes/api, packages the program as /app, and writes image.tar to FLUFFY_OUT_DIR. It uses FLUFFY_TARGET_PLATFORM for the target architecture. Copying this YAML alone into another project does not create the builder script.
For your own project, use a pinned builder image and an existing build command that produces the required archive. A compiled executable on its own is not the OCI image artifact. Keep uses, schedules, and consumers when editing an existing runtime.
#Choose cloud placement
In fluffy-chainsaw.workspace.yaml, a type selects Cloud Run and defines a named size. An environment selects that type, size, and an already configured provider:
resourceTypes:
runtimes:
service:
product: gcp.cloud-run
sizes:
standard:
cpu: 1
memory: 512Mi
minInstances: 0
maxInstances: 3
cpuIdle: true
environments:
prod:
runtimes:
defaults:
type: service
provider: application
size: standardThis is an HTTP-service example. Choose different settings for a continuously polling worker. The environment also needs its provider project, region, and deployment configuration; see Deployment.
#Add and verify an HTTP handler
The following standalone HTTP programs expose a health route. They do not need a gRPC server: Fluffy's generated clients make outbound calls to the sidecar. Use your usual language build and HTTP framework. These examples all listen on port 8080:
import { createServer } from 'node:http';
createServer((request, response) => {
response.writeHead(request.method === 'GET' && request.url === '/health' ? 204 : 404);
response.end();
}).listen(8080, '0.0.0.0');From its workspace root:
The C++, Ruby and Rust examples use cpp-httplib, WEBrick and Axum, respectively. Install those through your normal language build. For the Go Notes reference, keep its existing build and use:
fluffy-chainsaw generate --application notes --all --language go
fluffy-chainsaw local --application notesRequest /hello on the API URL Fluffy prints. Expect HTTP 200 and the greeting. Then request an unimplemented path to distinguish routing to the process from having a handler. Protect real data with authentication and application authorization.
#Add resource dependencies
A runtime's uses section grants its resource actions. Regenerate its SDK after changing those declarations and write the code that calls the new methods. How access works shows why editing YAML, generating a client, and changing deployed access are separate steps.
#Add scheduled work
A schedule belongs to the runtime that handles it:
runtimes:
api:
schedules:
hourly-check:
cron: "0 * * * *"The five fields are minute, hour, day of month, month, and weekday, evaluated in UTC. This expression runs at minute zero of each hour. The schedule name does not determine the cadence.
Implement POST /.well-known/fluffy/v1/schedules/hourly-check/invocations. Pass the original method, path, and headers through the generated InboundSchedules client's VerifyInvocation before doing work. The example's verifySchedule handler demonstrates that verification path. Repeated invocations need idempotent handling, just as message deliveries do.
The selected environment must supply a complete runtime schedule policy, for example under environments.prod.runtimes.defaults.schedules:
attemptDeadlineSeconds: 300
retryCount: 3
maxRetryDurationSeconds: 3600
minimumBackoffSeconds: 5
maximumBackoffSeconds: 300
maxDoublings: 5These are example settings, not implicit defaults. They control the invocation's deadline and retries; they do not extend the lifetime of a request your code has already abandoned.
#Reference: runtime and build constraints
| Field | Meaning and constraint |
|---|---|
artifact | Required; names a declared runtime artifact |
type | Optional explicit runtime type; otherwise workspace policy selects it |
port | 1–65,535; required when the runtime receives inbound HTTP |
ingress.http | If present, must be true; declares direct HTTP ingress |
identity.signJwt | Optional identity capability; does not replace application authorization |
uses | Outgoing resource, service, flag, or extension capability access |
consumes | Incoming queue/topic deliveries; see messaging constraints |
schedules | Named, verified scheduled invocations with five-field UTC cron |
Inbound HTTP includes browser/service targets, push consumers, schedules, and direct ingress. Declaring any of these without the required port is invalid.
Built artifacts require a digest-pinned builder and a nonempty exec argument list. An external artifact uses external: true instead; it cannot also contain the built-artifact fields. Static assets and executable runtime images cannot share one artifact declaration as different consumer kinds.
#Schedule policy bounds
attemptDeadlineSeconds is 15–1,800; retryCount is 0–5; maxRetryDurationSeconds and maxDoublings are nonnegative. Backoff values are positive, and the maximum must be at least the minimum. The complete resolved policy is required for scheduled work.
#Diagnose startup and routing
A failed build needs its command output and artifact contract checked. A process that exits needs its runtime logs. An unreachable HTTP endpoint needs the listening address, declared port, and exposure checked. An HTTP 404 means the program was reached but has no matching route; a missing SDK method points to a different boundary, the grant and generation step.
Continue with Databases to give the runtime durable data, or Run locally to configure source reloads.