DEV Community

Cover image for My Flask Backend Was Falling Asleep Every 15 Minutes — Here's How I Fixed It Completely Free
Rishu
Rishu

Posted on

My Flask Backend Was Falling Asleep Every 15 Minutes — Here's How I Fixed It Completely Free

I built a small Flask backend for one of my side projects, deployed it on Render's free tier, and felt that usual satisfaction of seeing it live with an HTTPS URL and everything. Then I shared the link with a friend to get some feedback.

His reply: "bro it's not loading."

I opened it myself. It did load — but after sitting there for almost a minute on a blank screen. Not a great first impression.

What Was Actually Happening

After a bit of digging I found out this is just how Render's free tier works. If your service gets no traffic for 15 minutes, Render shuts it down to save resources. The moment a new request comes in, it has to boot the server back up before it can respond — and that cold start can take anywhere from 30 seconds to a full minute.

For me sitting at my laptop knowing what's happening, it's fine. For anyone else opening the link cold, it just looks like the site is down or broken.

I didn't want to pay for hosting yet — the project was still in early stages and didn't need production-level reliability. But I also didn't want every first impression to be a 60 second loading screen. So I started looking for a workaround.

First Thought: GitHub Actions

My first idea was to write a simple GitHub Actions workflow that runs every 14 minutes and sends a curl request to my server. If something keeps hitting it before the timer runs out, it never goes to sleep. Simple enough in theory.

on:
  schedule:
    - cron: '*/14 * * * *'

jobs:
  ping:
    runs-on: ubuntu-latest
    steps:
      - run: curl https://green-spoon-backend.onrender.com/api/health
Enter fullscreen mode Exit fullscreen mode

But then I did the math. GitHub's free tier gives you 2,000 Actions minutes per month. Pinging every 14 minutes means roughly 103 runs per day, which comes out to around 3,000+ runs per month. That exceeds the free limit by a lot, and I didn't want surprise charges on a side project I wasn't even monetizing. Crossed that off the list.

What Actually Worked

The core idea was still the same — something needs to ping the server regularly so it never hits the 15 minute idle limit. I just needed a tool that could do it for free without consuming GitHub minutes.

I came across UptimeRobot. It's primarily a monitoring service — you give it a URL, it checks that URL every few minutes, and sends you an alert if it goes down. The free plan checks every 5 minutes, which is more than frequent enough to prevent Render from sleeping.

But before setting that up, I wanted a proper endpoint to ping — not just the root / which might have heavier logic attached. I added a dead simple /health route to my Flask app:

@app.route('/health')
def health():
    return {"status": "ok"}, 200
Enter fullscreen mode Exit fullscreen mode

No database queries, no business logic, nothing that could fail. Just a response that says the server is alive. This is actually a good practice for any backend — having a health endpoint is useful beyond just keep-alive purposes, like when you want to confirm a deployment went through or check if a service is up during debugging.

Then I went to UptimeRobot, created a free account, and added a new HTTP monitor pointing to https://green-spoon-backend.onrender.com/api/health with a 5 minute check interval. Took about 2 minutes to set up.

That's genuinely it. The server has stayed awake ever since.

Something I Was Worried About

My first concern was that I'd get flooded with emails — a notification every 5 minutes saying "your site is up" would be unbearable.

But that's not how it works. UptimeRobot pings your URL silently in the background. You only get notified when something actually goes wrong — when the server goes down, and again when it comes back up. During normal operation you hear nothing at all. It's actually a nice bonus to have real uptime monitoring on top of the keep-alive behavior.


If you've dealt with this before and found a better way to handle it, drop it in the comments — always curious how others approach this.

Top comments (0)