# A Heroku alternative that runs in your own AWS account

> Keep the Heroku workflow (git push, preview envs, managed Postgres) in an AWS account you own. Here's how teams do it and what changes when they do.

- **Published:** 2026-03-21
- **Author:** Ownkube team
- **Category:** Engineering
- **Tags:** heroku-alternative, aws, paas, platform-engineering
- **Canonical URL:** https://ownkube.io/blog/heroku-alternative-in-your-own-aws-account
- **Cover:** https://ownkube.io/blog/hello-ownkube.png

---
Somewhere around your third production incident on [Heroku](https://www.heroku.com), whether it's the 2 AM dyno that OOM-killed with no explanation or the compliance officer who asked where customer data actually lives, you start pricing alternatives.

For most teams we talk to, the honest answer isn't "move to [Render](https://render.com)" or "move to [Railway](https://railway.com)." Those are lateral moves. Same shared infrastructure, same markup, same awkward conversation with your auditor next quarter. The real answer is: keep the workflow you loved (git push, addons, review apps, one mental model), but run it inside an AWS account you own.

That's what this post is about. Specifically: how teams replace each piece of the Heroku experience with something that lives in their own VPC, what they keep, what they trade away, and the two reference architectures that actually work. If you're trying to compare PaaS-to-PaaS instead, we have a separate post on [Render vs your own AWS account](/blog/render-vs-aws-own-account); if you're trying to ship on AWS without hiring a platform engineer, [start here](/blog/deploy-on-aws-without-devops-engineer).

## What people loved about Heroku in the first place

It's worth stating plainly, because a lot of the industry has forgotten. Heroku was good. For a long time, it was the best developer experience in the business. You pushed git, you got a URL, you could add a Postgres, and you could go back to writing the product.

Specifically, what made it special:

- **Git push as a deploy primitive.** No build server to babysit, no container registry to configure. The VCS was the API.
- **Opinionated defaults.** You didn't pick a base image or a log driver. Someone else had already argued about those so you didn't have to.
- **Managed datastores without a ticket.** `heroku addons:create heroku-postgresql` and you had a production DB with backups in 30 seconds.
- **Review apps.** Every PR got a URL. Designers reviewed real builds. Sales demoed features that hadn't merged yet.
- **A single mental model.** Dynos, add-ons, releases. A new engineer was productive in an afternoon.

That package (velocity without decision fatigue) is what teams actually miss when they leave. They don't miss Heroku. They miss that shape of platform.

## Why teams leave shared PaaS anyway

Nobody leaves Heroku because they stopped liking it. They leave because it stops fitting.

**The bill stops making sense.** A 2x Performance-L dyno runs around $500/month on Heroku's published rates (April 2026). The equivalent on bare EC2 is closer to $150. On a small app the delta is a rounding error; on a growing app it's a full engineering hire.

**Compliance conversations get harder.** When your customer's security review asks where their data is processed, "Salesforce-owned shared infrastructure" is a slower answer than "our VPC in us-east-1." SOC 2, HIPAA, and most enterprise procurement forms want the second one.

**Your AWS credits are stranded.** Funded startups often carry six figures of [AWS Activate](https://aws.amazon.com/activate/) credits sitting unused because their platform bills go somewhere else. That's runway you're setting on fire.

**You hit architectural ceilings.** Private networking to a data lake, GPU workers, [VPC peering](https://docs.aws.amazon.com/vpc/latest/peering/what-is-vpc-peering.html), long-running batch jobs, [spot instances](https://aws.amazon.com/ec2/spot/) for background work. These are either impossible or painful on shared PaaS. (If you're weighing Render specifically, we wrote up the tradeoffs in [Render vs your own AWS account](/blog/render-vs-aws-own-account).)

**The escape plan is the real problem.** Even if none of the above mattered today, the day you outgrow the platform you're stuck rewriting how every service deploys, how every secret is injected, how every cron runs. There's no graceful exit.

So teams start sketching an alternative. And the sketch is almost always the same: _give me Heroku, but running in an AWS account I control._

## What actually changes when the account is yours

This is the part that gets glossed over in most comparison posts. Owning the AWS account is not a cosmetic change. It changes five concrete things.

**1. The data never leaves your perimeter.** Your Postgres, your object storage, your Redis, all provisioned in your VPC, in your region, under your KMS keys. Auditors stop asking follow-up questions. DPAs get shorter.

**2. You pay wholesale.** There's no per-dyno markup between you and EC2. A c7g.large is a c7g.large. Savings Plans apply. Spot applies. Credits apply. The unit economics look like an AWS bill because they are one.

**3. You inherit AWS's surface area.** Need a private link to an RDS instance a customer gave you access to? Fine. Need a specific instance family for a vendor's licensing? Fine. You're no longer constrained to the intersection of features your PaaS happened to expose.

**4. The exit is free.** If you decide to replace the platform layer, the workloads don't move. The databases don't move. The DNS doesn't move. You're disconnecting a control plane, not migrating.

**5. You become the operator.** This is the honest downside. Someone has to patch nodes, rotate certs, upgrade the orchestrator, watch for CVEs. The whole point of a Heroku-style platform in your own AWS account is to make that someone a piece of software, not a team of three.

## Two reference architectures: start small, scale later

Ownkube ships in two modes, and the right architecture depends on where your traffic and team size actually are today. Both are deliberately boring. We're not reinventing AWS, we're just making it feel like Heroku.

### Mode 1: k3s mode (the default for indie and small teams)

![Ownkube k3s-mode reference architecture on AWS: Cloudflare providing DNS, preview domain, and DDoS/bot/scrape protection, routing HTTPS traffic to a single k3s cluster on EC2 with managed Postgres on the same EC2 node, S3 for artifacts, Secrets Manager and CloudWatch, driven by the Ownkube SaaS control plane outside the customer account.](/diagrams/heroku-alternative-reference.png)

This is the shape most teams land on first. Single k3s cluster, a handful of EC2 nodes (mixed spot + on-demand in an ASG), Postgres running on the same EC2 managed by Ownkube, S3 for artifacts. That's it.

**Why [k3s](https://k3s.io) here, not [EKS](https://aws.amazon.com/eks/).** EKS has a $73/month control-plane bill before you've launched a pod. k3s is a single binary, boots in seconds, has a smaller CVE footprint, and runs happily on t4g/c7g with 1 to 2 GB of RAM overhead per node. For indie developers, side projects, and small-team dev environments, k3s removes the AWS tax without removing real Kubernetes underneath. (Full technical comparison: [EKS vs k3s on AWS for startups](/blog/eks-vs-k3s-on-aws-for-startups).)

**Why Managed Postgres on your EC2, not [RDS](https://aws.amazon.com/rds/).** For low-traffic apps, RDS is a tax. A db.t4g.micro RDS instance starts at about $12/month; the equivalent Postgres colocated on an EC2 node you're already paying for is free on top of the compute. Ownkube operates it like a managed service (backups, PITR, failover) but the bytes sit on your EBS volumes. When the workload grows past what one box can carry, you flip to RDS with one click. No migration tooling required.

**Why not [ECS](https://aws.amazon.com/ecs/).** ECS is tempting because it's "simpler than Kubernetes," but the simplicity is bought with lock-in. Task definitions, services, and the deploy model are AWS-proprietary: no portable API, no `kubectl` anywhere else, and none of the Kubernetes ecosystem (Helm, operators, ingress controllers) transfers. The day you want to move a workload to another cloud or another account, you rewrite every manifest. That's the exact opposite of the portability we're optimizing for here. k3s gives you most of ECS's operational simplicity without the one-way door.

**Why a mixed ASG.** Stateless web workloads and background jobs run on spot by default, with on-demand capacity reserved for the Postgres node. For most apps this takes 40 to 70% off the compute bill without any code changes.

### Mode 2: EKS mode (the scale tier)

Once you're past a single-node workload (multi-AZ uptime requirements, multiple teams deploying in parallel, heavy observability needs, or enterprise procurement asking about managed control planes), Ownkube flips the same application into EKS mode. Same git push, same preview URLs, same Cloudflare-backed domain. Different substrate.

![Ownkube EKS-mode reference architecture on AWS: Cloudflare handling DNS, custom and preview domains, plus DDoS/bot/scrape protection, routing HTTPS through an ALB into a multi-AZ EKS cluster with managed control plane and spot + on-demand node groups, backed by managed RDS Postgres (Multi-AZ, PITR), ElastiCache, S3, Secrets Manager (IRSA), and CloudWatch/OTel, all driven by the Ownkube SaaS control plane outside the customer account.](/diagrams/heroku-alternative-eks-scale.png)

The upgrade is additive, not a rewrite: EKS replaces k3s, RDS + ElastiCache replace the in-cluster Postgres, an ALB sits in front of Cloudflare's edge, and CloudWatch + OTel get wired in end-to-end. Secrets Manager uses [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) for workload identity. You keep your application manifests.

**Why the control plane is split.** In both modes, the Ownkube control plane (the thing that shows you deploys, handles git pushes, orchestrates previews) lives in our SaaS. It holds no application data, no database credentials, no secrets. Everything that actually matters runs in your account. If our control plane disappeared tomorrow, your apps would keep serving traffic.

## Why Cloudflare, not Route 53

A detail worth calling out: the ingress layer in both modes is [Cloudflare](https://www.cloudflare.com), not [Route 53](https://aws.amazon.com/route53/). This is a deliberate choice and it's one of the reasons the developer experience feels closer to Heroku than to raw AWS.

**You don't set up DNS.** When you connect an AWS account, Ownkube provisions a subdomain on a Cloudflare zone we operate, something like `your-app.ownkube.app`. Your preview environments get their own hostnames under it. You can send those URLs to customers, teammates, or stakeholders the same afternoon you connect your cloud. No domain purchase, no nameserver hand-off, no "waiting for DNS to propagate." You can attach your own custom domain whenever you're ready.

**You get an edge WAF for free.** Cloudflare's free tier includes DDoS protection, bot fight mode, and scrape protection. For an indie developer whose first viral launch is a real risk factor, that's meaningful. You inherit a CDN with unmetered mitigation before you've written a single security rule. On raw AWS, the equivalent is [Shield](https://aws.amazon.com/shield/) + [WAF](https://aws.amazon.com/waf/), and the bill shows up on the first invoice.

**TLS stops being your problem.** Cloudflare terminates TLS at the edge with managed certificates that rotate automatically. In k3s mode we run a simple HTTP listener inside the VPC and let Cloudflare handle public-facing TLS; in EKS mode the ALB terminates a second time with ACM for strict-origin validation. Either way, no cert-manager pager alerts on a Sunday.

Route 53 is still the right answer for some teams (if you're already committed to AWS-native DNS for Route 53 health checks, private hosted zones for internal service discovery, or complex failover routing), and Ownkube won't stop you from bringing your own zone. But for most teams, the first-month question "where do I put my DNS?" doesn't need to be a decision. Cloudflare is the answer, it's free, and it's already wired up.

The workflow on top of this is the part that should feel familiar. Connect a repo. A push to `main` triggers a build. The resulting image is promoted through environments. A pull request spins up a preview with its own DB fork and its own subdomain, and tears down on merge. Logs, metrics, and errors flow into one place. Secrets are injected at runtime from Secrets Manager. Nobody on your team writes a deployment manifest.

## Who this setup is actually for

Be honest about this, because the wrong fit is expensive for everyone.

**This is a strong fit if:**

- You have 10 to 100 engineers and a growing AWS bill.
- You've outgrown (or are about to outgrow) Heroku, Render, or Railway on cost, compliance, or capability.
- You have AWS credits you want to use.
- You don't have a dedicated platform team and don't plan to hire one for another 12 to 24 months.
- You care about portability. You want the option to walk away from any vendor, including us, without rewriting your deployment story.

**This is probably not a fit if:**

- You're a solo developer or pre-PMF team shipping a weekend project. Heroku or Railway will get you there faster.
- You already have a mature internal platform team with strong opinions. You don't need us; you need [Crossplane](https://www.crossplane.io/) and time.
- You require on-prem or sovereign cloud deployments today. We're AWS-first, with GCP and Azure coming.
- Your workload isn't web-shaped (heavy HPC, low-latency trading, specialized hardware). Those deserve a purpose-built stack.

If you're in the sweet spot, the calculus is usually straightforward: the platform costs less than one platform engineer, gets you back to a Heroku-shaped workflow, and leaves the infrastructure in your name.

## Where Ownkube fits

You can build the architecture above yourself. People do. It takes six to twelve months, one to three senior engineers, and ongoing maintenance that never really ends. That's a reasonable choice if platform engineering is a strategic moat for your business.

For everyone else, Ownkube is that architecture, turned into a product. You connect an AWS account, we bootstrap k3s and the supporting services, and you get the Heroku workflow (git push, managed Postgres, preview environments, autoscaling, cost controls) running on infrastructure you own. The Incident, Cost, and Scaling agents cover the parts nobody enjoys: translating crashloops into plain English, catching memory leaks before they page someone, flagging cost anomalies the day they start.

Pricing (as of April 2026) is free for teams on k3s mode for indie builders and small-team dev environments, and $5/vCPU/month plus $1/GB RAM/month on EKS mode when you scale. Your AWS bill goes to AWS, at AWS rates, with your credits applied. No markup on compute, no call-us-for-a-quote pages, and on k3s mode every dollar of AWS Activate credit applies straight to wholesale EC2.

If you've been sketching this architecture on a whiteboard for a quarter, or you're one Heroku invoice away from forcing the conversation with your CTO, [connect your cloud](https://app.ownkube.io/signup) and deploy your first app. Fifteen minutes, and the infrastructure is yours on the other side of it.