No account. Headers and history live on the device.
Alarm, not a ping
Full-screen page that loops until you acknowledge it
Android 8.0 and upSideload, not on Play
3:12
Checkout API
https://api.example.com/health
OperationalDegradedDown
Urgent alerting armed
Checkout API is down
Connection refused · down for 22m
AckRe-checkMute for an hour
2.5 s budget
Last
No response
Average
126 ms
Checks
60
Failed
5
Example readout, replayed60 checks · 5 min cadence
0:00 / 0:40
Intro
Forty seconds. Watch it with the sound off if you like, the captions are on the CC button.Read the video transcript
Most uptime alerts are one more notification you swipe away.
Nightbell runs entirely on your Android phone. No server, no account, no third party.
Four steps to add a monitor. Point it at anything that answers over HTTP.
Every check runs on the phone. Your tokens never touch a third party.
When a check fails, Nightbell doesn’t send you something you can miss.
It takes the whole screen, and the alarm loops until you acknowledge it.
Nightbell. The uptime monitor that needs no server, no account, and actually wakes you up.
02Why it exists
The problem
A notification you can swipe away is not an alert.
An ordinary alert
Monitoring service · 03:04
api.example.com is not responding
Tap to open the dashboard
Gone
One swipe, and there is no second one.
An urgent Nightbell monitor
Nightbell · ongoing
Checkout API is down
Connection refused · down for 22m
AckRe-check
Re-posted
Marked ongoing, so the swipe does nothing. It comes straight back.
Checking a URL has been a solved problem for twenty years. The hard part is the last ten
centimetres, between a server that knows and a person who is asleep.
Why I built it instead of paying for one
I kept missing outages because ordinary monitoring notifications behaved like
everything else in the shade. The services I tried either wanted a subscription before
they would text me, or sent something that looked exactly like a marketing email and
got swiped away with one. By the time I noticed, the interesting part of the incident
was over.
The hard part is alerting without crying wolf. An outage on an urgent monitor is not a
line in the shade. It behaves like an incoming call, and everything else in the app
exists to earn the right to do that.
Hosted monitoring, self-hosted monitoring and Nightbell compared across six aspects
Aspect
Hosted servicelike UptimeRobot
Self-hostedlike Uptime Kuma
Nightbellon your own phone
Infrastructure
Theirs. Nothing to run.
A box, a container, a certificate, and monitoring for the monitor.
The phone you already carry.
Account
Required.
Usually required, at least locally.
None. There is nothing to sign up to.
Where tokens sit
On their servers.
On your server.
On the device, in one JSON document.
Paging you
Usually the paid tier.
Yours to build, on top of a push service.
A local alarm, so there is nothing to bill for.
At 3am you get
An email or a push notification.
Whatever you wired up.
A full-screen page and an alarm that loops until you acknowledge it.
It cannot
Fail quietly. You will get a bill.
Watch itself.
Check while the phone is off, or beat Android's 15 minute background floor without a
foreground service.
Scroll the table sideways for the Nightbell column
03On the device
How a check runs
The check leaves your phone and goes to your service. That is the entire path.
Not in the path, and not in the dependency list
relay
queue
worker
backend
account
push service
analytics SDK
crash reporter
icon proxy
What it does not buy you is anonymity from the thing you are watching. Your service sees
the request and the IP it came from, exactly as it would for any other client on your
network. That is what a check is.
Implementation details
A status or request monitor is an OkHttp call from your phone to the host you typed in. A
page-element monitor loads the page in an offscreen WebView on the same phone and reads
the DOM nodes you picked by tapping them. There is no relay, no queue and no worker
somewhere else, because there is nowhere else.
Everything the app knows lives in one JSON document in DataStore: your monitors, their
headers and bodies, their sample history and your settings. Backup and transfer writes
that document through the Storage Access Framework, which is why Nightbell asks for no
storage permission and why you choose where the file goes. Nothing is uploaded, and there
is no import path that could reach anything you did not hand it.
What that does and does not buy you
It buys you this: an API token in a monitor's headers is on your phone and on your
server, and nowhere in between. No third party can leak it, subpoena it, or change its
terms of service. There is no analytics library, no crash reporter and no backend in the
dependency list, and site icons are fetched from the monitored origin itself rather than
through an icon proxy.
It does not buy you anonymity from the thing you are watching. Your service sees the
request and the IP it came from, exactly as it would for any other client on your
network. That is what a check is.
04What it watches
Three kinds of check
Point it at a status code, a response body, or one element on a rendered page.
Status check
The cheap one
Hit a URL, assert on the status code. Four modes, because "is it up" means different
things to a health endpoint and to a page that is allowed to redirect.
exact codeany 2xxa rangeany response at all
Cheapest check in the app. A connection refused has no status code and no round trip,
so it reports no response and no latency rather than inventing a zero.
Request and response
The precise one
Choose the method, set headers, send a body with its content type, then assert on
what comes back. Six body assertions, and JSON paths that understand nesting and
array indices.
GETPOSTPUTPATCHDELETEHEAD
containsdoes not containexactly equalsmatches regexJSON field equalsJSON field exists
data.items[0].state
This is the one that catches a deploy that returns 200 and an empty payload, which is
the outage a status check is blind to.
Page element
The expensive one
Loads the real page in an embedded WebView and watches DOM nodes you picked by
tapping them. Each node carries its own expectation and an optional nickname, and the
alert names the one that broke.
element existselement is gonetext equalstext containstext unchangedattribute equals
Every node resolves against one page load, so watching six costs about what watching
one costs. The expensive part is booting the WebView, not the assertions. Selectors
are re-resolved in a fixed order, id first, then a stable data attribute, then the
shortest unique CSS path, then XPath, then a text fingerprint, so a cosmetic markup
change degrades instead of paging you at 4am about a renamed class.
There is a widget too, worst monitor first. Monitors flow into columns rather than
disappearing below the fold when you drag it flat, because a widget's height is whatever
you dragged it to.
05Setup
Adding a monitor
Four steps, and everything is changeable afterwards.
Step 1 of 4
What to watch
Status check, request and response, or page element. This is the only choice that changes the rest of the wizard.
What step 1 sets: status checkrequest and responsepage element
Step 2 of 4
Target
The URL, and for a request monitor the method, headers and body. For a page monitor this is where the live preview opens and you tap the nodes you care about.
What step 2 sets: nameurlmethodheadersbodytest now
Step 3 of 4
Expectations
What healthy means. A status mode, a body assertion, or one expectation per watched element. Test now runs the whole thing once, there and then, before you commit to it.
What step 3 sets: status modeexpected codebody assertiontest now
Step 4 of 4
Cadence and alerts
How often, how long to wait for an answer, and whether this monitor is urgent. Also the latency budget, above which a successful but slow answer counts as degraded rather than down.
What step 4 sets: intervaltimeoutfollow redirectslatency budgeturgent
Nothing here is locked in. Every field is editable from the monitor's detail screen
afterwards, and Test now runs the whole check once before you commit to it.
06The payoff
Urgent alerts
When it breaks, Nightbell wakes you up.
Urgent is a per-monitor switch for the things you cannot afford to sleep through. It is
the only part of the app that is allowed to be loud, and it is deliberately hard to
ignore.
01 The check fails
The failure threshold is met, so this is an outage and not a blip. The card goes red, the banner at the top of the list counts it, and the sparkline keeps the wall of refused connections where you can see it.
02 The page arrives
One notification, on a dedicated alarm channel that bypasses Do Not Disturb. It is marked ongoing, so there is no swipe that dismisses it, and if full-screen alerts are granted it wakes the screen rather than waiting politely on the lockscreen. It comes back every five minutes until you deal with it.
03 You decide one thing
Ack silences this outage and nothing else. Re-check runs the check again right now. Mute buys an hour. The monitor stays red until it is not, and recovery re-arms the loop so the next outage shouts again.
0:00 / 0:11
A screen recording off a real phone. No sound, and it loops.
Repeat
Every 5 min, until acknowledged
Channel
A dedicated alarm channel that bypasses Do Not Disturb
Swipe away
Not possible. The notification is ongoing
On the page
Acknowledge, Re-check now
On the card
Ack, Re-check, Mute 1h
Acknowledging
Stops this outage only. Recovery re-arms it
Exact acknowledgement behaviour
Acknowledging stops the repeats for that outage and nothing else. The monitor stays red,
the ordinary down notification stays where it was, and recovery re-arms the loop so the
next outage shouts again. Urgent overrides cooldown and the repeat toggle, because that
is the point, but it still honours the master switch, the per-monitor switch, mute and
the failure threshold. It means "do not let me miss this", not "ignore everything I
configured".
07Honest limits
What Android allows
Four grants, and the limits that stay after them.
Android will happily let an app think it is alerting you while delivering nothing. This
is the part most phone monitoring apps skip, so it is worth being specific about.
Notifications
Without it nothing is posted at all.
Dialog, in the app
Unrestricted battery
Lets checks keep their schedule, and lets an urgent page keep repeating while the
screen is off.
Dialog, in the app
Full-screen alerts
Lets an urgent page wake the screen instead of waiting on the lockscreen.
Android settings, deep-linked
Do Not Disturb access
Without it, Do Not Disturb and Bedtime mode silence urgent pages completely, which is
exactly when you want one.
Android settings, deep-linked
The first-launch screen counts what is ready, deep-links to the two toggles Android has
no API for, and re-checks itself when you come back.
Things the platform will not do
Sub-15-minute background intervals are impossible, not unreliable.
WorkManager's periodic minimum is 15 minutes and there is no supported way around it.
Strict mode is the only way to get the interval you asked for.
Doze can delay even a 15 minute interval. Exempting Nightbell from battery
optimisation helps and is not a guarantee. Delay is reported in Settings and never
notified about, because it is not an outage.
Strict mode costs a permanent notification and real battery. That is
Android's price for a real cadence, not a design choice.
Element checks need a renderable page. Heavy single-page apps are
polled for about five seconds after load; anything slower to hydrate may report
element not found.
Quiet hours still suppress urgent pages unless you turn on the bypass.
That default is wrong. It is the next thing I want to fix properly, with a migration
rather than a flipped constant.
There is no CI. The 359 JVM and 173 on-device tests are run by hand.
08Install
Getting it
One APK, 2.06 MB, signed with a key you can check.
Signed with my key, not Google's, so Play Protect asks once. The certificate number is
what says the next version came from the same person.
Upgrading, and building it yourself
Android refuses an update signed by a different key, which is what makes the certificate
number above worth checking before you trust an APK you did not get from the link on this
page.
Anything from 2.0.0 onward updates in place and keeps your monitors. 1.x used a different
application id, so the only route across is the JSON export in Settings. Building it
yourself needs JDK 17 and an Android SDK with API 36; the commands are in the
README.
09Questions
Answers
The questions worth asking before you sideload something.
Does it keep checking when my phone is off?
No. The checks run on the phone, so a phone that is off, out of signal or in flight mode is a monitor that is not checking. That is the honest cost of having no server. If you need something watching while the phone is in a drawer, you need a machine that stays awake, and Nightbell is the wrong tool.
Can it check more often than every 15 minutes?
Only in strict mode. Android’s PeriodicWorkRequest has a hard 15 minute minimum and WorkManager silently clamps anything shorter, so Nightbell clamps it visibly instead and says so in Settings under Checker health. Turning on strict foreground monitoring runs a foreground service that keeps your interval exactly, down to about 15 seconds. It costs a permanent notification and real battery, which is Android’s price for a real cadence and not a design choice.
Why is it not on the Play Store?
There is no Play listing. Grab the APK from GitHub Releases and sideload it. It is signed with my own key, so Play Protect will ask you to confirm the first time. The foreground service also declares specialUse rather than dataSync, because dataSync is capped at six hours a day on API 34 and up, which would quietly break the one guarantee strict mode exists to make. Shipping that through Play review would mean justifying the subtype. Sideloading is unaffected.
Does anything leave my phone?
The check itself, to the service you pointed it at. Nothing else. There is no analytics library, no crash reporter and no backend in the dependency list, the permission list is short enough to read in one go, and site icons are fetched from the monitored origin rather than through an icon proxy. Your service sees the request and your IP, the same as any other client on your network would. What never happens is a third party seeing your tokens, your URLs or your uptime history.
Can I watch something on my home network, or over plain HTTP?
Yes. Cleartext traffic is allowed on purpose, so a box on your LAN answering on http:// is a valid target. The catch is the same one everywhere else: the check comes from the phone, so the phone has to be able to reach the host. A monitor on a LAN address stops passing the moment you leave the house, which is a true fact about your network rather than a bug.
What happens to my monitors when I update?
Anything from 3.0.1 onward installs over the top and keeps your monitors, history and settings. 3.0.0 is the exception: 3.0.1 is signed with a new key, because the old certificate’s subject still carried the previous name and a subject cannot be edited, so a 3.0.0 install has to be uninstalled rather than updated. Coming from Pulse 2.x is different again: 3.0.0 renamed the app and moved its application id, which Android treats as a different app entirely, so it installs beside the old one with an empty data directory rather than upgrading it. The route across is Settings, Backup and transfer in 2.4.3, then import on the new install. Export before uninstalling anything, because once the old app is gone so is its data. Placed widgets and your notification channel settings do not come across either.
How is this different from UptimeRobot or Uptime Kuma?
Both are better than Nightbell at being a monitoring service: they keep watching when your phone is in a drawer, they hold years of history, they have status pages. Nightbell is not trying to win that. It is trying to be the thing that wakes you at 3am without a subscription, a server or an account, by running on hardware you already carry and paging you with a local alarm instead of a push notification. If you already run Uptime Kuma, Nightbell is a reasonable pager to put in front of it.
Will the alarm really get through Do Not Disturb?
Once you grant Do Not Disturb access, yes: urgent alerts go to a dedicated DND bypassing alarm channel. One thing to know first, because it is the current known bug rather than a feature: quiet hours still suppress urgent pages unless you turn on the bypass. That default is wrong and is the next thing on my list, with a migration rather than a flipped constant.
What does it do to my battery?
With the default WorkManager scheduling, close to nothing. Strict foreground monitoring costs real battery, because it wakes for every due check instead of letting Android batch them, and it holds a permanent notification while it does. An unacknowledged urgent outage starts that same service on its own regardless of the setting, and stops it the moment you acknowledge or the monitor recovers.
Is it actually free?
Apache 2.0, the whole thing, source included. No paid tier, no account, no upsell, nothing to cancel. Same licence as everything it depends on, so forking it or lifting a piece of it is straightforward. Keep the notice and say what you changed.