For about half a year, I had been opening dashboards in the morning. But because AdMob and Crashlytics lived in two separate screens, one anomaly kept distracting me from the early signal of the other. While I was chasing a fill-rate drop, a crash spike was building, or the other way around. I knew, in theory, that revenue anomalies and quality anomalies tend to travel together. The structure of my morning routine just had not caught up to that fact.
I am Masaki Hirokawa, an artist and indie developer. I have been making iPhone and Android apps on my own since 2014, and the catalog has crossed 50 million cumulative downloads. This post is about a small change I tried for two weeks: folding the AdMob fill-rate check and the Crashlytics crash-spike check into one Cowork scheduled task, and what the numbers and the friction looked like.
Why I merged the two
On the morning of May 8th, I started triaging an 8-point fill-rate drop in AdMob. It was only in the afternoon that I realized a specific SDK version had been crashing in surges during the same hours. An ad SDK update had triggered crashes on one code path, and that path was also dragging the fill rate down. If I had looked at Crashlytics first, I could have isolated the cause half a day earlier.
Both of my grandfathers were temple carpenters, and they used to say that "the places that break tend to break together." A sagging roof and a sinking pillar. A leak and the wood shrinking around it. The symptoms look independent until you trace them back. App operations have the same texture. Revenue anomalies and quality anomalies are easier to read when one viewpoint covers both, rather than two dashboards on two screens.
How I set up the Cowork scheduled task
The integration is one Cowork scheduled task that opens AdMob and then Crashlytics through Claude in Chrome, in sequence. Before this, I ran two separate morning tasks. Because the outputs were also separate, I was the one cross-referencing them by hand.
The prompt itself is straightforward. It walks through these four steps.
- Open the AdMob report screen and pull out any app-by-network pair where fill rate has dropped by at least 5 points compared to the same weekday last week.
- Open Firebase Crashlytics and pull out any app where crashes in the last 24 hours have grown by at least 30 percent compared to the same weekday last week.
- Overlay the two by hour. If anything in the AdMob list overlaps in time with anything in the Crashlytics list, mark it as "possible correlation."
- Send no notification if nothing is detected. If something is detected, post a short summary to Slack.
Step three used to be the human step. It only took a minute per day, but using morning focus on a minute of overlay work felt wasteful, so I folded it into the prompt.
What the two weeks looked like
Between May 13th and May 26th, the task posted to Slack six times. Here is the breakdown.
- May 14 (Wed) AdMob fill rate down 7 points, Crashlytics flat. Geo filter change on the ad network side.
- May 16 (Fri) Crashlytics up 42%, AdMob flat. A launch-time crash that only reproduced on Android 6.
- May 18 (Sun) AdMob fill rate down 6 points, Crashlytics up 35%, marked as correlation.
- May 22 (Thu) Crashlytics up 31%, AdMob flat. A resolution-related crash on a specific wallpaper image.
- May 24 (Sat) AdMob fill rate down 9 points, Crashlytics flat. A short delivery pause.
- May 26 (Mon) AdMob fill rate down 5 points, Crashlytics up 38%, marked as correlation.
Both of the correlation cases (May 18 and May 26) came right after an ad SDK update. Under the old single-track routine, I would have spent half a day narrowing the cause down to the SDK update. With the merged check, I had a working hypothesis before noon, and the time to resolution felt roughly halved.
In concrete numbers, on May 18 I was on the case by 9:40 a.m., and it took about 90 minutes to restore the May-average eCPM. The closest analogue in April, handled under the old single-track routine, took about four hours from triage to closure. Across the two correlation cases, I recovered roughly 7,200 yen of revenue I would otherwise have lost. At my current scale, that is on the order of 15,000 yen per month.
Where it broke down
Some friction caught me off guard. The biggest one is that Crashlytics and AdMob handle sessions differently. AdMob asks me to log in again every few days, while the Firebase console rides on the Google account session, so its behavior changes with Workspace policies. Out of fourteen days, the task came back empty-handed on two of them, both because of Firebase authentication errors.
I added a Friday-evening habit of logging into both consoles manually. The errors are rarer now but not gone. The check task is idempotent, so an empty day just means silence with no real damage. If I were taking this to a stricter production setup, I would move the Crashlytics side to the Firebase Admin SDK for a more stable read path.
The other friction was a false positive on the correlation note. Once in two weeks, both spikes happened to fall in the same hour for unrelated reasons. A backend incident lined up with an unrelated ad SDK update, and the "correlation" label dragged me into the SDK investigation for half a day. "Happening at the same time" and "correlated" are different things, so I rewrote the note to say "same hour, please verify," and the deep dives have stayed shallower since.
What I delegate and what I keep
After two weeks, the boundary is clear enough to write down.
- Delegated: pulling AdMob and Crashlytics reports, computing the week-over-week deltas, drafting the notification when thresholds are crossed, and overlaying by hour.
- Not delegated: the final read on root cause, definitive interpretation of Crashlytics stack traces, scoping the user impact, and the call on whether to ship a hotfix.
- Half and half: listing and ranking candidate causes. I take the list and check the Firebase console and the AdMob screen myself before deciding.
When I was 17, an online mentor told me that "art is a natural language open to everyone," and I have since carried that idea into how I choose tools. Rather than pushing Claude toward making all the decisions, I keep it as a presence that lays out the material I need to decide. With that framing, I expect to keep working with these tools for a long time. The cause analysis stays in my hands. Only the way the material is gathered and arranged has changed.
What I plan to try next
From here, I want to push in three directions.
- Lower the Crashlytics surge threshold from +30% to +20% and see whether the smaller signals are worth picking up.
- Fold ANR rate from the Google Play Console into the same morning report, so I can read revenue, crashes, and ANR through one frame.
- Once a month, have the Cowork scheduled task list every day in the past 30 that produced a correlation note, and overlay it against the release calendar.
Spending ten minutes on inspection in the morning really does speed up the afternoon decisions. With both the number of apps and the number of SDKs still growing, I expect the structure of this check to keep evolving for a while.