# Elements vs AWS Amazon Web Services (AWS) is Amazon's cloud computing business, launched in 2006. It offers more than 200 services from data centers around the world. The foundational one is EC2, which rents virtual servers in hundreds of instance types, with Linux instances billed by the second. Other widely used services include S3 for file storage, RDS for managed databases such as PostgreSQL, Lambda for running functions without managing a server, Amplify for building and hosting web apps from a Git repository, CloudFront as a CDN, SES for sending email, Route 53 for DNS, and CloudWatch for monitoring. Lightsail sells simpler bundled servers at a fixed monthly price. Most AWS services are billed by usage: server time, storage, requests and data transfer. Elements is not a cloud provider. It is an integrated app environment for building web apps, built for people and their agents: one coherent system that includes a project server that runs while you work, a default app framework, a package installer, a test runner, a bundled Postgres database, and a deploy command. It deploys to any Ubuntu server you reach over SSH, and an EC2 instance is one. Elements charges for that tooling, per machine, and meters nothing ([pricing](/pricing)). Together, EC2 and Elements give you an app platform built from parts you control. On a bare EC2 instance, Elements sets up everything the app needs: Postgres, a job worker, a load balancer and HTTPS certificates. There is no web server, certificate tool, process manager, container image or deploy pipeline to assemble. The AWS services you choose, such as RDS, CloudFront and SES, connect through configuration, and the rest stay off the bill. ## Elements Runs Your App on One EC2 Instance AWS describes an EC2 instance as ["a virtual server in the AWS Cloud"](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html), and Elements deploys to [any Ubuntu server you can reach over SSH](/learn/man/deploy/setup). In the instance's security group, open port 22 for SSH, which deploys use, and ports 80 and 443 for the load balancer. Port 80 must stay open: the load balancer answers Let's Encrypt there when it gets or renews a certificate ([load balancer](/learn/man/deploy/load-balancer)). The first deploy installs Elements on the instance and brings up the app, the job worker, the load balancer and Postgres in a few seconds ([what deploy does](/learn/man/deploy/what-happens)). What you do not set up: nginx, certbot, pm2 or systemd units, a Docker image, CodeDeploy, or a CI workflow. Later deploys are fast because both ends keep their build state. The project server on your machine holds the build graph and build state in memory. It builds in milliseconds and answers agents and humans in microseconds. The instance runs the same project server, and `elements deploy` sends it only the files that changed, so a deploy often finishes in under a second ([deploy](/learn/man/deploy)). The app's tests run on the instance before the new release goes live, and the deploy either succeeds entirely or fails entirely, leaving the previous release serving. `elements deploy -json` reports every step on every machine in one structured result, so a failed deploy is diagnosed without logging in. ## EC2 or Lightsail AWS rents servers in two ways, and Elements deploys to both the same way. EC2 lets you choose the [instance type, machine image, key pair, security group and disk](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html). Linux instances bill by the second ([EC2 pricing](https://aws.amazon.com/ec2/pricing/)), and a public IPv4 address is billed by the hour on top ([VPC pricing](https://aws.amazon.com/vpc/pricing/)). [Amazon Lightsail](https://aws.amazon.com/lightsail/) makes most of those choices for you. It sells bundled servers at a monthly price that includes disk and transfer, with larger bundles costing more ([Lightsail pricing](https://aws.amazon.com/lightsail/pricing/)). Lightsail is the quicker start. EC2 is the choice when you want a specific instance type or your own VPC. ## Elements Works with the AWS Services You Choose The breadth of AWS is what we admire most: a managed service for most jobs around an app, such as databases, a CDN, email and monitoring, with databases such as RDS in the same private network (VPC) as your instances. An Elements app needs none of them to start, because it brings its own database, load balancer and HTTPS. When you choose one, it connects through configuration: - **Database.** [Amazon RDS for PostgreSQL](https://aws.amazon.com/rds/postgresql/pricing/) offers automated backups, a standby copy in a second data center (Multi-AZ) and read replicas. Set `DB_HOST` and the other `DB_*` values in `production.env` to the RDS endpoint, and Elements connects over TLS and creates its databases on the first build ([database CLI](/learn/man/database/cli)). - **CDN.** CloudFront can serve the app's built JavaScript, CSS and image files. Set `build.assetUrl` in `config.jsoc` from an `ASSET_URL` variable holding the distribution's hostname, and have the distribution forward the `Host` header ([load balancer](/learn/man/deploy/load-balancer)). Each built file's URL carries a hash of its contents, so a deploy never needs an invalidation for them ([build](/learn/man/build)). - **Email.** Elements sends mail through any SMTP provider ([email](/learn/man/email)), and [Amazon SES has an SMTP interface](https://docs.aws.amazon.com/ses/latest/dg/send-email-smtp.html). - **Monitoring.** [CloudWatch](https://docs.aws.amazon.com/cloudwatch/) collects each instance's CPU, disk and network metrics and can alarm on them. ## More Instances Share One Database Each instance runs its own bundled Postgres by default, because the scaffolded `production.env` sets `DB_HOST=127.0.0.1` ([setup](/learn/man/deploy/setup)). That is a good fit for a prototype or an app on one instance. For several instances, or when you want automated backups and scaling, Elements recommends Amazon RDS: point `DB_HOST` at it and every instance works on the same data. Then add each instance's public and private IP addresses to `config.jsoc` and give your domain an `A` record for each. Every instance's load balancer round-robins requests among all of them and retries elsewhere when one fails ([load balancer](/learn/man/deploy/load-balancer)). Migrations run once, on the first instance. Route 53 health checks can add DNS failover on top. ## Lambda, Amplify and Container Services Are Not Needed Some AWS services overlap with Elements rather than fitting around it. Lambda is one. AWS says Lambda ["is designed for short-lived compute tasks that do not retain or rely upon state between invocations"](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-limits.html), with a 15 minute limit on each function invocation. An Elements app is a long-running server by design. It holds a connection open to each browser, so a message the app sends through Postgres reaches every page listening on that channel ([channel](/learn/man/channel)). Its job worker keeps the queue in Postgres, so a job enqueued inside a transaction commits with it ([jobs](/learn/man/jobs)). Amplify builds and hosts apps from Git, the same model as Vercel's platform. Elements already builds and deploys the app, so Amplify has nothing to add. [Elements vs Vercel](/vs/vercel) compares that model in full. Container services such as ECS, Fargate and App Runner are not needed either: Elements deploys and runs the app on the instance itself, with no image to build or registry to push to. ## Questions ### Can I deploy an Elements app to AWS EC2? Yes. Launch an Ubuntu instance, open ports 22, 80 and 443 in its security group, add its public IP address to config.jsoc, and run elements deploy. The first deploy installs Elements and sets up Postgres, the load balancer and HTTPS. ### Can I run an Elements app on AWS Lambda? No. An Elements app is a long-running server: it holds browser connections open and runs a Postgres listener and a job worker. Lambda is built for short-lived invocations that keep no state. Deploy to EC2 or Lightsail, where the app runs as the long-running server it is designed to be. ### Does Elements work with Amazon RDS? Yes. Set DB_HOST and the other DB_* values in production.env to the RDS endpoint. Elements connects over TLS and creates its databases on the first build; use Postgres 16 or newer. RDS is also how several instances share one database. ### How do I put CloudFront in front of an Elements app? Create a distribution with the app's load balancer as the origin and have it forward the Host header. Then set build.assetUrl in config.jsoc from an ASSET_URL variable holding the distribution's hostname, and deploy. Built asset URLs change when their contents do, so no invalidations are needed. ### Should I use EC2 or Lightsail for Elements? Elements deploys to both the same way, over SSH on Ubuntu. Lightsail bundles disk and transfer into one monthly price with fewer settings; EC2 gives you every instance type and your own VPC.