GeoBloodA blood request should reach the right nearby donor in seconds, not after a night of phone calls.
request · locating donors
click the map to post a requestGeoBlood exists because of a family medical emergency where finding a matching blood donor took dangerously long. That search is normally a chain of phone calls, WhatsApp forwards and hospital noticeboards. It is slow, it leaks personal numbers, and none of it is verified. The organisation's stated mission is blunt: no one should lose their life due to lack of blood availability.
The engineering problem underneath that is a matching problem with a hard deadline. A request has to reach donors who are actually compatible, actually nearby, and actually real, and it has to do that while the requester is standing in a hospital corridor.
A blood request is not a broadcast. Spamming every user in a city destroys trust and gets the notification permission revoked within a week. So the match narrows before it notifies.
Blood type is a directed graph, not an equality check
O negative can give to anyone. Everyone else cannot. The rule lives in one place on the server.
Geospatial query, not a city string
Distance is computed, indexed and sorted server-side so the nearest eligible donor is first, not alphabetical.
Unverified accounts never enter the pool
Verification is checked at match time, so an account that lapses drops out immediately.
Not every request is equal
Critical requests get a higher push tier and a wider radius. Routine ones do not wake anyone up.
Contact details never change hands
Encrypted in-app messaging plus emergency calling, with no phone number exposed on either side.
| Layer | Built with | What it has to survive |
|---|---|---|
| iOS app | Swift, MVVM | App Store review cycles, Sign in with Apple requirements, permission prompts the user can deny, and a phone that is asleep when the notification arrives. |
| Android app | Java, Kotlin | Fragmented devices and aggressive OEM battery managers that kill background delivery. |
| API layer | Node.js, Express | Matching, request workflow, auth and admin operations under bursty traffic when a request goes out. |
| Data | MongoDB, Redis | Geospatial queries fast enough to run inside a request, with Redis absorbing the repeated reads. |
| Real time | Socket.IO | Chat and live request status across reconnects, backgrounding and flaky mobile networks. |
| Push | FCM, APNs | Two delivery systems with different failure modes, retried per-platform and never silently dropped. |
| Auth | Apple, Google, JWT | Account recovery and session integrity across two platforms and a web dashboard. |
| Admin | React | Verification queue, request moderation and platform data, used by volunteers rather than engineers. |
| Infra | AWS, Firebase | A nonprofit budget. Sized for the load it has, with headroom for the country it launches in next. |
GeoBlood on Instagram
Tap to load the reel from @geobloodorg
Loads directly from Instagram. Nothing is requested until you click.
Or open it on Instagram directly ↗






A blood app that is down is worse than no blood app, because someone was relying on it.
I wrote up the geospatial matching design in more depth: Matching Blood Donors by GPS: The Geospatial Query Design Behind GeoBlood ↗
Happy to go through the matching model, the push reliability design or the App Store compliance path on a call.