System Architecture
Understanding Nuraan's technical foundation and data flow
Overview
Nuraan follows a microservices architecture pattern with clear separation between data ingestion, processing, storage, and visualization layers. The system is designed for horizontal scalability and high availability during crisis situations.
┌─────────────────────────────────────────────────────────────────┐
│ Client Layer │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Web App │ │ Mobile App │ │ API Client │ │
│ │ (Next.js) │ │ (Future) │ │ (External) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│ HTTPS
┌─────────────────────────────▼───────────────────────────────────┐
│ API Gateway (Caddy) │
│ Automatic TLS, Load Balancing │
└─────────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────────▼───────────────────────────────────┐
│ Application Layer (FastAPI) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Auth API │ │ Geo API │ │ Analytics │ │
│ │ │ │ │ │ API │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────────▼───────────────────────────────────┐
│ Data Layer │
│ ┌──────────────────────┐ ┌──────────────────────┐ │
│ │ PostgreSQL/PostGIS │ │ ClickHouse │ │
│ │ (Spatial Data) │ │ (Time-series Data) │ │
│ └──────────────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
Component Details
Web Application
- Framework:
- Next.js 16 with React 19
- Map Library:
- MapLibre GL + Deck.gl
- State Management:
- Zustand
- Styling:
- Tailwind CSS 4.0
API Service
- Framework:
- FastAPI (Python 3.12)
- ASGI Server:
- Uvicorn
- Connection Pool:
- asyncpg
- Validation:
- Pydantic
Spatial Database
- Engine:
- PostgreSQL 16
- Spatial Extension:
- PostGIS 3.4
- Data Types:
- Geometries, Boundaries
- Indexes:
- GIST, B-tree
Time-series Database
- Engine:
- ClickHouse 24.3
- Storage:
- Column-oriented
- Data Types:
- CDR Events, Metrics
- Compression:
- LZ4, ZSTD
Data Flow
1 Data Ingestion
CDR data is ingested through secure API endpoints with validation and anonymization. Raw events are immediately written to ClickHouse for time-series storage while aggregated metrics are computed and stored in PostgreSQL.
2 Real-time Processing
Incoming data triggers real-time aggregation pipelines that compute population density, movement patterns, and service coverage metrics. Spatial joins with administrative boundaries happen at query time for flexibility.
3 Visualization
Processed data is served through RESTful APIs with GeoJSON responses for map rendering. The frontend uses MapLibre GL for efficient WebGL-based rendering of large datasets with client-side interactivity.
Scalability & Performance
ClickHouse can handle billions of events with sub-second queries
Connection pooling and query optimization ensure fast responses
Stateless API design allows adding nodes as needed
Performance Optimizations for ADM4
Map Rendering Optimizations
- • Viewport-based Loading: Boundaries fetched only for visible area using bbox
- • Dynamic Simplification: Lower zoom levels use simplified geometries (simplify_tolerance)
- • Pan/Zoom Refetch: Data updates on moveend events for efficient loading
- • Lighter Basemap: Tuned raster brightness/contrast/saturation for better readability
Database Optimizations
- • Spatial Indexing: GiST indexes on PostGIS geometry columns
- • Cascade Truncation: TRUNCATE TABLE admin_areas CASCADE for safe reloads
- • Flexible Schema: Same table/API supports both ADM3 (544 areas) and ADM4 (higher detail)
API Optimizations
- • Connection Pooling: Persistent database connections reduce overhead
- • GeoJSON Streaming: Efficient geometry serialization
- • Query Optimization: Spatial queries leverage PostGIS functions