The system outlived every assumption in it
Dinamo ran in production for four years — first commit December 2020, last January 2025. I wasn’t there for all of it: I joined the codebase in August 2023 and my work runs to the final commit, concentrated on the parts that decide whether a driver actually receives a trip.
Two apps, driver and rider. Two brands — “go” and “wasalni” — built from one codebase via product flavors rather than forked. Worth being precise about what’s shared and what isn’t: the code is shared across brands; the backend is not. Each brand points at its own domain, and driver and rider of the same brand meet there.
The part that actually mattered
A ride-hailing driver app has one job that cannot fail: notice that a trip exists. On Android, that is genuinely hard — the OS is actively trying to stop you.
The September 2024 rebuild of the driver app’s trip-fetching is a three-layer answer, and each layer covers a different way the first one dies:
- A foreground service drives the 30-second cadence and returns
START_STICKY, so Android tries to restart it if it’s killed. - Each tick’s actual work runs as a WorkManager job, so a single fetch completes or retries independently of whether the service survived long enough to see it through.
- A boot receiver restarts the whole thing after a reboot.
The location service is a separate process writing coordinates to shared preferences; the fetch worker reads them to bias its request. The two never talk directly, which is why one can die without taking the other with it.
What this is not
START_STICKY is a request to the operating system, not a guarantee. Aggressive OEM process-killers — very common on the devices this shipped to — can still prevent a restart, and there is no battery-optimisation whitelist prompt in this codebase. The architecture is honest about its intent; it isn’t bulletproof, and no amount of foreground-service discipline makes it so.
What four years of version history actually shows
Driver app reached versionCode 83, rider app 116. It’s tempting to describe that growth as accumulated battery engineering — it isn’t. Reading the commit history back, the recurring theme is state after death: crashes on relaunch, stale caches producing “not available in your area,” notification handling that dropped work when the process was recycled.
That’s a less glamorous story than battery tuning and a more useful one. The bugs that survive four years in production are the ones about what your app remembers when the OS decides it no longer exists.