Skip to content

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.
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

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

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; set public: true and 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

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 of AWS.ECS.Service) with the same three image sources as ECS: a registry image, a Dockerfile context, or an inline Effect program via main.
  • Job — run-to-completion work, or a CronJob when you set schedule.
  • Manifest and HelmChart — 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.

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

  1. Start with Lambda. Per-request cost, no servers, and the whole documented binding/event-source surface.
  2. Move a workload to ECS when it’s long-running, needs more than 15 minutes, or is already a container.
  3. Pick EKS over ECS when you want Kubernetes itself — Helm charts, operators, raw manifests — not just a container runner.
  4. Reach for EC2 when you need the machine itself — kernel access, GPUs, custom networking, or software that expects a host.