Most early-stage founders and indie hackers burn thousands of dollars every month on managed cloud services before they even find product-market fit. You see it constantly on technical forums: a seed-stage mobile app running a multi-node managed Kubernetes cluster, three separate managed database read replicas, and six enterprise SaaS monitoring add-ons. The monthly AWS bill lands at $1,800. The active daily user count sits at 40 people.
When I started setting up the infrastructure for FitLyfe, a real-time nutrition and calorie tracking service, I set a strict personal constraint. Keep the core infrastructure under one dollar per day without sacrificing deployment automation, security, or baseline uptime.
Today, that production workload runs reliably for exactly $0.64 per day. That comes out to less than $20 a month. Here is the full breakdown of how it works, what the numbers look like, how memory safeguards are configured, and the trade-offs you must accept if you choose this path.
#The Architecture Stack
The entire stack runs on a single AWS EC2 t4g.small instance in the us-east-1 region. That gives us 2 vCPUs built on AWS Graviton2 (ARM64 architecture) and 2 GB of memory.
Instead of full-blown Kubernetes, which would choke and exhaust that memory pool before running a single application pod, I deployed K3s. K3s is Rancher's lightweight, certified Kubernetes distribution packaged as a single binary under 100 megabytes. It replaces heavy etcd clusters with an embedded SQLite database by default, reducing memory overhead to around 500 megabytes.
Here is what runs inside that single K3s cluster:
- Ingress Controller: Traefik, which ships bundled with K3s, handling SSL termination via Let's Encrypt automated certificates.
- Backend API: Go microservice running inside an optimized scratch container consuming less than 40 MB of RAM.
- Database: PostgreSQL container with a persistent volume mounted to an encrypted Amazon EBS gp3 volume.
- Cache & Queue: Redis Alpine container for session caching and transient rate limiting.
- Backups: A scheduled cron job that dumps the database, encrypts the file, and ships it directly to Amazon S3 Standard-Infrequent Access.
Here is the systemd service definition used to launch K3s with minimal resource usage:
# /etc/systemd/system/k3s.service.env
# Disable unused bundled components to save memory
K3S_KUBECONFIG_MODE="644"
INSTALL_K3S_EXEC="--disable servicelb --disable local-storage --flannel-backend=host-gw"#The Exact Daily Math ($0.64 Breakdown)
Cloud pricing is not magic; it is simple arithmetic. Here is the exact daily expenditure based on real AWS billing reports:
- 1EC2 Compute (t4g.small, 1-year Savings Plan): $0.0168 per hour * 24 hours = $0.4032 / day
- 2EBS Storage (20 GB gp3 volume): $0.08 per GB-month = $0.0533 / day
- 3Egress & S3 Backups (Compressed daily dumps + CloudFront CDN cache hits): $0.0620 / day
- 4Route 53 Hosted Zone (prorated across 30 days): $0.0166 / day
- 5Elastic IP: Free while attached to a running instance = $0.00 / day
Sum total: $0.5351 base compute + $0.105 buffer for network spikes = $0.64 / day.
#Memory Safeguards: The ZRAM and Swap Strategy
When you operate on an instance with only 2 GB of physical RAM, a sudden spike in traffic or an unexpected memory leak can trigger the Linux Out of Memory (OOM) killer. If the kernel panics, your database or API pod gets terminated instantly.
To prevent sudden OOM termination without paying AWS for an instance tier upgrade, I implemented a compressed in-memory swap system using zram, backed by a small swap file on disk:
# Configure compressed in-memory zram swap
sudo apt-get install -y zram-tools
echo -e "ALGO=zstd\nPERCENT=50" | sudo tee /etc/default/zramswap
sudo systemctl restart zramswap
# Configure Linux kernel swappiness to favor zram
sudo sysctl vm.swappiness=60
sudo sysctl vm.vfs_cache_pressure=50The zram module creates a virtual block device in RAM that compresses memory pages on the fly using Zstandard (zstd) compression. This effectively doubles the usable memory pool from 2 GB to nearly 3.5 GB of practical memory capacity with virtually zero latency penalty. Heavy analytics queries that would have crashed the instance are handled smoothly.
#What Breaks and What Does Not
Let us be completely honest. Running production on a single node means you do not have high availability across multiple availability zones. If the underlying AWS hardware fails, the node reboots.
Here is what has broken in practice:
- Memory spikes during heavy report generation: Before configuring zram, a single bad query loading 50,000 meal records into memory triggered the Linux OOM killer. The kernel killed the Go API pod. K3s restarted the container within 3.5 seconds. The user saw a single failed request and hit retry. I solved this by adding strict memory requests and limits to the Kubernetes pod spec, and activating the zram swap partition described above.
- Disk space creep: Docker image layers and build artifacts gradually filled the 20 GB disk. I wrote a small nightly cron job running
crictl rmi --pruneto keep image storage pristine.
Here is what has never broken:
- Uptime: Over 14 consecutive months, the instance has maintained 99.92% uptime. AWS hardware degradation events are rare, and AWS sends scheduled maintenance notices days in advance.
- SSL Certificates: Cert-manager and Let's Encrypt have renewed four times seamlessly without manual intervention.
- Backups: S3 receives an encrypted PostgreSQL dump every night at 03:00 UTC.
Here is the automated backup verification script running inside our cron container:
#!/usr/bin/env bash
# Automated nightly backup and upload to Amazon S3
set -euo pipefail
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/tmp/backups"
FILENAME="fitlyfe_db_${TIMESTAMP}.sql.gz"
mkdir -p "$BACKUP_DIR"
pg_dump -h localhost -U postgres fitlyfe | gzip -9 > "${BACKUP_DIR}/${FILENAME}"
# Encrypt and upload directly to S3 Infrequent Access tier
aws s3 cp "${BACKUP_DIR}/${FILENAME}" "s3://fitlyfe-backups-secure/${FILENAME}" \
--storage-class STANDARD_IA \
--sse aws:kms
rm -f "${BACKUP_DIR}/${FILENAME}"
echo "Backup ${FILENAME} completed and uploaded successfully."#When Should You Graduate?
You should not stay on a $0.64 setup forever. There is a clear inflection point. When downtime costs you more than $100 per hour in lost revenue, or when you hire developers who need ephemeral staging branches, that is the day you migrate to AWS ECS Fargate or a managed multi-node cluster.
Until you reach that scale, do not let enterprise architecture blogs convince you that you need an enterprise cloud bill. Start lean, measure everything, and scale your spend only when user traction demands it.
