Inspiration# The EdgeSense Story: Resilient, Offline-First AI for West Africa
💡 Inspiration
In much of West Africa, internet connectivity is not a constant guarantee—it is a fluctuating variable. Mobile data is expensive, power grids are prone to load-shedding, and rural communities frequently experience complete network dropouts. Yet, most modern AI applications are designed with the assumption of high-speed, persistent broadband. If a user loses signal mid-conversation, the app freezes, inputs are lost, and the utility of the AI drops to zero.
We built EdgeSense to change this paradigm. We were inspired by rural health workers, farmers, and solar technicians who need immediate, context-aware information in the field but cannot rely on a constant connection. Our goal was to design an application that adheres to a simple philosophy: act locally, sync globally. The interface should never freeze, data should never be lost, and the AI should remain useful even when offline.
🛠️ How We Built It
EdgeSense is divided into a resilient, edge-native client and a high-performance, containerized backend.
The Client (Edge-Native Frontend)
- Framework & State: Built on Next.js 15 and styled with Tailwind CSS. We utilized Zustand for lightweight, reactive state management.
- On-Device Storage: An IndexedDB database (managed via the
idblibrary) serves as our local data warehouse. It handles the local message history, cached replies, user settings, and the offline transaction queue. - Connectivity Lifecycle Hook: A custom React hook (
useConnectivity) actively monitors network status by combining standard browsernavigator.onLineevents with a silent 15-second background health-check ping to the backend. This ensures we detect "zombie networks" (connected to Wi-Fi, but with no internet access).
The Server (Alibaba Cloud ECS Backend)
- Architecture: Built with NestJS 10 for structured dependency injection and high performance.
- AI Integration: The
QwenServiceacts as the interface to Alibaba Cloud DashScope, utilizing theqwen-plusmodel via its OpenAI-compatible endpoint. - Database: A lightweight MySQL database hosted directly on the same Alibaba Cloud ECS instance. To remain fully operational and self-contained in sandbox/offline environments, we bypassed heavy ORMs in favor of a direct connection pool using the
mysql2driver, creating the database schemas dynamically on startup. - Process Management: The entire backend is containerized and kept alive on the ECS instance using PM2 configuration.
🔬 Mathematical Modeling of Offline Efficiency
To measure the impact of our offline-first architecture, we modeled bandwidth savings and sync efficiency.
1. Bandwidth Savings
Let $N$ be the total number of queries sent by the user, $H$ be the local cache hit rate ($0 \leq H \leq 1$), and $S_p$ be the average network payload size in kilobytes. The total network data saved ($D_{saved}$) by local cache resolution is:
$$D_{saved} = N \times H \times S_p$$
In testing, with repetitive queries regarding local troubleshooting guides, $H$ approached $0.42$, representing a 42% reduction in cellular data costs for the user.
2. Batch Sync Compression
When the device reconnects, rather than firing individual HTTP requests for every queued message, it packages them into a single batch payload. Let $T_{single}$ be the average round-trip HTTP overhead time (handshakes, headers, rate-limit evaluation), and $N_q$ be the number of queued messages. The synchronization time efficiency ($E_{sync}$) of our /api/sync batch endpoint compared to sequential requests is modeled as:
$$E_{sync} = \frac{N_q \times T_{single}}{T_{batch}}$$
Where $T_{batch}$ is the execution time of the single batch request. Because $T_{batch} \approx T_{single} + (N_q \times T_{inference})$, the network latency overhead is reduced to a constant factor ($O(1)$ connections instead of $O(N_q)$), yielding massive battery and connection-time savings on mobile devices.
🚧 Challenges We Faced
- The IndexedDB Upgrade Block: During development, we updated the client-side database schema. We noticed that when hot-reloading occurred, the browser blocked the database upgrade because of active open connections in other tabs. This froze the store's hydration process, resulting in a blank loading screen. We solved this by implementing a 1-second connection race timeout that automatically falls back to an in-memory database store if IndexedDB is blocked.
- Offline Dependency Constraints: Our development environment had strictly restricted network access. When updating the backend database connection to match Prisma 7 requirements, we realized the required
@prisma/adapter-mysqldriver could not be fetched. Rather than letting the system fail, we surgically refactored the entire data access layer of the NestJS backend to use raw SQL queries viamysql2, removing the Prisma runtime dependency entirely while maintaining the exact same service interfaces. - Multi-lingual Context Drift: Ensuring Qwen responded in the selected language (e.g., Nigerian Pidgin or Yoruba) required careful prompt engineering. If the language instruction was placed at the end of the prompt, the model occasionally defaulted back to English. We resolved this by restructuring our system prompt generation to place the language instruction as the absolute first sentence in the array, anchoring the model’s generation attention immediately.
📈 What We Learned
- The Power of the Edge: Moving database logic and state fallbacks to the client browser drastically improves user experience. The app feels instant because it doesn't wait for server round-trips to render interactions.
- Defensive Design: When building for unstable environments, you must assume every point of failure will occur. Health checks must be active, local databases must have in-memory fallbacks, and sync protocols must be transactionally safe.
- Model Adaptability: Tapping Alibaba's Qwen model allowed us to support local dialects (like Nigerian Pidgin) with high natural accuracy, making AI feel native rather than foreign to West African users.
Built With
- alibaba-cloud
- alibaba-cloud-ecs
- alibaba-dashscope
- css3
- git
- html5
- indexeddb
- javascript
- json
- mysql
- nestjs
- next.js
- nginx
- node.js
- pm2
- qwen
- react
- rest-api
- tailwindcss
- typescript
- zustand
Log in or sign up for Devpost to join the conversation.