Runtime
Serverless Functions
Create, deploy, invoke, pause, resume, and roll back Quilt functions.
Functions are Quilt’s serverless surface.
Use them when you want execution without managing a long-lived container yourself.
Primary Routes
POST /api/functions
GET /api/functions
GET /api/functions/<function_id>
GET /api/functions/by-name/<name>
PUT /api/functions/<function_id>
DELETE /api/functions/<function_id>
POST /api/functions/<function_id>/deploy
POST /api/functions/<function_id>/pause
POST /api/functions/<function_id>/resume
POST /api/functions/<function_id>/invoke
POST /api/functions/invoke/<name>
GET /api/functions/<function_id>/invocations?limit=<n>
GET /api/functions/<function_id>/versions
GET /api/functions/<function_id>/pool
GET /api/functions/pool/stats
GET /api/functions/<function_id>/invocations/<invocation_id>
POST /api/functions/<function_id>/rollback
Create a Function
{
"name": "my-function",
"cluster_id": "cluster_123",
"description": "Processes incoming data",
"handler": "echo hello",
"runtime": "shell",
"memory_limit_mb": 256,
"cpu_limit_percent": 25.0,
"timeout_seconds": 30,
"environment": {
"NODE_ENV": "production"
},
"min_instances": 0,
"max_instances": 5,
"cleanup_on_exit": true,
"working_directory": "/app"
}
Important notes:
- the create contract does not include
source_code - creation is driven by
handler,runtime, and the runtime-owned execution image runtimeis optional and defaults toshellmemory_limit_mbmust be at least256working_directorymust already exist in the execution image if you set it
Function Lifecycle in Plain English
- create: register the function and start its versioned lifecycle
- deploy: warm and start capacity
- invoke: run it
- pause: scale it to zero
- resume: route through deploy again so it becomes invocable
- update: create a new version instead of mutating the active version in place
- rollback: point back to an older version
Invoke a Function
{
"payload": "{\"key\":\"value\"}",
"environment": {
"EXTRA_VAR": "value"
},
"timeout_seconds": 30
}
Invocation response:
{
"invocation_id": "uuid",
"function_id": "uuid",
"function_name": "my-function",
"execution_node_id": "node-a",
"status": "success",
"started_at": 1760000000,
"ended_at": 1760000001,
"duration_ms": 1200,
"exit_code": 0,
"stdout": "Result output",
"stderr": "",
"error_message": null,
"cold_start": true
}
Pool State
Function pool status:
{
"function_id": "uuid",
"warming_count": 1,
"ready_count": 2,
"busy_count": 1,
"total_count": 4
}
Global pool stats:
{
"total_count": 4,
"warming_count": 1,
"ready_count": 2,
"busy_count": 1,
"recycling_count": 0,
"terminating_count": 0
}
The Field That Matters Most
ready_count tells you how many function containers are already started and invocable.
That is the closest thing to “warm and ready right now.”
Rollback
Rollback requires this exact body shape:
{
"version": 3
}
A Sensible Debugging Flow
Inspect function state
Confirm the function exists and the version state looks right.
Check recent invocations
Look for failures, duration, stderr, and cold starts.
Check pool status
Make sure capacity is actually warm enough for your expectations.
Only then change config
Adjust pool targets, deploy, pause/resume, or roll back with real evidence.
Common Mistakes
Is `cold_start` an error?
Is `cold_start` an error?
No. It is execution metadata. It tells you the invocation started from a cold path, not that the platform failed.
Does update change the active version in place?
Does update change the active version in place?
No. Update creates a new version.
If a function exists, is it ready to invoke?
If a function exists, is it ready to invoke?
Not necessarily. Existence, deployment state, and warm pool capacity are different things.
