How to Stop a Free Host From Sleeping

Quick answer: A free web service on Render spins down after 15 minutes without inbound traffic, and the next visitor waits about a minute while it boots. A scheduled request every 10 minutes keeps it running. What almost nobody puts next to that advice is the price: Render grants 750 free instance hours per workspace per month against a 744-hour month, so you can hold exactly one service awake. Keep two and both stop before the month does. For most people the better answer is the first one below: move to a free tier that does not sleep at all.

There are two ways out and this covers both: move to a tier that stays up, or pay the allowance to hold this one open. Scope is web services that idle out -- databases sleep too, by different mechanics and with a different answer, and merging the two produces advice that is wrong for both.

Why It Sleeps

Render's documentation is specific: a free web service is spun down after 15 minutes without inbound traffic, and that counts both HTTP requests and WebSocket messages from existing connections. Render puts the spin-up at about a minute; its own dashboard warns of 50 seconds or more.

For a portfolio or an internal tool, that is fine. For anything a stranger might open, a 50-second blank screen is the whole first impression.

Option 1: Move to a Host That Does Not Sleep

This is the answer for most people, and it is usually less work than maintaining a pinger forever. Free tiers that stay up do still exist; each asks for a different compromise.

HostSleeps?The trade
NorthflankNo — its pricing page says "always-on-compute"Card verified at signup, not charged
Oracle Cloud Always FreeNo — a real VPSYou are the sysadmin; card required
Cloudflare WorkersNo — nothing to idle10 ms CPU per request; cannot run a process
Serv00No — long-running processes allowed over SSHNo card, but the account needs periodic renewal
RenderYes, after 15 minEasiest deploy of the five

Two of those trade the sleep problem for a different one. Cloudflare Workers never idles because there is no process to idle -- which also means it cannot run one; a 10 ms CPU ceiling per request rules out anything long-running. Oracle gives you a real machine that never stops, and hands you the sysadmin job with it.

Serv00 deserves a caveat: it allows long-running processes over SSH without a card, which makes it the closest thing to a free VPS on this list, but the account itself needs periodic renewal. You have swapped keeping a service awake for keeping an account alive.

Option 2: Keep It Awake

Worth it when Render is where you want to be, you have exactly one service, and moving costs more than the workaround. Any HTTP request arriving more often than the idle timeout works; against a 15-minute window, every 10 minutes is the standard choice.

PingerFreeCardMinimum interval
cron-job.orgYesNo1 minute
UptimeRobotYesNo5 minutes
GitHub Actions scheduleYesNoNot recommended — see below

The UptimeRobot link is an affiliate link. Its free plan is enough for this and we earn nothing if you stay on it, which we expect most readers will. cron-job.org pays us nothing and is listed first because its interval is tighter.

What Else UptimeRobot Does

Worth knowing if you are setting one up anyway, because pinging is the smallest thing it does. It is a monitoring product: the periodic request is the mechanism, the alert is the point. Eight monitor types — HTTP/HTTPS, keyword, ping, TCP port, cron/heartbeat, DNS change, response time, and SSL/domain expiry.

The heartbeat monitor is the interesting one here, and it runs in the opposite direction: instead of you pinging your service, your job pings UptimeRobot, and you are alerted when it stops. That catches the failure this article sets you up for — when the monthly instance hours run out, the service simply stops, with no notification, at whatever hour of the night the allowance happens to expire.

The free plan covers 50 monitors at 5-minute checks, 5 alert contacts, one status page, and two months of log retention. Alerts go by email; Slack, Telegram and Teams start on the paid Solo tier.

One trap worth naming: on the free plan an HTTPS monitor does not check the certificate. SSL and domain expiry monitoring is paid, so "I am monitoring the https URL" does not mean you will hear about a certificate about to lapse.

Why Not GitHub Actions

It is the obvious free scheduler and it fails here in two documented ways. GitHub's own documentation states that in a public repository, scheduled workflows are automatically disabled when no repository activity has occurred in 60 days. A keep-alive has to run forever; a repo you have stopped committing to goes quiet, the workflow is switched off, and nothing tells your service. It starts sleeping again two months later.

The same page notes the schedule event can be delayed under load, and that "if the load is sufficiently high enough, some queued jobs may be dropped". A dropped run against a 15-minute timeout is a spin-down.

What Staying Awake Costs

This is the part the "just ping it" advice leaves out, and it stays invisible until services start stopping.

Render grants 750 free instance hours per workspace per calendar month — per workspace, not per service. A 31-day month is 744 hours.

 Hours/month
Free allowance, whole workspace750
One service, never sleeping~744
Left for everything else~6

You can keep exactly one free service awake. Keep two and both run out before the month does — and because the allowance is shared across the workspace, the second one takes the first one down with it.

The Case Where It Will Not Even Deploy

One workload hits a wall before the spin-down: a process with no HTTP surface at all. A Telegram bot on long polling, a Discord gateway client, a queue consumer — each talks outward and receives nothing inbound.

Render's free plan covers three service types: web services, Postgres, and Key Value instances. There are no free background workers. A process that opens no port is not a web service, so there is nowhere on the free plan to put it — and deployed as one it is idle from the moment it starts, because long polling produces no inbound request to reset the timer.

Both problems have one answer: open a port you did not otherwise want.

import os, threading
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Cache-Control", "no-store")
        self.end_headers()
        self.wfile.write(b"ok")

    def do_HEAD(self):            # many pingers send HEAD, not GET
        self.send_response(200)
        self.end_headers()

    def log_message(self, *args):  # a ping every 10 min is 4,320 lines/month
        pass

def start():
    port = int(os.environ.get("PORT", 10000))   # the platform injects PORT
    srv = ThreadingHTTPServer(("0.0.0.0", port), Handler)
    threading.Thread(target=srv.serve_forever, daemon=True).start()

start()
bot.run()          # or whatever blocks forever

Three details decide whether it works. start() must run before the line that blocks forever, or the port never opens and the deploy is rolled back as unhealthy — which looks like a broken build, not a misplaced line. Bind 0.0.0.0, not 127.0.0.1, or the platform's router cannot see it. And silence log_message, or a ten-minute ping writes about 4,320 identical lines a month into logs you deploy to read.

Thirty lines of standard library, worth writing yourself. A version with the Node equivalent is at github.com/build996/free-tier-keepalive (MIT, no dependencies).

If your bot platform supports webhooks, switching off long polling removes this entire section: inbound requests are exactly what a webhook produces.

FAQ

Is pinging your own service against the rules?

It is not circumventing a limit — the hours are metered and deducted from your allowance exactly as intended. You are spending your monthly grant continuously rather than intermittently. The constraint that bites is the 750-hour budget, not a policy.

Why not use a shorter interval to be safe?

It changes nothing. The instance is either awake or it is not; pinging every minute keeps it awake exactly as well as every ten minutes, and burns the same hours.

Do databases sleep too?

Yes, and differently enough that the advice here does not transfer. Neon autosuspends its compute and resumes on the next query in seconds; Supabase pauses a whole project after about a week of inactivity, and that is not something an HTTP ping to your website prevents. Applying this article's fix to either would be wrong in one case and useless in the other. Its own write-up.

My deploy says "no open ports detected" — what did I get wrong?

Almost always one of two things: the server started after the blocking call, so it never ran, or it bound 127.0.0.1 instead of 0.0.0.0. Both look identical from the platform's side.

What happens when the free hours run out?

The service stops until the allowance resets at the start of the next calendar month. Hours do not roll over. This is why the one-service limit matters — running out is silent until something is down.