
Boring Hosting Is a Feature: How Notis Runs on Render
What actually runs on Render, the thirty-line relay that solved our static-IP problem, and why environment groups beat per-service configuration every time.
The best compliment you can pay a hosting provider is that you forgot it was there.
Notis runs on Render. I've been through the alternatives — the Kubernetes phase, the raw-VM phase, the platform-with-a-thousand-knobs phase — and for a founder-led product the thing I want from infrastructure is that it not become a second job.

What's actually running there
Notis is not one service, and the shape matters.
The Python/FastAPI backend owns the product: the agent loop, channel ingress and egress, tool dispatch, automations, billing logic. That's the core, and it lives on Render. Scheduled jobs — cleanup passes, notification sends, maintenance work — run there too.
Other things live elsewhere on purpose. The Next.js Portal is hosted where Next.js is happiest. Ephemeral Cloud Computer environments run on a sandbox provider built for exactly that. Render's honest job is the always-on part: services that need to be reachable, in a region we chose, with a deployment story that doesn't require a meeting.
Everything is in Frankfurt. That's not an aesthetic preference. Notis is operated by a Swiss company with mostly European users, and where the compute sits is part of the privacy answer — which is why Render appears by name in our Help Centre's platform providers overview with its certifications attached.
The static-IP problem, and the small service that solved it
My favourite thing we run on Render is thirty lines of config.
Several services Notis depends on — OpenAI and Composio among them — allowlist outbound IP addresses. Meanwhile, our Cloud Computer sandboxes are ephemeral by design and have no stable egress identity. Those two facts are incompatible.
The fix is a tiny relay hosted on Render: a stateless web service whose entire purpose is to give sandbox traffic an allowlisted static outbound address. Sandboxes dial in over a WebSocket, and the relay forwards only to an explicit list of destination hosts. Everything that doesn't need the allowlisted IP goes direct, because routing traffic through a hop you don't need is just a way to add latency and a failure mode.
It has no state and no disk, so it can redeploy and scale freely. It sits in Frankfurt because that's the region whose outbound addresses are on the allowlist — get that wrong and you'll spend an afternoon confused about why an allowlist isn't working.
It's a small thing. But it's exactly the kind of small thing that's trivial on a platform where spinning up a service is a YAML file, and a whole project on a platform where it's a cluster decision.

Configuration discipline
One practice I'd recommend to anyone on any platform: environment variables belong to a group, not to a service.
We manage config through shared environment groups, and the per-service variable list stays empty. That sounds pedantic. It prevents a specific, expensive failure: two services that are supposed to share a credential drifting apart because someone fixed one of them in a hurry at midnight.
With grouped config there's exactly one place a value lives. Rotating a key is one change. Auditing what's set is one list. And when a value is wrong, it's wrong everywhere at once, which is much easier to diagnose than wrong in one place.
It also makes the config machine-readable in a useful way — I can check group state through the API rather than clicking through a dashboard, which means a coding agent can verify configuration as part of a task instead of asking me to look.
Why not go cheaper or lower-level
I could run this on plain VMs for less money. I've done it. Here's what that actually buys you: base image maintenance, security patching, a deploy pipeline you wrote, log aggregation you wired up, health checks you tuned, and a pager that is you.
For a team of my size, the correct question isn't "what's the cheapest compute." It's "what's the cheapest compute including the hours." Those hours are the scarcest input in the whole company, and they're much better spent on the agent behaving well than on why systemd is unhappy.
The counter-argument is real: managed platforms cost more per unit and give you less control at the edges. When we've hit those edges — the static IP thing, region pinning, services whose disk pins them to one instance — the answer has always been available, just occasionally requiring a paragraph of reading. That's a fine deal.
If you're choosing infrastructure for a small product
- Optimise for hours, not instance price. Recompute that whenever someone shows you a cheaper VM.
- Pin your region deliberately, especially if you make privacy claims. It's also where allowlists bite.
- Keep config in groups, keep per-service overrides empty. Drift is the enemy.
- Let stateless things be stateless. The moment a service has a disk, it stops being freely redeployable, and you should know which ones those are.
- Don't host everything in one place out of tidiness. Match each workload to the thing built for it.
Notis is founder-led, Swiss-operated, and shipping constantly. Almost none of that shipping involves thinking about servers.
Render is a large part of why.

Flo is the founder of Mind the Flo, an Agentic Studio specialized into messaging and voice agents.
Related posts
How Notis Delivers an AI Assistant Inside WhatsApp With Twilio
WhatsApp is not a chat widget. Templates, session windows, media and delivery callbacks — and why failed delivery is product logic, not telemetry.
Turning Web Pages Into Agent Context With Firecrawl
Raw HTML is not context. How Notis uses Firecrawl to turn pages into Markdown an agent can think with — and the un-metered tool bug that cost us real money.
Social Proof You Can Click: How We Run Our Testimonial Wall With Senja
Every quote on the Notis homepage links to a public source. Here is how we collect them with Senja, and why we self-host a pinned copy of the widget loader.