AWS Builder Center
Building VayuSync: A Sub-Second Serverless Smoke Dispersion & AI Early-Warning Engine on AWS

Building VayuSync: A Sub-Second Serverless Smoke Dispersion & AI Early-Warning Engine on AWS

How we combined NASA VIIRS satellite fire telemetry, spherical kinematics on AWS Lambda, and Amazon Bedrock (Claude Haiku 4.5) to give schools and hospitals a 6-hour advance warning before toxic smoke plumes arrive.

Building scalable AI agents, serverless backends, and cloud-native systems.
How we combined NASA VIIRS satellite fire telemetry, spherical kinematics on AWS Lambda, and Amazon Bedrock (Claude Haiku 4.5) to give schools and hospitals a 6-hour advance warning before toxic smoke plumes arrive.



1. The Engineering Problem: Why Ground AQI Sensors Are Too Late

Every post-monsoon season (October–November) across Northern India’s Indo-Gangetic Plain, thousands of agricultural crop-residue fires ignite across Punjab and Haryana. Driven by prevailing north-westerly synoptic winds (300°–330°), dense PM2.5 plumes travel 200 to 350 km southeast into the Delhi National Capital Region (NCR), routinely pushing ambient PM2.5 concentrations above 400–500 µg/m³.
Yet almost every existing air quality platform is reactive:
  1. Zero Lead Time: Ground-level Continuous Ambient Air Quality Monitoring Stations (CAAQMS) only register a spike after the smoke plume has already enveloped the neighborhood. By the time an AQI app turns dark red at 8:30 AM, 4,000 students are already at morning assembly and hospital HVAC systems have already drawn high-particulate air into inpatient wards.
  1. Generic Public Metrics: Telling a hospital facility manager or a school principal that "AQI is 410" does not translate into an operational protocol with a specific arrival window, expected peak concentration, and facility-specific action checklist.
We built VayuSync to flip air-safety management from post-exposure reporting to preemptive institutional defense—delivering a 4-to-8-hour advance lead time at $0.00 idle infrastructure cost using an event-driven AWS Serverless architecture.



2. Event-Driven AWS Serverless Architecture

Agricultural burning is highly episodic and seasonal. Provisioning always-on EC2 clusters or RDS databases for a workload that spikes during satellite overpass windows wastes compute and budget. We architected VayuSync as a 100% serverless, scale-to-zero pipeline defined in  backend/template.yaml  using the AWS Serverless Application Model (AWS SAM).
text
+-----------------------+ +------------------------------------------+
| NASA FIRMS (VIIRS) | | Open-Meteo ERA5 / Forecast API |
| 375m Thermal Anomalies | 10m Wind Speed & Direction Vectors |
+-----------+-----------+ +--------------------+---------------------+
| |
+-------------------+-------------------+
|
v (Every 6h via Amazon EventBridge Cron)
+-------------------------------+
| AWS Lambda: IngestionEngine |
| (Python 3.12 · 512 MB) |
| • u,v Wind Vector Decomposition
| • Spherical Plume Cone Gen |
| • Precision-6 Geohash Index |
+-------+---------------+-------+
| |
Raw GeoJSON | | Active Hotspots & Plume Polygons
Archival v v
+---------------+ +-----------------------+
| Amazon S3 | | Amazon DynamoDB |
| Raw Payloads | | • VayuSync_Hotspots |
+---------------+ | • VayuSync_Institutions
| • VayuSync_AlertLogs |
+-----------+-----------+
|
v (Async Lambda Invoke)
+-----------------------------------------------+
| AWS Lambda: EvaluatorEngine (Python 3.12) |
| • Ray-Casting Point-in-Polygon Geofencing |
| • Haversine Plume Arrival ETA & PM2.5 Decay |
| • Invokes Amazon Bedrock w/ Latency Tracking |
+-------+-------------------------------+-------+
| |
v (InvokeModel) v (Fan-out Dispatch)
+-------------------------------+ +-----------------------+
| Amazon Bedrock | | Amazon SNS |
| Claude Haiku 4.5 | | VayuSync-AlertTopic |
| (Schema-Validated JSON | | SMS / Email / Webhook|
| + Deterministic Fallback) | +-----------------------+
+-------------------------------+
|
v (REST API: /dashboard, /alerts, /simulate)
+-------------------------------+ +-----------------------+
| Amazon API Gateway (ap-south-1) ---> | AWS Amplify Hosting |
| + SimulateTrigger & Dashboard| | React 18 + MapLibre |
+-------------------------------+ +-----------------------+

Why Each AWS Service Was Chosen

  1. Amazon EventBridge: Triggers  VayuSync-IngestionEngine  on a  rate(6 hours)  schedule aligned with polar-orbiting VIIRS satellite overpasses.
  1. AWS Lambda (Python 3.12): Four decoupled microservices ( IngestionEngine ,  EvaluatorEngine ,  SimulateTrigger ,  DashboardData ) handle orbital ingestion, geospatial polygon intersection, Bedrock inference, and REST API responses.
  1. Amazon DynamoDB ( PAY_PER_REQUEST ): Three on-demand tables ( VayuSync_Hotspots ,  VayuSync_Institutions ,  VayuSync_AlertLogs ) store geohashed thermal anomalies, facility coordinates, and generated advisories with single-digit millisecond reads and zero idle cost.
  1. Amazon S3: Archives raw GeoJSON dispersion polygons ( vayusync-raw-payloads-* ) for historical compliance and back-testing.
  1. Amazon Bedrock ( us.anthropic.claude-haiku-4-5-20251001-v1:0 ): Synthesizes facility-specific emergency directives in strict JSON format, backed by a deterministic physics/rule fallback.
  1. Amazon SNS: Fans out critical alerts to institutional subscribers and webhook endpoints.
  1. Amazon API Gateway & AWS Amplify: Exposes CORS-enabled REST endpoints in  ap-south-1  ( Mumbai ) consumed by our globally cached React 18 + TypeScript + MapLibre GL 3D command center on AWS Amplify.



3. Deep Dive #1: Pure-Python Spherical Plume Kinematics in AWS Lambda

A key lesson in serverless geospatial engineering is avoiding heavy C-extension binaries ( GDAL ,  GEOS ,  Shapely ) when you want ultra-fast Lambda cold starts and simple zip packaging. We implemented our entire atmospheric transport and polygon-intersection math in pure Python inside  backend/lambdas/shared/geo_utils.py .

Meteorological Wind Decomposition & Forward Projection

Meteorological wind direction reports the compass bearing the wind blows from (e.g., 315° NW means air parcels travel toward 135° SE). We decompose 10m wind speed  U  (m/s) and direction  theta_from  into zonal ( u , east-west) and meridional ( v , north-south) velocity components:
  •  u = -U * sin(theta_from) 
  •  v = -U * cos(theta_from) 
From the hotspot origin  (lat, lon) , we project the downwind plume centerline over a 6-hour horizon with a lateral Pasquill-Gifford dispersion half-angle of 15°, computing 15 arc vertices along the leading edge on a spherical Earth ( R = 6371 km ):
Python
def destination_point(lat: float, lon: float, bearing_deg: float, distance_km: float) -> Tuple[float, float]:
"""Calculate destination (lat, lon) given start point, bearing, and distance on a sphere."""
angular_dist = distance_km / EARTH_RADIUS_KM
bearing_rad = math.radians(bearing_deg)
lat_rad = math.radians(lat)
lon_rad = math.radians(lon)
dest_lat_rad = math.asin(
math.sin(lat_rad) * math.cos(angular_dist)
+ math.cos(lat_rad) * math.sin(angular_dist) * math.cos(bearing_rad)
)
dest_lon_rad = lon_rad + math.atan2(
math.sin(bearing_rad) * math.sin(angular_dist) * math.cos(lat_rad),
math.cos(angular_dist) - math.sin(lat_rad) * math.sin(dest_lat_rad),
)
return (round(math.degrees(dest_lat_rad), 6), round(math.degrees(dest_lon_rad), 6))

Ray-Casting Geofence Intersection

When  EvaluatorEngine  runs, it checks every registered school, hospital, and construction site against active dispersion cones. First, it runs an O(1) bounding-box pre-filter, followed by a pure-Python Ray-Casting Point-in-Polygon algorithm and a 25 km proximity corridor check:
Python
def point_in_polygon(point: Tuple[float, float], polygon_geojson: Dict[str, Any]) -> bool:
"""Ray-casting algorithm to determine whether (lat, lon) lies inside a GeoJSON Polygon."""
lat, lon = point
ring = polygon_geojson["coordinates"][0]
n = len(ring)
inside = False
j = n - 1
for i in range(n):
xi, yi = ring[i][0], ring[i][1] # GeoJSON order: [lon, lat]
xj, yj = ring[j][0], ring[j][1]
if ((yi > lat) != (yj > lat)) and (
lon < (xj - xi) * (lat - yi) / (yj - yi + 1e-12) + xi
):
inside = not inside
j = i
return inside



4. Deep Dive #2: Resilient Amazon Bedrock Advisories with Latency Telemetry

Once an institution is flagged inside a downwind plume cone,  EvaluatorEngine  calculates:
  • Downwind Distance ( D ): Haversine distance from the fire cluster to the facility.
  • Predicted Plume Arrival ( ETA ):  ETA_hours = D / V_kmh .
  • Estimated Peak PM2.5: Scaled by satellite Fire Radiative Power ( FRP  in MW) and inverse square-root distance attenuation.
We then invoke Amazon Bedrock ( us.anthropic.claude-haiku-4-5-20251001-v1:0 ) to generate a 3-point institutional action plan tailored to the facility type ( School ,  Hospital ,  Construction , or  Municipality ).

Designing for Zero Single Points of Failure

In a life-safety alerting pipeline, an LLM timeout, throttling exception, or cross-region inference profile issue must never block an emergency dispatch. We wrapped our Bedrock call with high-resolution  time.perf_counter()  instrumentation, strict JSON schema validation, and an automatic deterministic rule-engine fallback:
Python
t0 = time.perf_counter()
response = bedrock_client.invoke_model(
modelId=BEDROCK_MODEL_ID,
contentType="application/json",
accept="application/json",
body=body,
)
bedrock_latency_ms = round((time.perf_counter() - t0) * 1000.0, 1)
Every alert record persisted in  VayuSync_AlertLogs  explicitly records  "generation_method": "bedrock"  (along with  bedrock_latency_ms ) or  "generation_method": "rule_fallback" , and surfaces this metadata directly inside the frontend's Bedrock Prompt & Schema Inspector Modal.



5. Empirical Validation: CPCB Back-Test & N=30 CloudWatch Latency Benchmark

To verify that VayuSync works on real atmospheric events—not just synthetic demos—we conducted two rigorous validations logged in our repository.

A. 2024–2025 Retrospective Back-Test Against CPCB Ground Truth

We downloaded  15,394  hourly observations ( 2024–2025 ) from the Central Pollution Control Board (CPCB) / DPCC Anand Vihar reference station ( 28.6476° N, 77.3158° E ) and mechanically screened 8 historical dates using  backend/scripts/screen_dates.py  and  backend/scripts/backtest.py  combining archival NASA FIRMS VIIRS ( VIIRS_SNPP_SP ) fire detections and Open-Meteo ERA5 historical 10m winds:
Date
Episode Type
VIIRS Detections
Mean Wind (Speed, Dir)
Predicted Arrival (UTC)
Observed CPCB Peak (UTC)
Arrival Error (h)
Peak PM2.5 (Pred / Obs)
 2025-11-05 
NW Transport #1
620
12.1 km/h @ 305°
 15:52 
 17:00 
-1.13 h
375 / 353 µg/m³
 2024-10-31 
NW Transport #2
924
8.7 km/h @ 316°
 17:38 
 19:00 
-1.36 h
122 / 399 µg/m³
 2025-11-06 
NW Transport #3
228
11.4 km/h @ 305°
 18:55 
 18:00 
+0.92 h
132 / 326 µg/m³
 2025-11-01 
NW Transport #4
436
7.6 km/h @ 296°
 02:27  (+1d)
 03:00  (+1d)
-0.55 h
161 / 386 µg/m³
 2024-11-15 
NW Transport #5
708
6.8 km/h @ 301°
 04:39  (+1d)
 02:00  (+1d)
+2.66 h
115 / 441 µg/m³
 2025-11-03 
Control (Easterly)
306
5.2 km/h @ 139°
No alert
—
True Negative
— / 398 µg/m³
 2025-11-04 
Control (SE Flow)
599
8.2 km/h @ 120°
No alert
—
True Negative
— / 427 µg/m³
 2024-10-27 
Control (SE Flow)
456
5.9 km/h @ 118°
No alert
—
True Negative
— / 355 µg/m³
  • Arrival Time Accuracy: Across all 5 NW transport episodes, VayuSync achieved a Mean Absolute Error (MAE) of  1.32 hours  ( -0.55h  to  +2.66h ), providing a reliable 4-to-8-hour advance warning window.
  • Directional Specificity: Across all 3 easterly/south-easterly control days ( 118°–139° ), VayuSync generated zero false-positive alerts ( 0 / 3 ), proving that the dispersion cone geometry correctly projects plumes away from Delhi NCR when winds blow from the east.

B. Live Production Latency Benchmark (N=30 Warm Invocations)

We benchmarked the live deployed pipeline in  ap-south-1  across 31 sequential requests (1 cold start +  N=30  warm invocations) using  backend/scripts/benchmark_latency.py  and extracted exact AWS CloudWatch  REPORT  execution durations:
Metric Layer
Cold Start (Call #1)
Warm Median (p50, N=30)
Warm p95 (N=30)
Warm Mean (N=30)
Client HTTP Round-Trip ( POST /simulate )
 3,245.5 ms 
 932.8 ms 
 2,114.2 ms 
 1,158.1 ms 
Server Execution ( VayuSync-SimulateTrigger )
 2,313.0 ms 
 771.1 ms 
 2,009.2 ms 
 991.4 ms 
CloudWatch  REPORT  ( VayuSync-EvaluatorEngine )
 2,115.6 ms 
 748.9 ms 
 1,977.9 ms 
 966.2 ms 



6. Key Takeaways for AWS Builders

  1. Pure-Python Geospatial Math Beats Heavy Binary Layers for Simple Polygons: Implementing Haversine distance, spherical destination projection, geohashing, and ray-casting point-in-polygon in pure Python kept our Lambda deployment package under  20 KB  and warm execution overhead under  50 ms .
  1. Always Pair Generative AI with Deterministic Fallbacks in Critical Systems: Using Amazon Bedrock ( Claude Haiku 4.5 ) gives facility managers rich, context-aware advisories, while a deterministic physics fallback guarantees 100% alert delivery even if model quotas or regional endpoints fluctuate.
  1. Verify Serverless Claims with CloudWatch  REPORT  Logs & Ground-Truth Data: Instrumenting  time.perf_counter()  around Bedrock calls and benchmarking  p50/p95  durations across  N=30  warm invocations surfaced real multi-tenant variance that single-shot timing hides.



Try VayuSync Live

Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article