Judoscale on Tour: Render Has the Pieces, Not the Workflow

Jon Sully headshot

Jon Sully

@jon-sully
Note on AI use

Judoscale ‘On Tour’ Series

  1. “The Friction Model” & Heroku
  2. Render (This page!)
  3. Railway (Coming soon…)
  4. Fly (Coming soon…)
  5. Northflank (Coming soon…)
  6. Digital Ocean (Coming soon…)
  7. Amazon ECS Fargate (Coming soon…)

After about a month of migrating, tweaking, and configuring, our opinions are in! We successfully migrated our full production and staging application stacks to Render. We tried as many bells and whistles as we could, let things run for a non-trivial amount of time, and have some interesting thoughts to share with you.

👀 Note

The “Judoscale Tour” is our exploration of today’s PaaS offerings via deliberately migrating our real production app, our staging systems, and our development workflows to each of said offerings in sequence. It’s a big endeavor, but we want to know first-hand what each PaaS service on the market truly feels like. And we want to relay that information to you with receipts! We outlined our strategy and rubric in our first edition, the more-reflective, “An Ode To Heroku”.

Illustration of the Render logo beside a single server rack emerging from stylized clouds.

Tl;dr:

There’s no need to make you wait if you want a quick conclusion: our thesis landed a little differently than we first thought, but in the same ballpark… Moving from Heroku to Render means you’ll probably save a good chunk of change (likely 30-40% depending on what types of Heroku Dynos you currently pay for and run), but Render isn’t as simple or easy as Heroku. You will trade some of your development and maintenance time for those infrastructure dollars. You will own more. Render has a few neat features, but it simply doesn’t nail the simplicity that Heroku’s always had. That’s our tl;dr. But there’s a lot of nuance there, so we’d encourage you to read on.

The Mental Model

Since The Judoscale Tour is all about exploring potential alternatives and migration paths away from Heroku, we want to preface our thoughts and results with a quick sidebar of how the mental model for a given platform might differ from Heroku’s. In the case of Render it’s… tricky. Heroku’s primitive object upon which everything is built is the “app” — a collection of processes which are themselves distinct (web, fast-worker, slow-worker, clock, etc.), but which collectively act together to make up an application. Render, on the other hand, took the path of the processes themselves being first-class citizens; top-level constructs they call “Services”. For sure, that allows for greater flexibility and control in how things operate together, but it also means that certain app-level lifecycle events are overlooked and have to be built / coordinated yourself. You’ll see what we mean as we go over some specifics here, but just understand that a collection of disparate services (which have no workflow connection to one another) can be annoying.

Illustration comparing two software architecture models. On the left, several small service-like characters sit together inside a single rounded container, with arrows converging toward a shared center to suggest one coordinated application. On the right, similar characters stand on separate platforms with crisscrossing arrows between them, conveying independently managed services and a more fragmented deployment model.
This image may be a little over-emphasized… having separate services isn’t as bad as it looks, and having a cohesive app isn’t all harmony!

Render: Shipping Friction

At the very outset, getting your first Render service configured and deployed will likely be pretty easy! The git-connected, just-pull-from-Github/Gitlab/Bitbucket flow feels very familiar. Render has prefab buildpacks, configs environment variables from the web UI, and takes you right to a metrics dashboard. Sounds very familiar 😆.

✅ Tip

Even though it’s not documented anywhere that we could find, Render’s Ruby buildpack does luckily include Jemalloc. Just use the super intuitive environment variable LD_PRELOAD = /usr/lib/x86_64-linux-gnu/libjemalloc.so.2. Duh! 🤦‍♂️🤦‍♂️

But your application is more than a single service! Building out additional services via the Render web UI is, again, straightforward, but you might shift toward making a Blueprint: a YAML file that declares the shapes and basic configs of all services within your repository (*cough* app). While it can feel nice to have many basics configured in code rather than freely changeable web UI, it introduced some confusion for us. Mostly anything we can configure in a Blueprint, we can also configure in the web UI… even though we made a Blueprint. For example, our Blueprint for our judoscale-prod-clock process contains a buildCommand of bundle install. And when I open that service in the web UI, I see the corresponding build command:

And you might say, “Well yeah, it’s just telling you what’s in your Blueprint!” But you’d be mistaken (as we were)! And you’ll also note there’s an “Edit” button. Yes, you can open that field and edit the build command from the web UI! So then which one actually runs? The Blueprint command or the web UI command? That’s a great question! 🙃

Nonetheless, the zero-to-running-in-prod workflow on Render is pretty seamless. We’re confident any Heroku-user could get up and running on Render smoothly. Shipping friction doesn’t only occur on day one, though. The day-to-day development and deployment cycles of teams matters much more than first-time workflows! And we have less than ideal impressions on that front, too.

Given Render’s “processes are the first class object” model, each ‘service’ manages its own deployment lifecycle independent of others.

This is easy to understand when we think back to how Heroku handles deploys: there’s a single build that sets up the final “slug” for that deploy, a “release” step which executes, and a final rollout of the slug to all processes in the Procfile if the release step completes. Render simply doesn’t have this multi-process coordination out of the box. When running Render’s simple “deploy from Git” style strategy, each service receives its own notice that there’s a new commit to deploy. Each service then executes its own full build. Then each service attempts to run the pre-deploy command, then finally roll out its built code.

Illustration of four independent deployment pipelines. A single cloud at the top sends updates to four separate services, each shown with its own laptop, build conveyor, and rocket launch. The repeated parallel workflows emphasize that every service builds and deploys independently rather than sharing one coordinated application release.

That has two main hiccups we care about: first (though Adam and I disagree on how big of a deal it is 🤭) it’s not ideal that each service has its own build artifacts generated. Should they result in the same actual files? Yes, probably. But can things happen? For sure. Second, and more importantly, if the pre-deploy step fails for Service A, it doesn’t halt anything for Service B. Service B may still deploy its updated code while Service A does not. There’s no unified “app”-level halt for release-step failures. Which makes me think it’s only a matter of time before my services end up running different versions of the codebase at the same time 😱.

Thus, Render makes it easy to deploy services, but it did not make it easy to deploy Judoscale. We ended up constructing some Github Actions-based hackery to coordinate our builds and deploys across multiple services… none of it was particularly elegant. Coming from Heroku, where we didn’t have to do any of that, we didn’t love it 😕

Our grade for Render on Shipping Friction: C. There is friction and you will feel it when coming from Heroku.

Render: Debugging Friction

Pivoting over to a brighter outlook, Render’s facilities and tooling for debugging are actually pretty great! Where Heroku’s metrics charts are quite limited (and dated), its log tooling is essentially “view it in real time or plug in a log drain”, and its dashboard leaves something to be desired in terms of “how are things right now?”, Render solves many of these.

Render natively stores logs on your behalf for varying degrees of time (depending on your machine tier):

That’s pretty nice! We’d still recommend that serious production apps plug in a more comprehensive logging and dashboard/data tool, but it’s fantastic that Render itself can serve as a logs backup or even a simple debugging interface for smaller and/or less needy apps.

Render’s metrics charts aren’t especially comprehensive, but they win marks for having many different spans of time with which you can view them. From last-30-days to last-30-minutes, and just about everything in between. Going further, Render also supports OTel, so you can ship your metrics data off wherever you prefer with relative ease.

Screenshot of the Render application dashboard UI with the timespan selector for the metrics data open. Many options are shown, ranging from “Last 30 min” to “Last 30 days” and “Custom”

Now, it’s not all roses and daisies — you end up coping with the disparate services issue even in some of the observability tooling (e.g. “give me the average CPU load across web AND worker-fast AND worker-slow” etc. in every query…), but that per-service breakdown can occasionally be useful too.

Render just feels like a more modern Heroku in this area. Where Heroku has log drains, Render has metrics streams, OTel, their own logs, and more flexible log delivery mechanisms. We wish we had some of that on Heroku!

But if we’re talking about debugging friction, we need to talk about Render‘s support workflow as well. The “submit a ticket” kind…

❗ Important

To be sure, I’m fully aware that the comparison is to Heroku/Salesforce support, which is possibly the worst of all hosting companies. The bar is very low here.

Still, we found Render’s support workflow to be just ‘okay’. Email responses were on the order of (multiple) days and we got better support latency from their web chat widget, which feels distinctly less ‘professional’. Again, compared to Heroku it’s great, but still. It’s not an A+ experience.

Finally, the last note to make about Render’s debugging workflow is with production console access. There is no Render-parallel for Heroku’s interactive “one-off” dynos (don’t be confused by Render’s “one-off jobs”, those are fundamentally different!). Instead, you’re expected to hop into a production instance via SSH into one of your active service machines. As an autoscaling company, our first thought is, “Well what if you’re on a prod box and your autoscaler scales down that box…?” but TBD there. More critically, this workflow requires much more care and thought around system resources when taking production actions. Ever tried to execute something on a Heroku one-off dyno only for the connection to just die, then later realize that’s because you were spiking the memory way beyond what the default one-off dyno has available? Now think about doing that on your active web server. Whoops, that’s downtime!

It’s not necessarily a problem or a bad thing, it’s just something to be aware of and cautious about with production access on Render. You’re working on a live, hot machine. Work with caution!

All in all, we’re going to give Render a grade of A- for debugging friction. Render gives you much better windows into production than Heroku does, but also less-safe doors. 😜

Render: Infrastructure Friction

We’ve already talked a bit above about the “service” vs. “app” primitive creating some friction when it comes to shipping in particular. But as we look at infrastructure as a whole, we find that this primitive difference ultimately means there are just more things to model, more things to keep track of, and more choices to make.

Illustration of a cloud storing application environment variables. A locked configuration panel sits inside the cloud, with dotted lines connecting it to several different application components below, representing centralized storage and distribution of shared configuration and secrets.

Let’s start with environment variables. Heroku keeps environment variables at the “app” level — one place for all ENV vars for the app, and all processes can read them. Since there is no “app” in Render, environment variables are configured at the service level. Ordinarily that’d mean duplicating all of your ENV vars across all of your app’s processes, but Render does offer “Environment Groups” that can be shared across many services, but it’s extra layering to keep in mind.

While we’ve got “environment” on the mind, we must also note that Render made a terrible naming choice in calling their environment variable sharing system “environment groups” while also creating a wholly different feature set generally called an “environment” that’s totally different (grouping multiple services together to call “staging” or “production”). A Render ‘environment’ is a thin facsimile of Heroku’s “app” abstraction while confusing the word “environment” in the Render ecosystem to begin with.

On the plus side, domain management and SSL provisioning were largely painless, autoscaling worked excellently (one should hope!), and actual system performance was quite good. While Render’s Standard tier is not a perfect analog for Heroku’s Std-2x, their general performance has increased compared to the last time we took a hard look at Render. At this point, we found their CPU provisioning to be fairly true to their marketing, which is awesome.

Here’s a rough resource mapping we landed on after several trials:

“A comparison chart contrasts Heroku and Render hosting plans side by side. On the left, Heroku tiers are shown as Std-1x (1 core, 0.5 GB RAM, $25/month), Std-2x (2 cores, 1 GB RAM, $50/month), Perf-M (2 cores, 2.5 GB RAM, $250/month), and Perf-L (8 cores, 14 GB RAM, $500/month). On the right, Render tiers are Standard (1 core, 2 GB RAM, $25/month), Pro (2 cores, 4 GB RAM, $85/month), Pro Plus (4 cores, 8 GB RAM, $175/month), and Pro Ultra (8 cores, 32 GB RAM, $450/month). Arrows connect roughly equivalent tiers, with handwritten notes highlighting that Render generally offers substantially more RAM at similar or lower prices, more granular scaling options, and a dedicated CPU core at the entry level. The overall message is that Render provides more hardware resources per dollar than comparable Heroku plans.”

👀 Note

The chart above is our experience, and opinion, based mapping for how teams might migrate to Render from Heroku’s resource classes. Your mileage may vary!

*Heroku doesn’t reveal how many ‘actual’ cores you get on their hardware tiers, even for their dedicated (“Performance”) dynos. These core counts reflect our experience over the years and general recommendations, especially when considering Heroku’s noisy neighbors problems…

Given Render’s and Heroku’s different resource-size tiers, this isn’t a story of “Render is faster” or “Render is cheaper” — it’s not that simple and it will depend on the specific app’s needs. But what we can say is that Render offers more granular resource choices for all apps and, on average, we believe that most teams will save between 30-40% on their compute costs* when moving to Render while keeping the same net total horsepower. Particularly for those apps currently running on Heroku’s Perf-M’s. Render’s Pro tier is a serious savings for similar horsepower there.

*We’ll get to overall costs in the next section; we’re just talking about the service machine costs here!

All that said, we’re going to give Render a solid B here. Where Heroku hides more infrastructure shape and details, Render exposes those details but does give you the tools to manage them well.

Render: Organizational Friction

So, as noted above, we do believe that most teams will save 30-40% on their compute costs on Render. We’re saying that again because that is a massive deal. But now we need to talk about the other costs, because those can also be massive…

The big elephant in the room for us is egress costs. Render bills for egress bandwidth. How much egress bandwidth does your app currently use? How much should you expect Render to charge you for it? Great question! We don’t know. Not a single team we’ve asked or know can answer “Hey how much outbound bandwidth does your app use each month?”. Because it’s a question nobody’s asking and nobody’s measuring!

👀 Note

It’s worth noting that, as far as we know, Heroku is actually the only platform that doesn’t charge for bandwidth in some manner or form. But that doesn’t mean every other platform’s measurements or prices are the same!

That said, our general take is this: if you’re going to use Render’s own services for database and/or cache (e.g. Postgres and Redis), you’ll probably be fine with Render’s built-in (free) egress allocations:

However, if you’re using third-party services for database, cache, or otherwise, we wouldn’t recommend using Render for your compute hosting. Unless you can get Render’s VPC/Private Link architecture going for your services (we could not) you will almost definitely hit the free egress allocation for your account. And you might blow WAY past it.

Just being transparent, the month before we moved Judoscale to Render, our Heroku bill was ~$700. The month that we spent on Render, our bill was ~$4,500. A full $4,000 of that was just egress fees. Ouch, ouch, ouch. We use Timescale DB (now “Tiger Data”) and can’t set up a private link for that service with Render.

Illustrated bar chart comparing hosting costs. A single bar labeled “Price on Heroku” reaches $700. Next to it, a much taller stacked bar labeled “Price on Render” totals $4,500, with a small $500 compute section at the bottom and a much larger $4,000 egress section above it, illustrating that bandwidth charges make up the vast majority of the total cost.

So Render may well cut your compute bill down a fair amount, but if you run external services, you may rack up another bill you didn’t expect.

Lastly, Render’s pricing model itself is a little funky. It’s changing on August 1st, but before then, there’s a per-seat cost in addition to your actual compute (and egress) costs. We’re not fans of a per-seat model. After August 1st, 2026 the per-seat model is largely disappearing, but you end up either paying $25/mo flat-rate for the whole account while having only 25GB of egress bandwidth for the month, OR $499/mo flat-rate for the whole account while having 1TB of egress bandwidth. $500/mo before compute costs is wild to us, but egress becomes an even more important discussion point if you opt for their $25/mo “Pro” plan. Clear as mud!

For all of these reasons, and understanding that our egress may be an outlier in the community, we give Render a C for organizational friction. Egress costs are just not intuitive or easy to reason about, and their upcoming account billing structure is frankly frustrating.

👀 Note

We built a PaaS Pricing Calculator last year to help you understand what equivalent costs are across platforms, including comparing Heroku to Render. It can help you estimate high-level egress values, too!

Screenshot of the PaaS Pricing Comparison Calculator

So…. Render?

Render:

  • Shipping Friction: C
  • Debugging Friction: A-
  • Infrastructure Friction: B
  • Organizational Friction: C

So where does this all leave us? Render is absolutely a viable Heroku alternative, but it is not simply “Heroku, only cheaper”. Render’s primitive is the service, not the app, and that mental model shows up everywhere: deploys, migrations, environment variables, dashboards, domains, scaling, and billing. Render gives you more knobs, better built-in observability, useful infra-as-code tooling, and potentially (much) cheaper compute. But in exchange, you own more of the connective tissue that Heroku just handled for you.

For many teams, that tradeoff will be worth it. If your app is fairly standard — web, workers, Render-managed Postgres/Redis, modest outbound traffic — Render may save you a meaningful amount of money while giving you a more modern dashboard and better native debugging tools. But if your app uses third-party data services, pushes lots of outbound traffic, or needs tightly coordinated multi-service deploys, the savings may be eaten by workflow complexity or egress fees.

That’s probably our shortest verdict: Render had the pieces, but Heroku had the workflow. Render is more flexible, more observable, and often cheaper. It is also more service-shaped, more fragmented, and more likely to make you design the application-level lifecycle Heroku gave you for free. Fewer infrastructure dollars, more infrastructure ownership.

✅ Tip

Reminder: This article is the second post in our “Judoscale going on tour” series, where we put our money where our mouth is and migrate Judoscale to various platforms. No holding back, no keeping background jobs somewhere else, no splitting traffic.

Judoscale is a 24/7 real-time reactive production application. We receive well over 3,000 RPS every moment of every day. Our downtime is exceedingly rare (generally only when Cloudflare or Heroku themselves have issues), but then, it darn well should be! We’re an autoscaler! We need to be online, regardless of traffic load, so that we can reactively scale our clients’ applications correctly and appropriately any time of day.

Sign up for our newsletter to join us on this tour as we discover the nooks and crannies of 2026’s available PaaS’s. If you’ve been thinking about moving, let us feel the pain first — we’ll tell you all about it 😆.