Architecture & Scale
A mutual-aid social network built to scale from one Volta town to millions — Aurora DSQL at the core.
Ðekawɔwɔ — “the making of one” in Eʋegbe — is a community mutual-aid network where people Ask for help, Give help, and Wish for the support their town lacks. Its value compounds with every user (Metcalfe's law), and its data layer is engineered for that growth: Amazon Aurora DSQL as the globally-distributed, strongly-consistent social-graph core, specialised by PostGIS for geography and DynamoDB for the write-hot feed.
The problem
In Ghana's Volta Region, help already moves through community — but by word of mouth, limited to who you can physically reach. A welder two towns over who'd fix your roof never hears you need it.
The audience
Beta: ~180,000 residents of Ho and surrounding Volta settlements, across 11 languages. The pattern generalises to any community on earth.
The why
Mutual aid is the oldest social network. Digitising it without erasing it means respecting language, low-literacy access (voice-first), and that a connection is only valuable if it's local and trusted. That is a data-modelling problem before a UI problem.
System architecture
Three tiers: the browser talks only to the Vercel Next.js layer; the BFF holds the Cognito token server-side and is the sole caller of the AWS backend. Solid = sync, dashed = async geo-mirror. This is the event-driven Backends-for-Frontends pattern.
Three databases, three access patterns
Aurora DSQL
the social-graph core — 99.999% multi-region, snapshot-isolated
- Multi-region peered clusters — two active read-write endpoints, strong consistency.
- Snapshot isolation + OCC: conflicting concurrent writes detected at commit, not blocked by locks. Two helpers cannot both match the same ask.
- Virtually unlimited scale, scale-to-zero serverless — a beta town costs almost nothing between bursts.
- Phase 1 anchors in eu-west-1 + eu-west-2 for lowest latency to Ghana.
connectionsEvery Ask / Give / Wish authored by a usermatchesUNIQUE(ask_id, give_id) + OCC = no double-matchfollowsUser ↔ town — the retention engineusers.trust_scoreEarned by confirmed gives; consistent across regionsDynamoDB
the write-hot event feed
- Town-scoped partition keys spread write throughput naturally — no hot partition as the network grows.
- Single-digit-ms writes at any scale. Streams fan geo-tagged events into PostGIS via the geo-mirror Lambda.
- MRSC mode for the feed (globally-consistent reads). MREC for the audit log (eventual, last-writer-wins).
- TTL auto-expires ephemeral Drop-a-Pin sessions — no cron job needed.
activity-feedpk=TOWN#<id> sk=<event_id> — Streams → PostGISuser-actionspk=USER#<id> — per-user audit log, PITRephemeral-pinsTTL=expires_at — auto-expires when session endscollected-dataDemo submissions — write-once, on-demand billingAurora PostgreSQL + PostGIS
the geospatial engine
- GiST spatial indexes keep ST_DWithin and KNN sub-linear at any row count.
- Aurora Global Database: one primary + up to 10 read-only secondaries, typically under a second of replication lag.
- Aurora Serverless v2 backs readers — scales from 0 ACU to demand, idle secondaries cost nothing.
- RDS Proxy pools connections so thousands of Lambda invocations don't exhaust Postgres connections.
activity_geoGeo-mirror of DynamoDB feed — powers ST_DWithin 8kmtowns_geoKNN index — nearest settlement lookup for Drop a Pinresources_geoClinic / training / water points — radius searchservice_areasST_Intersects — which organisations cover my location?Consistency budget
Strong where correctness demands it. Eventual where latency matters more than precision.
The data layer is deployable AWS CDK + SQL in the repo: infra/sql/dsql-schema.sql, infra/sql/postgis-schema.sql, infra/lib/data-stack.ts.