Skip to content

Serverless

Serverless runs your containers without a cluster to manage: services that scale with requests, down to zero, jobs that run to completion, and stacks that create an app together with its database, cache, bucket and model route. It runs on your own servers or on the Frazer fleet, in a runtime Frazer operates for your organization. What makes it different is the wiring: a deploy reads your code, proposes the data it needs, and connects it with bindings, so nobody copies a password or a storage key.

Product overview: Serverless.

You deploy from a repository, an image or a stack file. Frazer builds the image, signs it, and creates an immutable revision. Traffic moves to the revision once it is ready, and the service’s instances scale between your minimum and maximum with the requests it receives. Every change is a plan you read before anything happens.

  • Where it runs. Frazer runs one serverless runtime cluster per organization per site, created with your first service at that site. It takes capacity from your server pool there, and Site capacity shows it as “Frazer serverless runtime”. You never see or manage that cluster. Without servers of your own, the same runtime runs on Frazer fleet nodes, one organization per node.
  • Isolation. Your code runs in a sandbox with a user-space kernel. Each project gets its own namespace with default-deny network policies, a resource quota from the project’s quota, the project’s secrets namespace, and the project’s metrics and logs.
  • Delivery. Revisions are stored in the Frazer API, rendered into the runtime’s serving objects, and applied by Frazer GitOps inside the runtime as signed desired state. The image is checked for its signature on admission.
  • Builds. A repository with a Dockerfile builds with it. Without one, Frazer detects Node, Python, Go, PHP, Java, Ruby and static sites; Cloud Native Buildpacks cover Java, .NET and other enterprise stacks. Builds run in a rootless image builder in the runtime, use Frazer Cache, push to Frazer Registry, and attach a signature and an SBOM.

Key terms:

  • Service: an HTTP or gRPC endpoint that scales with requests.
  • Revision: an immutable snapshot of a service: image digest, configuration, scaling and pinned secret versions. Named <service>-<number>, for example notes-api-00042.
  • Traffic: how requests are shared between revisions, by percentage or by tag.
  • Tag: a name on a revision that gives it its own URL and no public traffic.
  • Job: a container that runs one or more tasks to completion, by hand, on a schedule, or as a deploy’s release command. Each run is an execution.
  • Worker pool: containers with no URL that scale on a queue (Valkey streams, Postgres queues, Kafka or your own NATS) or run at a fixed count.
  • Stack: an app’s services, jobs and data resources, created by one plan and deleted together. A resource belongs to at most one stack.
  • Binding: “this service uses that resource as these variables”, with the identity and grant it needs.

The first time you deploy an app, from the Frazer app, the console or frazer deploy, Frazer asks where it should run and recommends one answer with its reason. The answer is stored in the repository as .frazer/app.yaml (runtime: serverless or runtime: kubernetes), so later deploys do not ask again.

Your app Recommended
A stateless HTTP or gRPC server up to 8 vCPU and 32 GiB, with no local disk needs Serverless
A project with no cluster Serverless
A repository already in a connected environment Kubernetes
StatefulSets, DaemonSets, CRDs or operators, host networking, raw TCP or UDP listeners, more than one GPU per pod Kubernetes
A long-running consumer without HTTP A serverless worker pool, or Kubernetes
A model to serve An inference endpoint in AI and GPUs

Both answers end in Frazer GitOps, and you can move a service to Kubernetes later.

You need the frazer CLI signed in (frazer login) and the Developer role on the project. The example deploys notes-api from the repository you are in, with a Postgres database and a Valkey cache, to the project acme-staging.

  1. Plan the deploy. The plan lists what Frazer detected in your code, every resource it will create, the bindings, the URL and the cost. Nothing is created yet.

    Terminal window
    frazer serverless deploy notes-api --source . \
    --with postgres,valkey --project acme-staging --dry-run
    Output
    Detected Next.js · Prisma (Postgres) · ioredis (Valkey)
    Plan + stack notes · service notes-api · scale 0–5 · sandbox
    + Postgres notes-db · small · PITR 7 days · binding DATABASE_URL
    + Valkey notes-cache · Basic · binding VALKEY_URL
    + notes-api-p7k2.frazer.run · TLS
    Cost included in the server fee · on your servers

    Use --image <digest> instead of --source . to deploy an image from Frazer Registry or a connected registry. --with takes postgres, valkey, bucket and llm.

  2. Apply the plan: run the same command without --dry-run, or choose Deploy in the console. Frazer builds the image, creates the database and the cache, writes the bindings, and creates revision notes-api-00001. Callers never see a half-deployed service: a revision receives traffic only once it is ready.

    Output
    ✓ revision notes-api-00001 ready
    https://notes-api-p7k2.frazer.run
  3. Open the URL, then follow the logs:

    Terminal window
    frazer logs notes-api --follow

To deploy on every push, choose the branch when you create the service: the GitHub App “Frazer Reader” notifies Frazer and each push builds a new revision. In a production project, a second person approves the plan before it applies; see Access and audit.

A binding writes environment variables from a Frazer resource and grants the service the access it needs. People never read binding values: the service’s Variables and secrets tab shows names, sources and versions.

Binding to Variables How access works
Postgres DATABASE_URL (through the pooler), DATABASE_DIRECT_URL, PG* A role generated for the service, its password kept in the secrets store, reached over a private endpoint
Valkey VALKEY_URL, with the alias REDIS_URL An ACL user from the app-readwrite template
Memcached MEMCACHED_SERVERS Network and TLS
Bucket S3_BUCKET, plus the S3 endpoint and region variables below Short-lived credentials from the service’s identity; no access keys
LLM gateway route FRAZER_LLM_BASE_URL and a token file A one-hour token for the service, with a budget per route
Secret Any name you choose A path in the secrets store, version pinned per revision
Another service <NAME>_URL The internal URL, with permission to call it

A bucket binding writes its endpoint and region as AWS_ENDPOINT_URL_S3 and AWS_REGION.

Secret versions are pinned per revision, so a revision is reproducible. A new database password or a new secret version rolls out as a new revision; Valkey passwords overlap during rotation.

To add a binding to an existing service, add it to the service’s bind map in the stack file, or change it on the service’s Variables and secrets tab. Either way the change is a plan, and applying it creates a revision. Plain environment variables live on the same tab.

Every change to the image, variables, bindings, scaling or runtime creates a revision. Choose how traffic reaches it:

  • All at once: the default in staging.
  • Gradual: the default in production. Traffic moves 10 → 25 → 50 → 100 %, ten minutes per step, behind an analysis gate that compares the 5xx rate, the p95 latency and the cold-start p95 with the previous revision. A failing gate rolls back and opens an incident.
  • No traffic: the revision is created and gets no public traffic until you send it some.

Split traffic and tag a canary. The tag gets its own URL, https://canary---notes-api-p7k2.frazer.run:

Terminal window
frazer serverless traffic notes-api \
--split 00008=75,00009=25 --tag 00009=canary --dry-run

Roll back by sending all traffic to an earlier ready revision. No rebuild is needed:

Terminal window
frazer serverless traffic notes-api --to notes-api-00008=100 --dry-run

Run each command again without --dry-run to apply it. Frazer keeps the specification of the last 20 revisions; pin a revision to keep it longer. A revision that fails never receives traffic.

A deploy can run a release command, such as a database migration, before traffic moves. It runs as a one-off job with the new revision’s image and bindings, and if it fails, the deploy stops and traffic stays where it was. In a stack file it is the service’s release key, for example release: "alembic upgrade head".

A pull request can open a preview stack: the service as a tagged revision, a Postgres branch from a snapshot of the stack’s database, a fresh Valkey instance and a scratch bucket prefix. It is deleted when the pull request closes or after seven days. Production data is never used unless your preview policy says so. Previews are set up with a preview policy; see Templates and previews.

Instances scale with requests between a minimum and a maximum. CPU is allocated for an instance’s whole life, not only while it handles a request, and you pay while the instance exists.

Setting Default What it does
Min instances 0 in staging and previews, 1 in production Instances kept running with no traffic. Set on the service, so changing it creates no revision
Max instances 20 The ceiling, up to your project quota
Concurrency 80 The hard limit of requests per instance. The autoscaler aims at 70 % of it
Size run-1x: 1 vCPU, 1 GiB From run-0.25x to run-8x (8 vCPU, 32 GiB). Requests equal limits
Request timeout 300 seconds Up to 3,600 seconds
Scale-down delay 15 minutes How long an idle instance stays before it is removed

In a stack file, scaling is the service’s scaling map:

frazer.stack.yaml
services:
notes-api:
scaling: { min: 1, max: 20, concurrency: 80 }

Cold starts. When a service is at zero, the first request waits while an instance starts; it does not get an error. Every revision that has traffic or a tag is pre-pulled on the runtime’s nodes, and each service page shows the cold-start count and the wait at p50 and p95. Keep one instance warm (min: 1) when that wait matters.

Each service gets https://<service>-<hash>.frazer.run on Frazer’s apps domain, kept apart from frazer.ai. Cookies stay host-only there: the edge refuses a cookie set for the parent domain, so one app can never set or read another’s cookies on frazer.run. The same rule holds for raw files served from frazerusercontent.com. Default URLs, tag URLs and custom domains answer over IPv4 and IPv6.

Custom domains. Add a hostname on the service’s Networking tab. Frazer issues the certificate and handles DNS one of three ways:

  • Delegate a subdomain to Frazer DNS, and Frazer manages the records. See DNS and certificates.
  • Keep your DNS provider, with a token limited to one zone.
  • Manage the records yourself: the console shows the exact records, plus one _acme-challenge CNAME so certificates renew without a provider token.

Access modes. Choose one per service:

  • Public: anyone can call the URL.
  • Frazer sign-in: callers sign in with Frazer and need the serverless.services.invoke permission.
  • Internal: no public route. The service is reachable only inside the project’s VPC network at <service>.run.<project>.internal.

Outbound traffic leaves through the project VPC’s NAT. Managed data is reached only through private endpoints. Port 25 is blocked on both IPv4 and IPv6.

A job runs a container to completion: one task, or up to 10,000 tasks with a parallelism you choose. Each task receives TASK_INDEX and TASK_COUNT. A failed task retries three times by default (0 to 10), and a task may run for up to 24 hours. Schedules take a cron expression, a time zone and a concurrency policy.

Create a daily job from the service’s image, then run it once by hand:

Terminal window
frazer serverless jobs create notes-digest --from notes-api --schedule "0 7 * * *"
frazer serverless jobs execute notes-digest

In a stack file:

frazer.stack.yaml
jobs:
notes-digest: { from: notes-api, command: ["python", "-m", "notes.digest"], schedule: "0 7 * * *", tz: UTC }

You can run a job with overrides for its arguments, environment and task count. Each execution shows its tasks as succeeded, failed or retried.

Move to Kubernetes. Frazer writes the service into an environment repository you choose as a pull request (Deployment, Service, HTTPRoute, autoscaling, and ExternalSecrets for the bindings), shifts traffic at the gateway, then retires the service. The data stays where it is.

Terminal window
frazer serverless move notes-api --to kubernetes \
--environment acme/platform-envs:envs/production --dry-run

The pull request comes from the opt-in GitHub App “Frazer”. Moving the other way creates a service from a workload’s image and environment; you then delete its folder from Git. Both directions are plans with a cutover step.

Export a stack. Without a repository file, the Frazer API is the source of truth. Export the definition to keep it in Git; once a repository holds frazer.stack.yaml and is connected, console edits become pull requests and the fields show From Git.

Terminal window
frazer serverless stacks export notes > frazer.stack.yaml

Delete. Delete a service on its own, or a stack with every member together; a stack’s databases get a final backup first. A service with deletion protection on is refused until you turn it off.

Terminal window
frazer serverless services delete notes-api --dry-run
frazer serverless stacks delete notes --dry-run
Role Can
Viewer Reads services, revisions, traffic, jobs and stacks
Developer Deploys
Responder Rolls back and restarts
  • Approvals. In a production project a deploy needs a second person’s approval and a step-up sign-in. Nobody approves their own plan, and agents never approve.
  • Agents. MCP tools are read-only by default. A write becomes a plan that a person applies, and the audit log records it as the agent acting on behalf of that person.
  • What is logged. Every plan and apply, with the revision it created. Each build records its commit, image digest and revision, with the signature and SBOM.
  • Values stay hidden. Binding values and secret values are never shown to people, only names, sources and versions.
  • Support. Frazer support has read-only views of the runtime cluster.
Limit Default Range
Min instances per service 0 (staging, previews), 1 (production) 0–100
Max instances per service 20 1–1,000, within project quota
Concurrency per instance 80 1–1,000
Instance size run-1x (1 vCPU, 1 GiB) run-0.25x to run-8x (8 vCPU, 32 GiB)
Request timeout 300 s 1–3,600 s
Scale-down delay 15 min 0–60 min
Revisions kept with their specification Last 20 Pinned revisions are kept
Tasks per job 1–10,000
Retries per task 3 0–10
Task timeout Up to 24 h
Preview stack lifetime 7 days, or until the pull request closes

You pay for vCPU and memory while an instance exists, at the same rate as a VM, with no request fee; on your own servers it is part of the server fee.

ServerlessOn your serversOn the Frazer fleet
PriceIncluded$0.030 / vCPU-hour + $0.007 / GiB-hour, per second

Every line, with the estimator: pricing.

Builds bill at the same rates. A stack’s data resources bill as themselves. On the Frazer fleet, a capped budget scales services to zero and suspends job schedules when it is reached; nothing is deleted.

Start with the signals. Each service page shows requests by status, latency at p50, p95 and p99, instances against the minimum, cold starts, CPU and memory per instance, and billable instance time. Logs carry the request ID and the revision, with a live tail (frazer logs notes-api --follow). New services get alert policies for a 5xx rate above 2 % for 5 minutes, p95 above 1 second for 10 minutes, instances at the maximum for 15 minutes, and a failed revision. Frazer Monitoring has a Serverless service dashboard; see Frazer Monitoring.

Symptom Cause Fix
The deploy stopped and traffic stayed on the old revision The release command failed Read the release job’s logs, fix the migration, and deploy again
A new revision never receives traffic It failed to become ready (frazer.service.revision.failed.v1) Read the build and the revision’s logs; traffic stays on the last ready revision
A gradual rollout went back to the previous revision The analysis gate saw a worse 5xx rate, p95 or cold-start p95 Open the incident it created, compare the revisions, fix, and deploy again
The first request after a quiet period is slow The service scaled to zero and an instance is starting Set min: 1, or a longer scale-down delay
The alert “instances at max” fires Requests need more instances than the maximum allows Raise max instances within your quota, or the size
Callers are asked to sign in, or are refused The service uses Frazer sign-in Grant the callers serverless.services.invoke, or change the access mode
The URL does not answer from the internet The service is Internal Call it from the project’s VPC network, or change the access mode
The plan creates a database you do not want Detection found a client library in your code Untick the row in the plan, or drop it from --with
Services on the fleet scaled to zero and schedules stopped A capped budget was reached A billing admin lifts the cap with a reason

CLI

CommandWhat it does
frazer deployDeploy the repository you are in. Asks once per app whether it runs on Kubernetes or serverless, and remembers the answer.
frazer serverless deployBuild and deploy a service from source or an image, with the data resources it needs, as one plan.
frazer serverless services listList the services in a project.
frazer serverless services getShow a service, its URL, its revisions and its traffic.
frazer serverless services deleteDelete a service.
frazer serverless trafficSend traffic to a revision, split it between revisions, or tag a revision with its own URL. Rolls back.
frazer serverless jobs createCreate a job from a service's image, with an optional schedule.
frazer serverless jobs executeRun a job now.
frazer serverless stacks createCreate a stack and every resource in it from a frazer.stack.yaml file.
frazer serverless stacks exportWrite a stack's definition as frazer.stack.yaml.
frazer serverless stacks deleteDelete a stack and its members together, with final backups.
frazer serverless moveMove a service to Kubernetes as a pull request to an environment repository.

All of them: CLI reference.

MCP tools

ToolWhat it does
serverless_detectRead a repository and list the data it needs (Postgres, Valkey, a bucket, an LLM gateway route).
serverless_services_deploy_planPlan a deploy, Kubernetes or serverless, with the detected resources, bindings and cost. Writes become a plan that waits for approval.
serverless_services_getShow a service's state, revisions and traffic.
serverless_logs_listRead a service's logs.
serverless_traffic_update_planPlan a traffic change or a rollback. Writes become a plan that waits for approval.
serverless_stacks_create_planPlan a new stack or a change to one. Writes become a plan that waits for approval.

All of them: MCP tools reference.

Events

Event typeWhen it is sent
frazer.service.deployed.v1A deploy of a service finished.
frazer.service.revision.ready.v1A new revision is ready and can receive traffic.
frazer.service.revision.failed.v1A revision failed to become ready. It receives no traffic.
frazer.stack.created.v1A stack and its resources were created.

All of them: Events reference.