AWS Builder Center

Safe in the Heat,Without Losing a Day's Pay: Building HeatGate on AWS

In an Indian heatwave, a delivery rider who stops to rest loses orders and pay. HeatGate turns heat-safety rules into readable Cedar policies that run on AWS Lambda before every order is dispatched. We tested four rule sets on real hot days in a simulated city, and asked what rest pay would make safety affordable. Here’s what we built, what fought back, and what we refuse to claim.

It is 2 pm in Delhi, the air is above 44 °C, and a delivery rider's phone buzzes with a new order. He has been riding since late morning. He knows he should stop. He also knows that if he skips this order, the app may push him down the queue, and the money for that hour is gone.
That moment is the whole project. HeatGate is our attempt to answer one question: can a delivery app keep riders safe in a heatwave without making safety cost them money?
This post walks through what we built for the Amazon Developer Hackathon, how it runs on AWS, the parts that fought back, and the things we deliberately refuse to claim.

The problem: heat rules exist, but nobody can check them

India has heat guidance. The national disaster agency publishes heat action advice, and rider unions have their own demands: rest breaks, shorter shifts, no penalty for skipping orders in extreme heat. The trouble is not a lack of rules. It is that these rules live in PDFs and press releases, while the real decision happens inside an app's dispatch code, in a fraction of a second, where nobody outside the company can see it.
We talked to one rider while building this. That is a small number, and we say so. But what we heard matched the shape of the problem: on the hottest days, stopping feels like a luxury, because the pay is per order.
So we set ourselves three requirements:
  1. The rules must be readable. A union or a labour officer should be able to read the exact rule, not a description of it.
  1. Every decision must be explainable. If a rider is stopped, there must be a record saying which rule fired and why.
  1. Safety must be measured against pay. A rule that protects riders but quietly halves their income is not a solution.

What we built: four pieces

1. Heat rules as Cedar policies. Each rule set is written in  Cedar , the policy language AWS built for access control. We used it for something it wasn't built for: deciding whether a rider may take an order. Before every order, the app asks one question – may this rider take this order right now? – and Cedar answers with one of four outcomes:
Outcome
What the rider sees
Rest now
Stop working and take a break, with the nearest cooling point
Not allowed
This order is refused for safety
Order skipped
The rider may decline this order without penalty
Allowed
Carry on
When several rules fire at once, the strongest wins: rest now beats not allowed, which beats order skipped. We compare four rule sets: no rules, the NDMA 2025 heat guidance, a union demand set, and our own HeatGate Fair. HeatGate Fair has seven settings (rest temperature, work limit, short-trip distance, and so on) that anyone can move with a slider and re-run.
2. A simulated city. We can't experiment on real riders, so we built a seeded simulation: a 10 × 10 km city, 50 riders logging in over two waves, 8 cooling points, and a realistic flow of orders. The same day runs four times, once under each rule set, so the comparison is fair.
3. Real weather. The simulation can replay 9 real hot days from Delhi, Lucknow and Hyderabad, using hourly historical weather from Open-Meteo, or you can set the heat yourself with a slider.
4. A website with four views.
  • Policy Sandbox: pick a day, run it, and watch riders on a city map.
  • Platform View: the four rule sets side by side on safety, speed and rider earnings, shown as ranges, not single numbers.
  • Rider View: the phone notification a rider actually gets, in English, Hindi, Telugu or Urdu, with the nearest cooling point.
  • Audit Log: every decision, with the rule that caused it. No rider location is ever stored.

Policy Sandbox at 15:10 on a replayed Lucknow day: 13 riders resting at cooling points, 7 delivering. Rider-012 is told to take a paid 20-minute break at a heat index of 46 °C.

Rider View: the notification in Hindi, with the nearest cooling point 1.9 km away and "No penalty". The translation is marked Draft.

Audit Log: every decision shows the rule set, the outcome and the exact rule that fired, such as  union-rest-due  or  fair-rest-due .

The stack: small, serverless, and in Mumbai


The browser loads the website from S3 and calls the API through API Gateway. One Lambda function holds the Cedar rules and answers every "may this rider take this order?" question. A second Lambda runs the simulation, and DynamoDB keeps the runs and the audit log.
Service
What it does for us
Why we chose it
AWS Lambda (API)
Runs the Cedar rules: /decide, /policies, /audit
A rule check is tiny and bursty; paying only per call fits
AWS Lambda (simulator)
Simulates a full day for 50 riders under 4 rule sets, in about 10–15 seconds
Heavy work kept out of the API path; at most 3 runs at once, a 4th gets a polite "busy"
Amazon API Gateway
The public HTTPS front door for the API
Managed TLS, CORS and throttling without a server
Amazon DynamoDB
Stores runs and every decision in the audit log
Simple key lookups; no rider location is ever written
Amazon S3
Hosts the website
Simple, cheap static hosting with no server to run
AWS SAM / CloudFormation
Builds the whole setup in one command
Anyone can redeploy it, and the setup is in the repo
Everything runs in ap-south-1 (Mumbai), close to the riders it is built for. The rules engine uses the official  @cedar-policy/cedar-wasm  package, so the exact same rules run in our tests, on our laptops and on Lambda.
We also wrote a smoke test of 30+ checks that runs against the live API after every deploy, alongside 267 unit tests.

What fought back

The riders who earned ₹0

Our first full run showed several riders ending the day with zero earnings. That looked like a dramatic finding – until we dug in. Riders who were mid-delivery when the shift ended at 8 pm were never paid for that last order; the simulation simply stopped. It was our bug, not a rule's effect. We fixed it so in-flight deliveries finish and get paid, with no new orders after 8 pm. Lesson: when a result looks dramatic, suspect your own code first.

Real weather is cooler than the headlines

We used Open-Meteo's historical reanalysis, which averages weather over roughly a 25 km grid. That smooths out hot spots, so it reads a few degrees below the peaks that weather stations report. We kept the honest data rather than inflating it, and we say so on screen. We also don't have the official IMD alert for each day, so the alert level is assumed from the peak temperature, and labelled that way.
We planned 15 replay days. After removing days that were near-duplicates of each other, 9 were left. We kept 9.

Everyone works for two apps

Many riders run two delivery apps at once. If HeatGate stops a rider on one app, nothing stops them taking an order on the other. We modelled this by assuming 40% of riders work a second app. That sets a floor: no rule set can push unsafe minutes to zero, and our results show that floor instead of hiding it.

Code that worked on one laptop

A Lambda function crashed on AWS while working perfectly on our machines: the simulation worker runs as plain Node, which needs an explicit  with { type: "json" }  to import data files. On Windows, our tests failed for a different reason: Git converted line endings, so a check that compares generated files byte by byte saw every file as changed. A  .gitattributes  file and a line-ending-safe comparison fixed it. Neither bug was interesting. Both cost hours.

A website that said too much, and once said things that weren't true

Our first UI audit found numbers on screen that came from nowhere, and a quiet fallback to sample data when the API was down. A judge would never have known. We rebuilt it so every number comes from a live API response, and a badge always says whether you're looking at Live API or API unreachable.
Then the opposite problem: the pages were drowning in caveats. We redesigned them, but kept the old version tagged in Git, ran both side by side, and only switched once the new one was clearer and still honest. Visible words dropped by 33% to 74% per page. Three caveats stayed visible on every page no matter what: riders are simulated, rupee amounts are placeholders, and the alert level is assumed.
One more design rule came out of this: colour never ranks the rule sets. Green-for-good, red-for-bad would have quietly told the viewer which answer to prefer. Where two rule sets' ranges overlap, the page says "≈" – no clear difference – instead of declaring a winner.

What we found, and what we refuse to claim

The question we cared most about: how much would a rider need to be paid per minute of rest to earn as much as today? At our default demand of 34 orders an hour, the model's answer is ₹0.64–₹1.17 per minute under the union's rules and ₹0.77–₹1.12 per minute under HeatGate Fair. The ranges overlap, so we say there is no clear difference between them. At 50 orders an hour, no rest pay up to ₹1.50 per minute gets riders back to today's earnings. These rupee figures are placeholders until we have real rider pay data.

Break-even rest pay: earnings as a share of today, against rest pay per minute, at 25, 34 and 50 orders an hour.
We wrote down the claims we won't make before we wrote the pitch, and kept them in the repo next to the numbers:
  • We don't claim riders earn more under any rule set. Our rupee figures are placeholders, not real wages.
  • We don't claim to know what riders want. We spoke to one rider. That is a starting point, not evidence.
  • We don't claim these are real riders. The weather is real; the riders and the city are simulated.
  • The translations are drafts. All 39 messages in Hindi, Telugu and Urdu are waiting for native-speaker review.

What's next

  1. Talk to many more riders, with consent, and replace the placeholder rupee figures with what they actually earn and what rest pay would make stopping worth it.
  1. Get the translations reviewed by native speakers.
  1. Use station-level weather and real IMD alerts instead of reanalysis and assumed alert levels.
  1. Turn the  /decide  endpoint into something a real dispatch system could call before assigning an order.

Try it

Pick a hot day in the Policy Sandbox, press Run, then open Platform View to see the four rule sets side by side.
Riders keep our cities fed in the worst heat of the year. Their safety shouldn't cost them a day's pay.
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