TECHNICAL DOCUMENT

Why Your Screen Time Limit Doesn’t Block at Exactly 30 Minutes on Android

You set a 30-minute limit. You pick up the phone at 33 minutes and the blocking screen has only just appeared. Nothing crashed. Nothing looks broken. It just ran late.

Search for an explanation and you’ll find plenty of pages telling you how to set a limit, and almost none telling you why the limit you already set didn’t land on the minute. This page is the second thing. I build an Android screen-time app, so most of the numbers below come out of my own project’s logs, and I’ve said which device each one came from.

One thing up front, so this doesn’t read as a sales pitch in disguise: this is a limitation of the APIs Android gives to any third-party app. Mine has it too. What varies between apps is how big the gap is and which direction it leans, not whether it exists.

The thirty-second version

  1. Android doesn’t tell a third-party app when the app on screen changes. No callback, no notification. Apps have to ask, repeatedly. That polling is where the first few seconds go.
  2. My app asks once per second. Even so, the delay between a child opening a monitored app and my app noticing measured 5 to 28 seconds on one Huawei handset.
  3. The bigger delay isn’t detection — it’s the phone freezing the counter. Manufacturer battery management suspends background apps. While suspended, a screen-time app can’t count and can’t block.
  4. On that same handset, the phone held back my 60-second wake-up alarm for just over five minutes — its own alarm dump reported a maximum delay of 5m1s, and the result was 5 minutes 33 seconds of uninterrupted video past the limit. Moving that wake-up into the alarm category Android promises never to delay took the same test to 57 seconds.
  5. The error typically runs late. A deliberate design bias with a price: your child occasionally gets extra seconds. We would rather that than cut them off before their time is genuinely up.
  6. Tens of minutes over with no reminder at all isn’t drift — that’s monitoring being frozen, and on some phones one specific setting fixes it.

How to tell normal drift from something actually broken

The thresholds sit further apart than you’d guess.

Normal, on Android, with any third-party app:

  • A few seconds to a couple of minutes past the limit before the block appears
  • The counter reading slightly lower than a stopwatch would have
  • The block arriving faster on some days than others, depending on what else the phone was doing

Not normal — worth investigating:

  • Tens of minutes over with no reminder at all. The 60%, 75% and 90% nudges in my app double as a canary: if none fired, the monitoring wasn’t running. That isn’t lateness.
  • The counter doesn’t move while you watch the child use the phone. That’s a frozen or stopped service, not drift.
  • Reminders only appear right after you open the parental app. The manual-thaw signature from the timeline below, and the clearest single symptom of a frozen service.
  • The counter reads higher than reality. In my app’s design that shouldn’t be possible; if it happens, it’s a bug rather than the platform.

If you’re in the second list, check the manufacturer background setting (under “What you can actually do about it” below) before concluding the app is broken.

Android won’t tell an app what’s on the screen

This is the root of everything else, and it surprises most people.

There is no way for a normal Android app to be told that the child just switched to a video app. The older APIs that let one app inspect what else was running — getRunningTasks, getRunningAppProcesses — were restricted years ago for privacy reasons and now return only the calling app’s own. What’s left is UsageStatsManager, which works the other way around: the system records usage events, and a parental-control app asks for a window of them and reads back what happened. It’s a query, not a subscription. Nothing pushes.

So every third-party screen-time app on Android is built as a loop — ask, wait, ask again — and that has two costs: how often you ask, and how quickly the system’s records reflect reality.

One exception, named rather than hidden. An accessibility service can observe window changes closer to real time, and Google’s Play policy puts declaration and prominent-disclosure requirements on using that API for anything other than helping users with disabilities. My project removed its accessibility service and made a rule never to reintroduce one, so everything below describes the polling world.

What polling actually costs

Here’s what my app does, taken from its source rather than rounded off:

WhatInterval
Check which app is in front1 second
Reread the parent’s settings from the database30 seconds
Background wake-up, the safety net for when the loop is suspended60 seconds
Save the counter to diskevery 5 checks

A one-second loop sounds precise, but it isn’t the binding constraint. On that Huawei handset, the delay between a child actually opening a monitored app and my app registering it measured between 5 and 28 seconds, even with the loop running normally. That’s the system’s event records catching up, not the loop being slow.

When my app is itself on screen, accuracy is a second or two. That’s not the case anyone cares about. The case that matters is a child in a video app — exactly when the phone has the strongest incentive to put my app to sleep.

The real culprit: the phone freezes the counter

Manufacturers who compete on battery life are aggressive about background apps. Not killing them, necessarily — freezing them. The process stays in the list but stops getting CPU time. A foreground service doesn’t exempt you. Neither does a wake lock. And there’s no public API to opt out.

This isn’t sabotage: a phone that lets any app run a one-second loop all day has bad battery life, and battery life is something people compare. It’s a sensible default that happens to be terrible for the small category of apps with a legitimate reason to keep counting.

While frozen, a screen-time app isn’t counting, isn’t checking, and can’t put anything on screen. The child is watching. The app is asleep beside them.

My answer to that is the 60-second wake-up: even with the loop frozen, an alarm fires once a minute, wakes the app, works out how much time it missed, and blocks if the limit has passed. Worst case, a minute late.

That’s the design. Here’s the night it didn’t hold.

One measured evening on one Huawei handset

On 2026-06-12 the limit was long past and opening a video app produced nothing. Switching to my app and back blocked instantly. Classic frozen-process behavior — but the 60-second net should still have caught it. It didn’t, and the phone’s own diagnostics said why.

TimeWhat happened
21:49:53Video app opened, process frozen seconds earlier. 46 seconds, no block.
21:50:36I opened my own app — which thaws the process by hand.
21:50:39Video app reopened. Blocked in 0.7 seconds. The blocking logic was fine all along.
21:50:43 – 21:56:16Video app in front continuously. Five consecutive 60-second wake-ups were never delivered.
21:56:16The alarm finally fired. The block appeared.

That’s 5 minutes 33 seconds of uninterrupted video past the limit — and the phone admitted it. The system’s alarm dump listed a maximum delay of +5m1s against that alarm. Nothing was cancelled or misscheduled; all five were held back, on the same phase.

The failure wasn’t “the app forgot to block.” It was “the app was never woken up to find out it should.”

What fixed it, and what it cost

Android has more than one class of alarm. The strongest is the one reserved for alarm clocks, which the system commits to delivering on time even in low-power states — because a phone maker that delays that category makes users miss work.

I moved the wake-up into that category, but only while a child is actually blocked and the screen is on. On the same handset, the same reproduction went from 5m33s to 57 seconds.

The cost is visible, and I’d rather state it than have a parent discover it: while a child is blocked with the screen on, an alarm-clock icon appears in the status bar. It goes away within about a minute of unlocking or the day rolling over.

All of this was measured on one Huawei handset running EMUI. Not all Huawei phones, and certainly not all Android phones — a Pixel doesn’t freeze background apps this aggressively, so the same test there wouldn’t reproduce it. What I can say is that on that device the delay was real, the cause came from the system’s own logs, and the change closed most of it.

Why the error leans late

This is the part I’d want to know as a parent, and the one place where the answer isn’t “Android’s fault” but “I chose it.”

There are three separate places where my app throws away time rather than estimate it:

One — an over-long gap gets truncated, not extrapolated. The loop expects one second between checks; when the phone has been throttling, it might be forty. If the child was clearly in the same app throughout, my app counts up to 60 seconds of it. If the app changed during the gap — nobody knows what happened in the middle — it counts at most 5 seconds. Anything above those caps is discarded, not credited.

Two — a suspicious gap is dropped entirely. If the internal timer sees a jump longer than 5 seconds, it treats that stretch as unknown and adds nothing.

Three — the ceiling is the system’s own number. Periodically my app compares its running total against Android’s daily usage figure for the same apps, and raises the counter to match if the system’s number is higher. It only ever moves up toward that total, never above it and never back down.

Add those together and, while monitoring is running normally, the counter tends to sit below real usage. A tally that leans towards undercounting needs more real minutes to reach the limit, so the block lands on the late side.

The trade-off is real. Choosing “rather late than early” means choosing “sometimes extra”: your child occasionally gets a bonus minute or two, and on a badly-behaved phone occasionally more. The alternative is guessing at the frozen gap and rounding up — which sometimes means telling a child their time is up when it isn’t. A kid cut off early has a completely legitimate grievance, and they will remember it. That’s the worse failure, so I picked the other one.

The short version, which is written into my app’s terms rather than buried: as long as the monitoring is actually running, the moment isn’t guaranteed but the stop is. How to tell when it isn’t running is further down.

What you can actually do about it

None of these make the gap zero. Each one measurably shrinks it.

Check the manufacturer’s own background-app setting, not just battery optimization. These are often two independent switches, and turning off battery optimization doesn’t touch the other one. On Huawei the one that matters is App launch management, which defaults to automatic. I lost a demo recording to it: 22 minutes in a video app, no reminder, no block, on a phone where the battery whitelist was already granted. Setting the app to manual with all three sub-switches on fixed it — afterwards the remaining-minutes counter ticked down normally within three minutes. On Xiaomi the rough equivalent is autostart plus the “no restrictions” battery policy, and on Samsung it’s adding the app to the never-sleeping list — though I haven’t tested either myself. For paths per manufacturer, dontkillmyapp.com is the community reference.

Don’t swipe the parental app out of Recents. On many skins that reads as “the user wants this gone,” a stronger signal than any battery setting.

Set the limit as a budget, not a stopwatch. If you want the screen off at 7:30, don’t set a limit that lands on 7:30 exactly.

Expect the ending; don’t rely on the block to announce it. A limit that fires silently at an unpredictable second is worse than a warning you know is coming. Which Android settings actually produce an advance warning, and which quietly don’t, is a separate piece.

What I can’t tell you

I don’t have a rack of devices — everything measured here came off one handset, and I haven’t reproduced any of it on Xiaomi, OPPO, vivo or Samsung.

I also can’t tell you how other apps behave. They read the same system data through the same API, so the same physics apply, but the size and direction of their error is theirs to publish rather than mine to guess at. What’s striking is that nobody publishes it. Google’s own Family Link help page explains how to set limits and says the child gets a notification when the device is about to be locked. It says nothing about how accurate the counting is, or how long enforcement can take.

That silence is the reason this page exists.


Written by a parent who builds Tortoise Time, an Android screen-time app for kids aged 6 to 14. It nudges quietly at 60%, 75%, and 90% of the daily limit before blocking anything at 100%. It’s free, with no ads and no in-app purchases. Your child’s screen-time data stays on the phone by default — the only things that leave the device are anonymous crash reports and usage statistics, as our privacy policy says.

Sources and provenance

  • The intervals and caps (1-second polling, 30-second settings refresh, 60-second wake-up, the 60- and 5-second gap caps, the 5-second drop threshold, the keep-the-larger-value database write) are constants and logic read directly out of my app’s source, not recalled.
  • The 5-to-28-second detection lag, the +5m1s alarm delay, the 5m33s uncovered stretch and the 57-second result after the fix were measured on one Huawei handset running EMUI on 2026-06-12, cross-checked against the system’s usage-event stream, event log, alarm dump and my app’s own timing records.
  • The 22-minute case with no reminder was the same handset on 2026-07-01, App launch management at its automatic default, battery whitelist already granted.
  • “Manage your child’s screen time.” Google For Families Help. (Retrieved 2026-08-02, checked specifically for any statement about counting accuracy or enforcement delay — there is none.)
  • UsageStatsManager, Android API reference, and “Use of the AccessibilityService API”, Google Play Console Help. Both described in my own words, not quoted.
  • dontkillmyapp.com — community reference for per-manufacturer background restrictions. Not tested by me device by device.

Not verified: the same measurements on Xiaomi, OPPO, vivo, OnePlus, Samsung or Pixel hardware, and the accuracy or enforcement delay of any other screen-time app.

Source public/en/31-why-limits-dont-block-instantly.md
Written and maintained by the Tortoise Time team

Add Developer WeChat

Scan to connect with me

WeChat QR Code

Please mention "Tortoise Time User" in request