{
"title": "Building a CFA Study Platform That Actually Works on African Mobile Networks: SharkFlow's Technical Deep Dive",
"content": "# Building a CFA Study Platform That Actually Works on African Mobile Networks: SharkFlow's Technical Deep Dive\n\nPreparing for the CFA exam is brutal. Doing it on a 2G connection in Nairobi? That's a different kind of hell.\n\nWhen we started building SharkFlow's CFA preparation module, we realized most EdTech platforms treat African markets as afterthoughts. They optimize for Wi-Fi. They assume reliable power. They ignore that Kenya's 60M+ mobile money users work on devices with 512MB RAM and unstable networks.\n\nThis article breaks down how we engineered a CFA study platform that doesn't just *exist* in Africa—it genuinely thrives here.\n\n## The Problem We Solved\n\nThe CFA curriculum is dense: 300+ hours of study across derivatives, portfolio management, ethics, and quantitative methods. Traditional platforms require constant connectivity and heavy data transfer. In Kenya, where mobile data costs ~KES 50 ($0.38 USD) for 100MB, every kilobyte matters.\n\nWe had three non-negotiable constraints:\n1. **Work offline-first**: Download once, study everywhere\n2. **Handle ~10Mbps fluctuations**: Network conditions are real\n3. **Scale to 50,000 concurrent users** without melting our infrastructure\n\n## Our Architecture: Offline-First by Default\n\n### Progressive Data Sync\n\nWe built a two-tier content system:\n\n```
typescript\n// Content strategy: Cloud-sourced, device-stored\ninterface ContentTier {\n tier1: {\n size: '85MB',\n content: 'Core curriculum (Ethics, Quantitative)',\n syncStrategy: 'aggressive_prefetch',\n frequency: 'weekly'\n },\n tier2: {\n size: '250MB',\n content: 'Full question banks + video lectures',\n syncStrategy: 'background_sync',\n frequency: 'on_demand'\n },\n tier3: {\n size: '15MB',\n content: 'Real-time market data + performance analytics',\n syncStrategy: 'delta_sync',\n frequency: 'hourly'\n }\n}\n
```\n\nUsers can start studying immediately with Tier 1 (~85MB), which covers the essentials. Tier 2 downloads in the background during low-cost hours (most Kenyan carriers offer off-peak data). Tier 3 syncs only when connected.\n\n### Smart Compression\n\nOur content pipeline compresses ruthlessly:\n\n```
python\n# Content compression strategy\nclass ContentCompressor:\n def compress_materials(self, material_type: str):\n if material_type == 'video':\n # H.265 codec, 480p target (not 4K)\n # Bitrate: 800kbps (vs 5Mbps standard)\n return self._transcode_video()\n \n elif material_type == 'pdf':\n # Remove embedded fonts, compress images\n # Target: 60% size reduction\n return self._optimize_pdf()\n \n elif material_type == 'questions':\n # Plain JSON with heavy gzip\n # 10,000 questions = 12MB (uncompressed: 85MB)\n return self._serialize_questions()\n
```\n\nOur question bank of 10,000 CFA questions compressed from 85MB to 12MB. That's the difference between \"I'll download later\" and \"done in 2 minutes.\"\n\n## Database Architecture: SQLite Locally, PostgreSQL Globally\n\nMost EdTech platforms use Firebase or MongoDB. Both are overkill and expensive at scale in Africa.\n\nWe use a hybrid:\n\n```
sql\n-- Local SQLite schema (device-side)\nCREATE TABLE questions (\n id INTEGER PRIMARY KEY,\n level INTEGER, -- L1, L2, L3\n topic TEXT,\n question_text BLOB, -- Compressed\n answers BLOB,\n explanation BLOB,\n last_reviewed INTEGER,\n performance_score REAL,\n FOREIGN KEY(topic) REFERENCES topics(id)\n);\n\nCREATE INDEX idx_topic_level ON questions(topic, level);\nCREATE INDEX idx_performance ON questions(performance_score);\n\n-- User progress (syncs bidirectionally)\nCREATE TABLE sync_queue (\n id INTEGER PRIMARY KEY,\n action TEXT, -- 'quiz_completed', 'bookmark_added'\n payload BLOB,\n timestamp INTEGER,\n synced BOOLEAN DEFAULT 0\n);\n
```\n\n**Why SQLite?**\n- Zero setup. Instant. ~300KB footprint.\n- Handles 100K+ records per device without breaking a sweat\n- Built-in on iOS and Android\n- Sync conflicts? We handle them client-side with timestamp-based resolution\n\n**Backend (PostgreSQL):**\n\n```
sql\n-- Aggregates user progress across 50K students\nCREATE TABLE user_performance (\n user_id UUID PRIMARY KEY,\n level_1_score REAL,\n level_2_score REAL,\n level_3_score REAL,\n total_questions_answered INTEGER,\n last_active TIMESTAMP,\n device_type TEXT, -- iOS, Android, Web\n region TEXT -- For performance tracking\n);\n\nCREATE MATERIALIZED VIEW topic_difficulty AS\nSELECT \n topic,\n AVG(performance_score) as avg_difficulty,\n COUNT(*) as attempts,\n PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY time_spent) as median_time\nFROM user_attempts\nGROUP
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)