Choosing a runtime
Every Alchemy app on AWS needs somewhere for its code to run. Alchemy ships four runtimes, all driven by the same pattern — bundle an Effect program, deploy it as a resource, bind building blocks to it:
- Lambda — serverless functions. Use this by default.
- ECS — long-running containers on Fargate.
- EKS — containers as Kubernetes workloads on a managed Auto Mode cluster.
- EC2 — virtual machines you fully control.
At a glance
Section titled “At a glance”| Lambda | ECS | EKS | EC2 | |
|---|---|---|---|---|
| Execution model | Per-request, event-driven | Always-on containers | Kubernetes objects (Deployments, Jobs) | Always-on machine |
| Cost shape | Pay per invocation; scales to zero | Pay per running task | Control plane + Auto Mode nodes | Pay per running instance |
| Startup | Cold starts (ms–s), then warm | Task launch (tens of seconds), then steady | Cluster create (~10 min), Pods in seconds | Instance boot (minutes), then steady |
| Packaging | Bundled zip (Rolldown) | Docker image, built + pushed for you | Docker image, built + pushed for you | Bundled program on an AMI you choose |
| Networking | None required (Function URL) | VPC required (awsvpc), optional ALB | VPC required, LoadBalancer Services |
VPC required, you own every primitive |
| Alchemy coverage | Fully documented | Cluster/Service/Task resources | Cluster/Deployment/Job/Manifest/Helm | Instance + full VPC primitives |
Lambda — the default
Section titled “Lambda — the default”Serverless, event-driven, and the runtime this documentation is
written around. You get the Function
resource with a public Function URL, typed bindings that mint
least-privilege IAM policies from your call sites, and
Stream-shaped event sources for SQS, Kinesis, DynamoDB
Streams, S3 notifications, SNS, and EventBridge. Cold starts and
the 15-minute execution cap are the trade; per-request pricing
and zero idle cost are the payoff.
Choose Lambda unless you have a specific reason not to.
→ Lambda
ECS — long-running containers
Section titled “ECS — long-running containers”When your workload doesn’t fit a request/response window — a WebSocket server, a worker that holds connections open, anything that should be always-on — run it as a container. Alchemy models ECS with three resources:
Cluster— an ECS cluster for running tasks and services.Task— bundles an inline Effect program, builds and pushes a Docker image to a generated ECR repository, provisions task + execution IAM roles and a CloudWatch log group, and registers a Fargate task definition. Tasks can serve HTTP directly and accept the same binding contract (env + IAM policy statements) as Lambda.Service— keeps a task definition running with awsvpc networking; setpublic: trueand Alchemy provisions a public ALB + listener + target group for you.
You pay for running tasks whether or not they’re serving
traffic, and you bring a VPC (subnets + security groups) — the
Network helper builds one in a
single call.
→ ECS
EKS — when your platform is Kubernetes
Section titled “EKS — when your platform is Kubernetes”When the workload is container-shaped but you want Kubernetes itself — Helm charts, operators, raw manifests, or teams already speaking Deployments and Jobs — Alchemy targets EKS Auto Mode, where AWS manages the control plane, nodes, storage, and load-balancer integration. Alchemy models it with:
Cluster— the control plane;compute: "auto"turns on Auto Mode with sensible defaults.Deployment— a replicated Kubernetes server (the Kubernetes analog ofAWS.ECS.Service) with the same three image sources as ECS: a registryimage, a Dockerfilecontext, or an inline Effect program viamain.Job— run-to-completion work, or aCronJobwhen you setschedule.ManifestandHelmChart— any raw Kubernetes object or a rendered Helm chart, applied via server-side apply.
Bindings work the same as on Lambda and ECS — env vars plus IAM
policy statements, delivered through an EKS Pod Identity role —
and there is no YAML and no kubectl step. You pay for the
control plane and the nodes Auto Mode provisions, you bring a VPC
(the Network helper builds one),
and the control plane takes ~10 minutes to create.
→ EKS
For ML training fleets specifically — persistent, health-checked
GPU clusters rather than application containers — EKS pairs with
SageMaker HyperPod: the HyperPod nodes
join your EKS cluster, and Deployment/Job opt onto them with
the hyperpod prop.
EC2 — when you need the machine
Section titled “EC2 — when you need the machine”Full-control VMs for workloads that need an OS, a GPU, custom
daemons, or just predictable dedicated capacity. The
Instance resource can act as a
low-level compute primitive or run a bundled long-lived Effect
program directly on the machine (including serving HTTP), and
Alchemy ships the complete networking toolkit around it:
Vpc,
Subnet,
SecurityGroup, NAT and
internet gateways, route tables, EIPs, and VPC endpoints (see
VPC & networking).
You own patching, scaling, and availability.
→ EC2
Rule of thumb
Section titled “Rule of thumb”- Start with Lambda. Per-request cost, no servers, and the whole documented binding/event-source surface.
- Move a workload to ECS when it’s long-running, needs more than 15 minutes, or is already a container.
- Pick EKS over ECS when you want Kubernetes itself — Helm charts, operators, raw manifests — not just a container runner.
- Reach for EC2 when you need the machine itself — kernel access, GPUs, custom networking, or software that expects a host.
Where next
Section titled “Where next”- Lambda — deploy a function with a public URL.
- AWS overview — resources and recipes.
- Providers reference — generated docs for every ECS, EKS, and EC2 resource.