DEV Community

Cover image for How I Monitor 80+ Cloud Services in Real-Time (And Get Notified Before My Users Do)
Firat Celik
Firat Celik

Posted on

How I Monitor 80+ Cloud Services in Real-Time (And Get Notified Before My Users Do)

A deep dive into building StatusWatch; push notifications for service outages, built with Flutter and a real time status aggregation backend.


The moment that started it all

It was a Friday evening. A client messaged me: "The checkout isn't working."

Stripe had been down for 38 minutes. I had no idea.

I did what most developers do opened five browser tabs, checked Stripe's status page, scrolled Twitter looking for complaints. By the time I confirmed the issue and messaged the client back, 45 minutes had passed.

That was embarrassing. More importantly, it was preventable.

I started looking for a mobile app that would just... tell me when my stack breaks. Something that monitors the services I actually use and sends a push notification the moment something goes wrong. I couldn't find exactly what I wanted, so I built it.

This is the story of how StatusWatch works under the hood.


The core problem: status pages are not built for developers

Every major cloud provider publishes a status page. AWS has one. GitHub has one. Stripe has one. They're public, they're (usually) accurate, and almost nobody checks them proactively.

Why? Because checking 10 different status pages manually every time something feels off is not a workflow. It's a punishment.

The real need is simple: when something in my stack breaks, I want to know immediately not when a user tells me.

StatusWatch solves this by polling the official status APIs of 80+ services, normalizing the data into a unified format, and pushing a notification to your phone the moment an incident is detected.


Architecture overview

At a high level, the system has three layers:

[Status APIs] → [Aggregation Backend] → [Flutter Mobile App]
Enter fullscreen mode Exit fullscreen mode

Let me walk through each one.


Layer 1: Polling the status APIs

Most major services expose their status data in one of two formats:

Atlassian Statuspage (the most common) used by GitHub, Stripe, Vercel, Cloudflare, Supabase, Linear, and dozens more. The API returns a structured JSON response with components, incidents, and scheduled maintenances.

GET https://www.githubstatus.com/api/v2/summary.json
Enter fullscreen mode Exit fullscreen mode

A simplified response looks like this:

{
  "status": {
    "indicator": "minor",
    "description": "Minor Service Outage"
  },
  "components": [
    {
      "name": "Git Operations",
      "status": "degraded_performance"
    },
    {
      "name": "API Requests",
      "status": "operational"
    }
  ],
  "incidents": [
    {
      "name": "Increased error rates on Git push",
      "status": "investigating",
      "created_at": "2025-04-10T14:22:00Z"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Custom status APIs — services like AWS, Google Cloud, and Azure have their own formats. AWS Health Dashboard, for example, returns RSS/Atom feeds per region and service. These require individual parsers.

The normalization challenge

Each service returns data in a slightly different shape. To display everything uniformly in the app, I normalize every response into a shared schema:

{
  "service_id": "github",
  "name": "GitHub",
  "overall_status": "degraded",
  "components": [...],
  "active_incidents": [...],
  "last_checked": "2025-04-26T09:15:00Z"
}
Enter fullscreen mode Exit fullscreen mode

This normalization layer is what makes it possible to show a consistent green/yellow/red dashboard regardless of which service you're looking at.


Layer 2: Detecting state changes and triggering notifications

Polling alone isn't enough. The key logic is detecting when a service's status changes — from operational to degraded, from degraded to outage, and back to operational.

Previous state: operational
Current state:  degraded
→ Trigger notification: "GitHub is experiencing degraded performance"
Enter fullscreen mode Exit fullscreen mode
Previous state: degraded  
Current state:  operational
→ Trigger notification: "GitHub is back to normal ✓"
Enter fullscreen mode Exit fullscreen mode

Each service's last known state is stored server-side. On every polling cycle, the new state is compared against the stored state. If they differ, a notification is queued.

Polling intervals

Not all services are polled at the same frequency. The free tier uses a 5-minute polling interval. Pro users get near-instant detection — polling runs every 60 seconds, and for major services like AWS, GitHub, and Stripe, we watch for webhook-based updates where available.

Push notifications

Notifications are delivered via FCM (Firebase Cloud Messaging) for Android and APNs for iOS. When a state change is detected, the backend sends a targeted push to all users who have that service in their watchlist.

The notification payload is minimal and actionable:

Title: ⚠️ Stripe — Incident Detected
Body: Payment API is experiencing elevated error rates
Tap: Opens incident timeline in StatusWatch
Enter fullscreen mode Exit fullscreen mode

Layer 3: The Flutter app

The mobile app is built with Flutter, which gives us a single codebase for iOS and Android with native performance.

The dashboard

The main screen is a flat list of your followed services, each showing:

  • Service name and logo
  • Current status (green dot, yellow dot, red dot)
  • Active incident summary if one exists

The status colors follow a simple convention: green = operational, yellow = degraded performance, red = major outage or partial outage.

Incident timeline

Tapping any service opens its incident timeline a chronological feed of status updates from "Investigating" through "Identified", "Monitoring", and finally "Resolved". This is pulled directly from the status API and gives you the full picture without opening a browser.

Uptime heatmap (Pro)

For Pro users, each service shows a 90-day uptime heatmap — a grid where each cell represents one day, colored by uptime percentage. This gives a quick visual sense of a service's reliability history.

State management

The app uses Riverpod for state management. Each service's status is a stream that updates when the backend pushes new data. The UI rebuilds reactively — no manual refresh needed.


The services we monitor

One of the most time-consuming parts of building StatusWatch was the initial service integration work. Not every service has a clean, documented status API. Here's a breakdown of the current coverage:

Category Services
Cloud AWS, GCP, Azure, DigitalOcean, Hetzner, Fly.io, Railway
DevOps GitHub, GitLab, CircleCI, Render, Linear, Jira
Hosting Vercel, Netlify, Heroku, Cloudflare, Firebase
Database Supabase, MongoDB Atlas, Neon, Redis Cloud, Upstash
Payments Stripe, Paddle, Twilio, SendGrid, Resend
Monitoring Datadog, Sentry, Grafana Cloud, PagerDuty, New Relic
AI OpenAI, Anthropic, Hugging Face, Together AI

80+ services total, and the list grows with every release.


What I learned building this

Status APIs are inconsistently documented. Some services have beautifully documented status APIs. Others you have to reverse engineer from their status page's network requests. A few don't expose machine-readable status data at all, which means falling back to HTML scraping fragile, but sometimes the only option.

Push notification timing is everything. A notification that arrives 20 minutes late is almost useless. The entire value proposition is knowing before your users do. This made the polling architecture a first class concern from day one, not an afterthought.

Normalization is harder than it looks. "Degraded performance" on Stripe is not the same operational severity as "degraded performance" on GitHub. Building a useful unified model required understanding each service's incident taxonomy not just their API shape.

Free tier design matters for conversion. The 5-service limit on the free tier is intentional. Most solo developers track 5–8 services. Hitting that limit naturally creates the moment where a user thinks "I need one more" which is where the Pro upgrade conversation starts.


What's next

A few things on the roadmap:

  • Android widgets glanceable status on your home screen without opening the app
  • More services always expanding the list based on user requests
  • Custom webhook endpoints for services not on the official list
  • Team accounts shared watchlists and notification routing for small DevOps teams

Try it

StatusWatch is free to download. The free tier covers 5 services with 5-minute notification delays enough to see if it fits your workflow before committing to Pro.

If your stack touches AWS, Stripe, Supabase, OpenAI, or Vercel, you'll probably want to know about outages before your users do.

[Download StatusWatch on the App Store]


Built by a Firat Celik. Feedback welcome drop a comment or find me on X [@Bi9x6].


Tags: flutter, devops, sre, devtools, buildinpublic, mobile, backend, cloudinfrastructure

Top comments (0)