← All whitepapers
May 3. August 29, 2026

Six apps are live. Here is what a day actually looks like when you stop building one at a time:

Not a productivity theory. This is the git history off my own laptop -- 314 commits across five codebases, 85 hours of it timestamped to the minute, and 94% of those hours falling outside a Monday-to-Friday nine to five. Plus the honest cost of holding six half-built things in your head at once.

6
apps live
85
hours, total
314
commits
94%
outside 9–5

The thing nobody tells you about building fast:

It is not that you got faster at the work. It is that you stopped waiting.

In November 2024 I started on Pi Squared, a daily maths game. I was working on a shared repo with other people and I pulled from it, on and off, for ten months. That was my education. Everything I know about Flutter, Firebase, App Store Connect and the particular misery of iOS signing, I learned there, slowly, one problem at a time.

Then in May 2026 I started Braindex on my own. Between that first commit and the end of August I authored and shipped five more apps. Same laptop. Same day job Monday to Friday. Same two hours of soccer training most evenings.

The obvious explanation is that I got better. That is partly true and mostly not the point. The real change is structural, and it is visible in the timestamps: I stopped building one thing at a time. When a model is generating, when a build is compiling, when Apple is processing a TestFlight upload -- those are not waits any more. They are the other app's turn.

This paper is about what that actually looks like hour by hour, what it costs, and the five things I would tell anyone trying it.

Figure 01

The six, and what each one cost in build days.

Build days means days on which at least one commit landed -- not calendar days, and not hours. Braindex is the outlier because it never stopped: it is the one I keep shipping into.

AppWhat it isFirst commitSpanBuild daysCommits
Pi SquaredDaily maths game. My first, built with others on a shared repo.Nov 2024~10 months----
BraindexDaily AI vocabulary, then daily trivia, then leagues, friends and a live multiplayer chase.3 May 2026119 days42192
Chip MeOnline card game. Started life as a web prototype, became a Flutter app.21 Jun 202642 days819
BuzzScraperTap-to-fly arcade. A bee, a city, and eventually a Mode 7 kart racer.1 Aug 202624 days630
M50 Speed RunTraffic-weaving endless runner. Built as a web game, wrapped for iOS.5 Aug 20265 days429
Over the BarGAA free-taking game. Every county, its own clubs, its own hundred levels.10 Aug 202617 days644

Counts are taken from the local git reflog on my machine, which is the record of what my laptop actually did. Pi Squared is left blank on purpose -- I cloned that repo rather than authored it, so its history is not mine to count.

The number I keep going back to is M50 Speed Run: four build days, start to finish, live on the App Store. Not four weeks. Four days on which I opened the editor at all. And it was not a quiet four days -- two of them were shared with BuzzScraper and one with Braindex.

The parallel day:

Three claims about how this works, and the evidence for each from the commit log.

Claim one: the day is not the day. I have a full-time job. I am not building between nine and five. So the interesting question is not "how many hours" -- it is which hours, and what shape they are.

Figure 02

When 314 commits actually landed, by hour of day.

All five apps I authored, May to August 2026, in Michigan time. The shape is not subtle.

00:00
29
01:00
13
02:00
3
03:00–06:00
0
07:00
6
08:00
9
09:00
3
10:00
6
11:00
12
12:00
5
13:00
4
14:00
5
15:00
11
16:00
16
17:00
11
18:00
16
19:00
16
20:00
8
21:00
29
22:00
52
23:00
60

Peak hour is 23:00. Second is 22:00. Between 03:00 and 06:00 there is not a single commit in four months, which I take as the one piece of good news in this chart.

183 of 314 commits -- 58% -- landed between 9pm and 2am. That is the window. It is after the job, after training, after dinner. It is roughly three hours, four or five nights a week, and it is the entire budget. Everything in this paper is a strategy for getting six apps' worth of progress out of three hours.

Claim two: the unit of work is a commit, not a session. Inside that window the median gap between one commit and the next is nine and a half minutes. Half of all consecutive commits are under ten minutes apart. That is not me typing faster. That is what happens when the loop is: describe the change, review what comes back, commit, move.

And "move" is doing a lot of work in that sentence. Because the next thing you move to is often a different app.

Figure 03

One real evening: 9 August 2026, two apps, twenty-five commits.

Every commit that landed that day, in order, across both repos. Blue is M50 Speed Run. Gold is BuzzScraper. Nothing has been reordered or tidied.

15:37
BuzzScraper
Ship 1.0 as two games; add pause, score history and stats
15:44
M50
Rework the menu, game over screen, and add pause plus a speedometer
15:45
BuzzScraper
Add the player profile model, with the consent rules in the model itself
16:19
M50
Add Firebase project config, Firestore rules and indexes
16:29
BuzzScraper
Wire up Firebase: analytics events and locked-down Firestore rules
16:32
BuzzScraper
Rewrite the privacy policy for the Firebase reality
17:07
BuzzScraper
Raise the iOS deployment target to 15.0 for the Firebase pods
17:10
M50
Add App Store screenshots and the capture pipeline
17:11
M50
Add App Store Connect screenshot uploader
-- five hours off. Dinner, training, life. --
22:23
M50
Relax run createdAt rule for the REST client
22:37
M50
Add live Firebase leaderboard, offline-tolerant by construction
22:38
BuzzScraper
Add Sign in with Apple and the Firestore sync layer
22:39
M50
Update privacy policy and store description for the leaderboard
22:46
M50
Rebuild the menu around the world, add leaderboard and a new icon
22:52
BuzzScraper
Move stats onto the game tiles and make big scores legible
22:53
M50
Menu music, working mute button, mission calendar, drop install hint
22:56
M50
Rebuild the share card, and use normal version numbers
23:05
M50
Leaderboard ranks players not runs; art-direct the share card
23:29
BuzzScraper
Add the bee racer's track geometry and driving model
23:36
M50
Refresh App Store screenshots
23:43
M50
Ship as 1.0.1 so build numbers sort correctly
23:45
BuzzScraper
Add the racer's screen: camera, city, drag steering and lap HUD
23:54
M50
Document version and build numbering
23:54
M50
Correct stale build-numbering note
23:57
M50
Test that a player actually reaches the leaderboard

Look at 22:37 to 22:39. A Firebase leaderboard lands in M50, then Sign in with Apple lands in BuzzScraper, then M50's privacy policy is updated to describe the leaderboard that arrived two minutes earlier. The two apps are not competing for attention. They are covering for each other. While one is generating or building, the other is where I am.

Note also what 16:19 and 16:29 have in common. The same job -- wire Firebase, write the rules -- done twice, ten minutes apart, in two different apps. That is not duplicated effort. That is the cheapest either of them will ever be, because I only had to remember how once.

Claim three: the switching is the method, not the accident.

Figure 04

Eleven of fifty-three build days touched more than one app.

Every multi-app day between May and August 2026, and which repos were open.

22 Jun
2 apps
1 Jul
2 apps
2 Jul
2 apps
3 Jul
2 apps
1 Aug
3 apps
5 Aug
3 apps
9 Aug
2 apps
10 Aug
2 apps
12 Aug
2 apps
15 Aug
2 apps
24 Aug
2 apps

21% of build days. 40 recorded switches from one repo to another within a single day. The busiest -- 5 August -- ran M50, BuzzScraper and Braindex from just after midnight through to 22:22.

That 5 August day is worth pulling apart, because it is the whole method in one line: M50 Speed Run went from an empty repo at 00:02 to a working TestFlight pipeline at 00:34. Thirty-two minutes. Then at 00:40 I was back in Braindex shipping group invite codes, and at 00:42 back in M50 switching the iOS export to manual signing.

Over the Bar did something similar five days later: initial commit at 21:21, "playable on device, shipping to TestFlight" at 23:26. Two hours and five minutes from nothing to a build in Apple's hands.

The hours, timestamped:

Every sitting, every window, and how much of it fell outside a normal Monday-to-Friday nine to five.

I wanted to know the real number, so I worked it out properly rather than guessing. Every commit is grouped into a sitting -- a run of commits with no gap longer than ninety minutes -- and each sitting gets twenty minutes added at the front, because the first commit is never the first thing you do. Then every minute of every sitting is checked against Monday to Friday, 08:00 to 17:00.

Across four months and six apps, the answer is 85 hours. Not eighty-five hours a week, or a month. Eighty-five hours in total, from 3 May to 29 August.

Figure 05

Where the 85 hours actually sat against a working week.

Monday to Friday, 08:00 to 17:00 is treated as core hours. Everything else -- evenings, nights, weekends -- is outside.

Weekday evenings & nights
47.4 h
Weekends
32.4 h
Inside Mon–Fri 8–5
5.3 h

93.8% of the total fell outside core hours. Of 51 sittings, exactly two happened entirely inside a normal working day -- 30 June and 7 August, twenty minutes each.

The 5.3 hours inside core hours is the number I find most reassuring, and it is worth saying plainly: this was not built on my employer's time. 3.4 of those 5.3 hours are a single Friday -- 3 July -- and what is left is seven short sittings scattered over four months, most of them before 09:00 or in a lunch hour.

The rest of the shape: 31 of 51 sittings ran to 22:00 or later, and 13 of them finished after midnight. The longest single sitting was 4.6 hours, on a Sunday afternoon in July. The longest day was Saturday 15 August -- 6.7 hours across three separate sittings, which is the day Over the Bar got its counties, its clubs and its Apple sign-in fix.

Figure 06

The full log: every sitting, 3 May to 29 August 2026.

Windows are start to finish in Michigan time, including the twenty-minute lead-in. "Outside" is the hours of that day falling beyond Mon–Fri 08:00–17:00; "all" means the entire day did. Weekend rows are shaded. A sitting that runs past midnight is logged under the day it began.

DateDayWindows workedHoursOutsideApps
3 MaySun11:01–12:02 · 18:51–19:11 · 21:29–21:521.7allBraindex
8 MayFri23:16–00:141.0allBraindex
9 MaySat11:22–11:530.5allBraindex
11 MayMon18:09–19:00 · 22:22–23:292.0allBraindex
12 MayTue17:22–18:14 · 22:10–23:192.0allBraindex
13 MayWed19:49–20:09 · 22:09–22:290.7allBraindex
16 MaySat07:08–07:57 · 19:24–20:332.0allBraindex
17 MaySun00:52–01:210.5allBraindex
20 MayWed19:25–19:450.3allBraindex
23 MaySat16:29–16:490.3allBraindex
24 MaySun20:54–21:140.3allBraindex
25 MayMon10:14–10:34 · 19:31–23:404.54.1Braindex
26 MayTue22:32–23:050.5allBraindex
21 JunSun19:58–20:180.3allChip Me
22 JunMon20:34–21:541.3allBraindex, Chip Me
23 JunTue22:32–23:130.7allChip Me
28 JunSun15:33–15:530.3allBraindex
30 JunTue11:27–11:470.30.0Chip Me
1 JulWed17:53–18:37 · 20:52–21:12 · 22:48–23:081.4allBraindex, Chip Me
2 JulThu18:19–19:03 · 22:03–23:242.1allBraindex, Chip Me
3 JulFri01:23–02:38 · 11:15–13:43 · 15:04–15:58 · 17:19–17:395.01.6Braindex, Chip Me
4 JulSat17:02–18:181.3allBraindex
5 JulSun00:54–01:14 · 10:39–11:28 · 15:02–19:385.7allBraindex
6 JulMon23:53–00:130.3allBraindex
13 JulMon00:22–00:42 · 21:40–22:511.5allBraindex
14 JulTue17:58–18:18 · 22:16–22:360.7allBraindex
15 JulWed08:05–08:25 · 21:40–23:252.11.7Braindex
28 JulTue18:37–19:32 · 21:01–21:211.2allBraindex
1 AugSat09:33–09:53 · 15:08–15:280.7allBraindex, BuzzScraper, Chip Me
2 AugSun11:59–12:190.3allBraindex
3 AugMon23:00–23:200.3allBraindex
4 AugTue22:52–00:542.0allBraindex, M50
5 AugWed07:38–08:14 · 20:45–22:222.22.0Braindex, BuzzScraper, M50
6 AugThu17:07–17:270.3allM50
7 AugFri09:42–10:020.30.0Braindex
8 AugSat07:46–08:080.4allM50
9 AugSun15:17–17:11 · 22:03–23:573.8allBuzzScraper, M50
10 AugMon20:47–23:262.7allBuzzScraper, Over the Bar
12 AugWed21:41–23:281.8allBraindex, BuzzScraper
13 AugThu23:19–23:390.3allOver the Bar
14 AugFri20:49–01:044.3allOver the Bar
15 AugSat12:25–12:49 · 14:59–17:05 · 19:17–23:296.7allBraindex, Over the Bar
16 AugSun00:39–01:55 · 10:44–11:041.6allOver the Bar
19 AugWed13:45–14:05 · 19:30–21:041.91.6Braindex
20 AugThu17:55–18:19 · 21:23–00:493.8allBraindex
23 AugSun09:37–10:29 · 13:18–14:14 · 15:57–16:45 · 23:05–01:254.9allBraindex, BuzzScraper
24 AugMon20:47–21:07 · 22:51–23:451.2allBuzzScraper
25 AugTue23:23–00:140.8allBraindex, Over the Bar
27 AugThu18:40–19:000.3allBraindex
28 AugFri22:21–00:552.6allBraindex
29 AugSat14:06–15:031.0allBraindex
51 sittings85.079.8

Read down the Windows column and the pattern is unmistakable. 21:00-something to 23:00-something, over and over, for four months. An hour here, forty minutes there, and then occasionally a Saturday that runs from lunchtime to half eleven at night.

The average build day is 1 hour 40 minutes. That is the honest unit. Six apps did not come from marathon sessions -- they came from ninety-odd minutes a night, four or five nights a week, with two or three of them open at once.

How the machine is actually laid out:

People ask about the tooling. The tooling matters less than the arrangement.

Figure 07

One window per app, and one job each.

Not tabs. Separate VS Code windows, each with its own folder, its own terminal, its own agent session, arranged so I can see which ones are thinking.

Window 1

The one I am in

Whichever app I am actively reviewing. This is the only window where I am reading diffs line by line and making calls. It moves between apps several times an evening.

Window 2

The one that is generating

An agent working on a task I described two minutes ago. I do not watch it. I come back when it is done. The whole trick is that this window is never empty.

Window 3

The one that is building

A Flutter build, a pod install, an IPA upload. Minutes of dead time each. Multiply by six apps and this is where the parallel gain actually comes from.

Browser

The admin lane

App Store Connect, Play Console, Firebase. Screenshots, declarations, review responses. This is what I do while the other three windows are busy -- it needs almost no thinking, and it is never finished.

Markdown

The memory

Every repo has a TODO.md, and the busy ones have PRIORITIES.md and NEXT-SESSION.md. This is where I put the state of my own head before I leave a window.

Phone

The truth

A real device with a TestFlight build on it. Simulators lie about signing, about haptics, about how a game actually feels in the hand.

The arrangement is the point. Three windows means that at any moment, two of them are working without me. My job is to be the one thing that cannot be parallelised: deciding what should happen next, and judging what came back.

Built with:

The same stack, six times
  • Flutter + Dart -- four of the six. One codebase, iOS and Android
  • HTML/JS + Capacitor -- M50 Speed Run, wrapped as a native iOS app
  • Claude Code -- the pair programmer in every window
  • VS Code -- one window per app, never tabs
  • Firebase -- auth, Firestore, analytics, security rules, in all six
  • Xcode + Transporter -- signing and upload

The repeated stack:

What every app needed anyway
  • Sign in with Apple + Google, plus guest play
  • A leaderboard that tolerates being offline
  • A streak, and the date logic that makes it honest
  • A share card worth sending to somebody
  • Analytics events, going to two places
  • Privacy policy, support page, account deletion page
  • Store screenshots, at two device sizes minimum

The hurdles that are specific to building in parallel:

The Braindex paper covered the ordinary ones -- CocoaPods, Xcode archives, Google Play's 14-day closed test. These five only show up once you are holding more than one app at a time.

1. You will hit the same bug twice, and the second time is the payoff.

On 18 May I spent a chunk of a day on Sign in with Apple failing silently in Braindex. The Apple identity-token nonce is single-use, and the manual credential flow tries to spend it twice on retry, which Firebase rejects. Three months later, on 15 August, the exact same bug appeared in Over the Bar.

The second time it took fourteen minutes. Three commits, 23:15 to 23:29, and the last one even says what it was: Fix Apple sign-in: the nonce was single-use and we were spending it twice. The first app pays the tuition. Every app after it gets in free. This is the actual compounding argument for building several -- not that you are faster, but that the problems stop being new.

2. Names drift when you are not looking.

Three of the five got renamed mid-build. "No Thanks!" became "Yes Please!" became Chip Me. "HEATLINE" became "M50 Traffic Chase" became M50 Speed Run. "Flappy Dash" became BuzzScraper. Each rename is not one commit -- it is the bundle ID, the display name, the icon, the privacy page, the store listing, the Firebase project, and something you will forget.

Fix: do not name the app on day one, but do lock the bundle ID on day one and never touch it. games.davidcarr.something is invisible to users and expensive to change. The visible name can drift for free until the day you submit; the identifier cannot.

3. Your apps start to look like each other.

When the same person builds six games in four months with the same tools, they converge. Every one of mine ended up with a leaderboard, a streak, sign-in, and a share card -- because that is what I knew how to build well, and because the pattern genuinely works. But there is a real risk of shipping the same app six times with different art.

What I do about it: force one thing per app that does not transfer. Over the Bar has real county and club data. M50 has a physical world that moves. BuzzScraper has a Mode 7 racer that has nothing to do with the rest of it. If an app has no component that would be useless in the other five, it probably should not exist.

4. Admin does not amortise. It multiplies.

This is the one that surprised me most. Six apps means six Apple review submissions, six Play data-safety forms, six age-rating questionnaires, six sets of screenshots at multiple device sizes, six privacy policies that must return HTTP 200, six delete-account URLs, six content ratings, six export-compliance declarations. None of it gets easier per app. It just happens six times.

Fix: build it as a pipeline, not a task. M50 has a committed screenshot-capture script and an App Store Connect uploader; Braindex now submits to Apple review through the ASC API. The first app where you automate the admin is the one that pays for the next five. Do it on app two, not app six.

5. You will ship something broken, because you were not looking at it.

On 20 August I found out Braindex was freezing on the launcher icon for some Android users. It had been live. I had not opened it on an Android device recently because I had been in three other repos. That is the honest cost of parallel: the app you are not in is the app you are not testing.

Fix: a pre-release gate that does not need me. Three days later I committed Add an Android pre-release gate that proves the app actually opens -- a script that boots an emulator, installs the build and confirms it launches, before anything ships. If you are running more apps than you can personally check, the checking has to become a machine.

What it actually costs:

I would not write this paper honestly without this section.

The chart in Figure 02 is a nice piece of evidence for a method. It is also a picture of a person who commits code at eleven at night, four nights a week, for four months. Peak hour 23:00. Second-place 22:00. Twenty-nine commits landed after midnight.

Nothing about this is free. The three-hour window is real, but it is the same three hours other people spend with their families, or asleep, or doing nothing at all, which turns out to be a legitimate and underrated activity. I have shipped six apps and I have also had evenings where I could not tell you what I did between 9pm and 1am other than "moved between windows".

The second cost is subtler. Parallel building is very good at breadth and quietly hostile to depth. Three of mine went from an empty repo to shipped in under a month, and M50 did it in five days. Braindex, the one I stayed with, is the only one with leagues, friends, live multiplayer, an ELO system I have now rewritten six times, and actual users doing actual things. The other five are real, shipped, and thin. The method got them born. It is not the method that makes them matter.

The third is that switching has a floor. Nine and a half minutes between commits sounds fast, and it is -- but a nine-minute unit of work is a nine-minute-sized thought. There are problems in Braindex I did not solve for weeks because they needed an unbroken two hours and I never gave them one. If everything in your week is nine minutes long, some things simply never get done.

So the honest version is this: parallel building is the right method for getting things into the world. It is the wrong method for making one of them great. You need both, and you need to know which one you are doing this evening.

What I would tell you before you try it:

Six things, in the order they would have saved me the most time.

1

Write your state down before you leave the window.

This is the whole skill and it is not a technical one. When you switch apps, the expensive thing you lose is not the code -- it is knowing what you were about to do. Every one of my repos has a TODO.md; the busy ones have PRIORITIES.md and a NEXT-SESSION.md that says, in plain sentences, what is broken and what is next. Thirty seconds of typing buys back twenty minutes of re-reading your own code tomorrow. Treat the markdown file as the handoff between two different people, because by tomorrow night it is.

2

Build the second app while the first is in review.

Apple review, TestFlight processing, Google Play's mandatory 14-day closed test -- these are days and weeks where the app is out of your hands and there is genuinely nothing to do. That dead time is not a gap in the schedule. It is the schedule. Every one of my apps after Braindex was started inside somebody else's review window.

3

Do the same job twice on purpose, close together.

On 9 August I wired Firebase into two apps ten minutes apart. On 12 August I stripped the advertising ID Firebase had added on its own out of BuzzScraper; four days later I did the same to Over the Bar and it took one commit. Doing a job while it is still warm is dramatically cheaper than doing it fresh in three weeks. If you know two apps need the same piece, schedule them on the same evening.

4

Automate the admin on app two.

Screenshots, listing copy, store uploads, review submission. It feels wasteful to script it the second time you do it, because scripting it takes longer than doing it. Do it anyway. By the fourth app you are getting the time back every week, and by the sixth the difference between "I could ship this" and "I did ship this" is entirely whether the boring part is a button.

5

Lock the bundle ID, let the name float.

Three of my five got renamed and every rename cost more than it should have. The user-visible name can change up to the day you submit -- that is free. The bundle identifier, the Firebase project, the package name: pick those on day one, make them boring, and never touch them again.

6

Know which evening you are having.

Parallel is for getting things born. It is a genuinely excellent method for that and I would defend it against anyone. But depth needs an unbroken two hours in one window with the others closed, and you will not get there by accident, because there is always another repo with something quick in it. Decide before you sit down: tonight I am shipping four things, or tonight I am fixing one thing properly. Both are good nights. Pretending you are having one while having the other is not.

All six are live.

Braindex, Pi Squared, Chip Me, BuzzScraper, M50 Speed Run and Over the Bar. If you would like to see what three hours a night for four months actually produced:

See all six apps
Thanks for reading! -- David

Where these numbers come from

Every figure in this paper is derived from the git reflog on my own laptop -- the record of what the machine actually did, timestamped in Michigan time. It covers the five apps I authored between 3 May and 29 August 2026. Pi Squared is excluded from the counts because I worked on a shared repository there rather than authoring it, so its history is not a fair measure of my own. Hours are estimated, not clocked: commits are grouped into sittings with a ninety-minute gap threshold, each sitting is credited twenty minutes of lead-in before its first commit, and every minute is then tested against Monday–Friday 08:00–17:00. That method will undercount thinking time away from the keyboard and overcount nothing. If you want the working, it is all in .git/logs/HEAD, which is a file I would encourage anyone to go and read about themselves.