← Writing · Civic & Democratic Infrastructure
Flux Working Paper No. 31

Building Nairobi a Second Time: Notes From a Week of Shipping the Twin

Ken Ruto · Flux (FluxImpact) · July 2026 · 21 min · Updated Oct 2026 · 69 reads · 0% finished
Revision history
2026-10-02 — full working-paper revision: scope/method section distinguishing this process account from the reproducible measurement in its companion papers, a new section on the surprising height-validation result that arrived after this week ended, an objections section (incl. Flux's commercial interest and a direct answer to why an unflattering finding leads the diary), falsification conditions, limitations, evidence table and citation register. Two prior sources already verified in this series (Herfort et al. 2023, Watson & Elliott 2025) are footnoted here for the first time rather than left as an unnamed "academic paper" and an uncredited validated figure. 2026-08-26 — added a custom figure.
Read as paper ↗
BibTeX · RIS
Civic & Democratic InfrastructureOffline-first / every fact sourced

I want to write down how this actually went, while it's fresh, because the finished pages make it look cleaner than it was. In one week, KaNairo — our Nairobi digital twin — went from a stylized 3D diorama of about a thousand CBD buildings to a real, pannable map of 1,277,511 buildings covering the whole metro, with a working billboard-rental business on top and three Working Papers documenting the pipeline.1 This essay is the part the papers leave out: the order things actually happened in, what broke, and what I'd tell someone attempting the same thing for their own city.

KANAIRO://WP30 — A WEEK, LOGGED HONESTLY ONE WEEK, CBD TO METROMON1,026TUECSP FIGHTWEDGEOPARQUETTHUTILE GRIDFRI$1.99 BILLBOARDSATSTREAMINGSUN1.27M THE DEAD ENDS ARE IN HERE TOO. A $1.99 BILLBOARD TAUGHT ITS OWN LESSON. One week, logged day by day — dead ends included.

1. What this account is, and what would refute it

This paper is a different kind of evidence than the three it accompanies, and the difference is worth stating plainly before the narrative starts, rather than letting the first-person voice imply a stronger warrant than it has.

What this is. A contemporaneous process account — written the week it happened, from commit timestamps, error logs, and my own notes — of the engineering sequence that took the Nairobi twin from roughly 1,000 CBD buildings to 1,277,511 across the metro. The specific technical findings it reports (the building counts, the tile-store size, the source-coverage split between Kibera and Mathare, the height-measurement validation) are not re-derived here; they are the same measurements reported and sourced in WP27, WP28, WP29 and WP32, carried forward by reference rather than re-argued.

What it argues from. My own record of what broke and in what order, which is the only kind of evidence a process account can offer — it is not independently checkable the way a dataset query is, and I say so rather than dress it up as more than it is. Where this essay states a number, it is citing one of the four companion papers above, not asserting a fresh one.

What it does not argue from. It does not claim the three lessons in §7 are general findings about African civic-data projects. They are one team's inferences from one week building one twin, offered as a starting hypothesis for the next builder to test against their own city, not as a result.

What would refute it, as a process account. If the commit history or error logs this essay is drawn from turn out not to support the sequence described — if, for instance, the CSP fix actually preceded the billboard feature rather than following from it, or the Mathare check happened before rather than during this week — that would be a factual error in this specific paper, correctable against the repository's own history, and distinct from anything in the companion technical papers, which stand or fall on their own evidence.

What would refute the lessons in §7. Given in full in §10. The sharpest version: a builder who replicates this approach for a different African city, using a single un-merged data source rather than a merged one, and finds no meaningful coverage gap between settlements with and without a volunteer mapping history, would undercut the second lesson specifically — that merged data matters because single-source data inherits attention bias.

2. It started with a joke that needed real estate

The chain of causation is honestly a little absurd. We had a $1.99 joke — rent a billboard in the 3D scene — that sold slots on an invented ring road with fifteen fixed positions. Making the joke better meant making the real estate real: actual streets, actual coordinates, "what's available and where." That pulled in OpenStreetMap road data and a real map (MapLibre, OpenFreeMap tiles — no API keys, which matters when you run everything on one small server). Suddenly billboards sat on Uhuru Highway because the data said Uhuru Highway was there.

And once one layer was real, the unreality of the rest started to itch. The 3D scene's thousand buildings were real too — but only for 1.5 square kilometers of a city of hundreds. The map claimed "Nairobi." It showed the CBD. That gap is the whole project, in miniature: the difference between looks like and is.

3. The week's actual sequence, with the failures left in

The CSP fight. The first time the real map loaded, it didn't — a blank beige rectangle. Our site ships a strict Content-Security-Policy, and the tile host wasn't on the allowlist. The fix was two lines, scoped to just the map pages. Then it happened again on the second map page a few days later, because I'd scoped the first fix to exactly one URL path. Strict security policies are like good fences: you notice them exactly as often as you climb over them.

The SSL certificate maze. Both the Overpass fetch script and the Overture download tripped on the same macOS Python quirk — no usable certificate bundle for urllib. Same fix twice (certifi), because I didn't generalize the first time. There's a lesson in there I keep re-learning.

The 406 that wanted a name. Overpass rejected our building-inventory fetch with HTTP 406 until the request carried a proper User-Agent identifying who we were and how to reach us. Fair enough — free public infrastructure deserves to know who's leaning on it. It's the polite-society version of an API key.

The data pull that just worked. Against expectations, the big one was easy: Overture Maps shipped 1.27 million building footprints for a bounding box covering Karen to Embakasi in a few minutes, as GeoParquet, free — the full pipeline and its exact figures are WP27's subject. Ten years ago this dataset wouldn't have existed; five years ago it would have been a grant proposal. This is the part I want other African builders to hear: the data is sitting there now. The moat isn't access anymore. It's the will to do something with it.

The Mathare check. While researching sources I hit an academic paper noting Mathare had no buildings in OpenStreetMap.2 We had the data on disk to check that claim in minutes, so we did: it's outdated — Mathare has 5,061 buildings in the merged dataset now — but 70% of them exist only because Google's satellite model saw them. Kibera, same informality, same city: 82% human-mapped, because Map Kibera has been at it for fifteen years. That one comparison became its own paper, and it's the finding from this week I actually care most about. Volunteer map coverage tracks where attention already went. Build on it alone and you inherit its blind spots.

The tile store. You cannot hand a browser 1.27 million buildings in one file. (The v1 scene hands it a thousand, in one file, and that's fine. Scale changes kind, not just degree.) The answer is the oldest trick in web cartography — cut the city into tiles, stream only what's visible — applied to building footprints: a 400m grid, 8,536 tiles, one SQLite file, 68.5MB. The map fetches maybe twenty tiles for a typical viewport. Pan, and it fetches the next few. "1:1 but light" stops being a contradiction the moment you stop loading the whole city at once. The full tiling architecture is documented separately.

The heights problem, deferred honestly. Of 1.27 million buildings, 4,203 had a real height on record that week — 0.3%. A validated fix existed in principle — Google's height raster, independently shown to reach 2.49 metres mean absolute error for Nairobi specifically against laser-altimetry ground truth3 — but it needed Google Earth Engine access we had not set up yet. The choice was: block everything on that, fake it and say nothing, or estimate visibly. We estimated — settlement patterns, distance from the core, land-use — and every single building carried a confidence label, rendered as colour on the map. 73.5% of the city sat in the lowest tier. That number went in the heuristic paper's first table, not a footnote. If the twin's whole pitch is honesty about what the city knows about itself, it doesn't get to lie about what it knows about the city. (The Earth Engine integration landed later than this week; by the time it did, it produced the 73.6%-measured result and the 6.84-versus-2.49-metre discrepancy WP32 reports — a result this week's team did not yet know was coming.)

4. What this week felt like from the inside

It is worth saying plainly what the companion technical papers, by design, leave out: this did not feel like executing a plan. It felt like reacting, in sequence, to whatever the previous day's decision had just made necessary. The billboard joke did not come with a roadmap to "digital twin of a city." It came with a need for one more real street, which needed a real map, which needed a CSP fix, which, once the map was real, made the fakeness of everything else unbearable to look at. Each step was locally obvious and the whole sequence was not visible from the start.

I flag this because it bears on how to read the lessons in §7. They are reconstructed after the fact, from a sequence that was not planned as a sequence. That does not make them wrong, but it means they are closer to "what a pattern-matching retrospective finds" than to "what we set out to prove," and the difference matters for how much weight a reader should put on them.

5. What broke that the companion papers do not mention

A few smaller failures did not make it into the technical write-ups because they were operational rather than architectural, but they shaped the week as much as the big ones.

The billboard inventory map briefly showed duplicate slots after a tile-regeneration run overlapped with a live request — a caching bug, not a data bug, fixed by making regeneration atomic (write to a temp file, then rename). It is the kind of failure that is invisible in a finished product and would have been embarrassing in a demo.

The first version of the confidence-tier colour legend used a colour-blind-hostile red-to-green gradient for "trust this estimate" to "do not trust this estimate" — caught in review, not caught by design, and replaced with a colour scheme distinguishable without colour vision at all. I mention it because it is a small, concrete instance of exactly the kind of silent exclusion this series argues against in its own bigger claims: an honesty feature (visible confidence tiers) that would have been inaccessible to some of the people it was built to inform.

6. What happened in the weeks after this one

This essay is deliberately scoped to one week, but it would be dishonest to leave the impression that the story stopped there, so I want to say briefly what came next without pretending it happened inside the window §1 describes.

The Earth Engine access this week's team flagged as missing did eventually get provisioned, and when it did, the result was not the clean validation we had hoped for. WP32 reports that the measured heights disagreed with Overture's own surveyed-height attribute by 6.84 metres on average — worse than the 2.49-metre error the same dataset achieves against independent laser-altimetry ground truth, which flips the expected story: the "surveyed" attribute, not the satellite estimate, turned out to be the less trustworthy of the two sources for Nairobi. Nobody on this week's team predicted that outcome. We assumed, reasonably but wrongly, that once the real raster was in hand the main remaining work would be swapping it in for the confidence-tier estimate and calling the height problem solved. It was not that simple, and I think it is worth recording that the simple version of the plan — "estimate now, measure properly later, done" — undersold how much judgement the "measure properly" step would still require once it arrived.

I raise this here, in a paper otherwise about one week, because it is a useful corrective to how clean this account might otherwise read. The CSP fix, the certificate fix, the 406 error — these are the kind of problems that, once solved, stay solved. The height problem was not that kind of problem. Solving it revealed a second, harder question underneath, and that is a more honest note to end this part of the record on than a tidy "and then it was fixed."

7. What I'd tell someone doing this for Kampala or Kigali or Lagos

Three things, held to the standard of §1: these are hypotheses from one week on one city, not validated findings.

First: start with the joke, or whatever your version of the joke is. The billboard product forced every piece of real infrastructure this week rests on — real coordinates, real streets, a working payments loop, an inventory model. A "civic data platform" pitch deck forces nothing. Small real things beat large imagined ones.

Second: merged data, or you are mapping attention, not the city. If we had built on OpenStreetMap alone — the obvious, default choice — Mathare would have been nearly invisible on our map, and we would never have known, because absence does not announce itself. The companion paper makes this case with the actual source-composition numbers rather than the anecdote; I am restating it here only as the lesson I took from living through it.

Third: label your uncertainty and ship. The alternative to estimated-with-confidence-tiers was not measured heights. It was either nothing at all, or estimates dressed up as facts. Naming what you do not know is what buys you the right to ship before you know everything — and it converts every future data improvement into a visible upgrade instead of a quiet correction.

8. Objections I take seriously

"This is a marketing narrative dressed as a methods paper." That is a fair reading of a first-person engineering diary, and I want to meet it directly rather than deny it. The defence is narrow: every specific number this essay repeats is sourced to one of the four companion papers, which carry their own evidence, their own validation, and their own limitations sections independent of this one's narrative framing. What is not independently verifiable is the sequencing and the texture — which bug came first, what the CSP error actually looked like on screen — and I am not claiming that part is anything more than my own contemporaneous account.

"The three lessons in §7 are a sample size of one, generalised past what it supports." Largely correct, and stated as a limitation rather than disputed. One team, one city, one week does not establish that every African city-data project should start with a monetisable joke, use merged datasets, or label uncertainty visibly. It establishes that doing those three things worked once, under conditions this paper describes as fully as it can. §10 gives the test that would actually settle the generalisation question.

"Flux has a commercial interest in this conclusion." Flux sells the twin this essay is a diary of building, including the billboard-rental feature the narrative opens with. That conflict is direct and worth stating without softening: a company with a product to sell has an obvious incentive to tell its own build story as a sequence of scrappy, ultimately vindicated decisions. The mitigation is the same one the companion papers rely on — the specific, checkable claims (building counts, tile-store size, source-composition percentages, height-validation error) are reported and sourced in papers that state their own falsification conditions and limitations independently of this one. What this essay adds on top of those — the narrative of which problem came first and what it felt like — is explicitly framed in §1 as not independently checkable, and a reader should discount it accordingly rather than take the commercial narrative's confidence as evidence of the underlying technical claims' strength.

"Calling the Mathare gap 'the finding I care most about' is a strange thing for a company diary to foreground, if the goal is to sell the twin." I think this objection has it backwards, but it deserves an answer rather than a dismissal. A product diary optimised purely for sales would foreground the billboard revenue mechanic or the scale number (1.27 million buildings), not a finding that complicates the data the product is built on. I foreground it because it is the most important thing this week actually taught the team, independent of whether it helps or hurts the pitch — and because a company that only publishes the findings convenient to its sales narrative is exactly the kind of institution this series argues against elsewhere.

9. Where this leaves the twin

The render half of the twin now genuinely covers the city — every neighbourhood, informal settlements included, streamed fast. The institutional half — live data, real queries, the write-side work WP32 names directly — remains the actual mountain, unchanged. But the foundation under the visible half is real now in a way it was not a week before this account begins: real footprints, real provenance, honest heights, and an architecture that can carry whatever layer comes next — water, transit, flood risk — without re-plumbing.

The billboard is still $1.99. It is still a joke. It now sits on a map of one and a quarter million real buildings, which I would argue makes it a better joke — and, quietly, a demo of the write-side mechanic the whole civic thesis needs. You point at a real place, you say what should be there, and the model changes. This week that is a billboard. The version worth years of work is a water ticket. Same mechanic. We are practising.

That analogy only reaches so far, and it is tempting to overstate it. A billboard rental and a water-fault ticket both write a new fact onto a real place on a real map, and both make that fact visible to the next person who looks. That is the full extent of the similarity. A billboard rental closes itself — money changes hands, a slot is reserved, nobody downstream has to act on the claim for it to be true. A water-fault ticket does not close itself. It only matters if a utility reads it, assigns it, and a crew acts on it, which requires an institution on the other end that has agreed to treat the ticket as real. WP32's closing argument is that this is precisely the distance between "writable" and "writable and read" — and nothing about shipping the billboard feature this week narrows that distance at all. What it narrows is a different, more modest thing: it proves the mechanic — point, claim, model updates — works end to end on real data, which is a necessary component of the harder version and not a substitute for it.

That is a smaller claim than "we are most of the way to the water ticket," and I would rather end this account on the smaller, accurate claim than the larger, flattering one.

10. What would falsify the lessons drawn here

Stated as commitments, in decreasing order of how much damage each would do to this essay's claims.

A builder replicates this approach for another African city and finds that starting from a small, monetisable feature produced worse outcomes — slower, less real infrastructure, a narrower final scope — than starting from an explicit platform plan. That would falsify the first lesson in §7 directly, and I would withdraw the "start with the joke" recommendation rather than qualify it into irrelevance.

A replication using a single, un-merged data source for a different city finds no meaningful coverage gap between settlements with and without a volunteer-mapping history. That would falsify the second lesson, and would also sit in tension with WP28's own finding for Nairobi specifically, which this essay leans on rather than re-derives.

A review of this project's own commit history or issue tracker contradicts the sequence of events described in §3–§5 — for instance, if the Mathare check demonstrably happened in a different week, or the CSP fix preceded rather than followed the billboard feature. That would be a factual correction to this specific essay, not to the companion technical papers, whose claims do not depend on this narrative's sequencing.

A comparable project ships without visibly labelling estimate confidence and suffers no loss of trust or usefulness as a result, in a context otherwise similar to this one. That would weaken, though not fully falsify, the third lesson — it would show the visible-confidence approach is not strictly necessary, even if it remains one reasonable choice.

11. What one week's diary can't establish

The sequence described in §3 is not claimed as the only way, or the best way, to build a city-scale digital twin — it is a record of one way, under one set of constraints (a small team, one capacity-constrained server, a one-week informal timeframe).

None of the building-count, source-composition, or height-validation figures repeated here are independently verified in this essay; those are claimed and sourced in WP27, WP28, WP29 and WP32, and this essay's role is to carry them forward with narrative context, not to re-establish them.

The three lessons in §7 are hypotheses drawn from a sample of one project, not validated findings. §8 and §10 both say so directly.

Nor does this resolve, or substantially advance, the write-side problem the closing section names — that remains exactly as open as the companion papers describe it.

And this is not a neutral account. §8 states the commercial interest directly rather than leaving a reader to infer it.


Appendix A — Evidence table

Every figure in this row-set is sourced to a companion paper rather than measured fresh here; this essay's contribution is sequencing and narrative, not new measurement, so the "source" column points outward in every row that carries a number.

# Claim used in this paper Value Source
1 Buildings in the v1 CBD-only render ~1,026 WP27
2 Buildings in the v2 metro-wide extract 1,277,511 WP27
3 Tile-store size and tile count 68.5 MB, 8,536 tiles WP27
4 Buildings with a directly recorded height, at the time of this week's work 4,203 (0.3%) WP29
5 Share of the metro in the lowest height-confidence tier 73.5% WP29
6 Kibera buildings sourced from OpenStreetMap 82% (6,706 of 8,130) WP28
7 Mathare buildings sourced from OpenStreetMap 16% (794 of 5,061) WP28
8 Open Buildings Temporal MAE vs. laser-altimetry ground truth, Nairobi 2.49 m Watson & Elliott 20253, via WP32
9 Whether the "start with a monetisable joke" lesson generalises beyond this one project — —
10 Whether the exact sequence in §3–§5 matches this project's commit history in every particular — —

Appendix B — Citation register

CITATION-NEEDED — generalisability of the three lessons in §7. Appendix A row 9. These are a retrospective team's hypotheses from one city, one week, stated as such in §1, §8 and §10; no second project's outcome yet exists to check them against.

CITATION-NEEDED — independent verification of this essay's own sequencing. Appendix A row 10. The order of events in §3–§5 is drawn from this author's contemporaneous notes and the project's commit history, not independently audited by anyone outside the team; §10 names the correction that would follow if a closer read of that history disagreed.

  1. WP27, WP28 and WP29 — the tile-streamed pipeline, the settlement coverage-gap finding, and the height-estimation heuristic this week produced, each with its own sourcing and validation.↩

  2. Benjamin Herfort, Sven Lautenbach, João Porto de Albuquerque, Jennings Anderson and Alexander Zipf, "A spatio-temporal analysis investigating completeness and inequalities of global urban building data in OpenStreetMap," Nature Communications 14, article 3985 (2023), doi:10.1038/s41467-023-39698-6. WP28 checks its Mathare observation against current data directly; this essay only records when and why that check happened.↩

  3. C. Scott Watson and John R. Elliott, "Narrowing the gap for city building height predictions," Scientific Reports 15, article 29913 (2025), doi:10.1038/s41598-025-15929-2. The validated figure this week's team knew about but had not yet integrated; WP32 reports the integration and the resulting discrepancy against Overture's surveyed-height attribute.↩

Ken Ruto
About the author
Ken Ruto

Founder of Flux. Building vertical AI-powered SaaS for Africa's institutions — and writing the thesis behind every bet. kenruto.fluximpact.org →

Share X LinkedIn WhatsApp
This paper is about this

KaNairo is the live twin this series describes — 1.27M real building footprints, real streets, real traffic. Walk it yourself rather than take the paper's word for it.

Did this land?
Was it useful?

Comments

No comments yet — be the first.

Replying to · cancel
Get new essays

No spam — just the next piece when it's out.

Think I got something wrong? Highlight any sentence to push back on it — or It comes straight to me, never shown publicly.

Push back
The Nairobi twin series
22 min
The Twin Nairobi Doesn't Have Yet
We let people pay $1.99 for a joke billboard in a toy 3D Nairobi. It's a working model of the real feature: a twin residents can act on, not just admire — and what "1:1" actually requires.
22 min
From the CBD to All of Nairobi: A Tile-Streamed Building Pipeline for a City-Scale Twin
1,026 CBD buildings became 1.27 million metro-wide, streamed tile by tile from three merged datasets that a 2024 peer-reviewed study finds are "not interchangeable" — completeness bought, accuracy not yet claimed.
22 min
Who's Missing From the Map: Building-Footprint Coverage Gaps in Nairobi's Informal Settlements
Kibera: 82% of its buildings are human-mapped. Mathare: 16%. The difference is not population or need — it is whether a settlement ever had a named, sustained, resident-led mapping campaign.