North India's annual smoke festival
Contents
Every year from mid-October to late November, north India holds a festival nobody bought tickets for. Farmers in Punjab and Haryana burn the straw left after the rice harvest (parali), the smoke rolls across the plains, meets cold still air, and settles over Delhi for the season. Schools go online, construction stops, and someone announces a plan. This year Delhi’s official air quality index was 376 at 4 PM on Diwali, Sunday 8 November, and on Diwali night 125 pollution readings went missing from the official records. Convenient timing.
This is file no. 1 of File Pending, a project where I open problems that have been “under consideration” for years with public data. For this one I built Parali Watch, a dashboard that tracks farm fires across Punjab, Haryana, Uttar Pradesh, Rajasthan, Delhi and Uttarakhand from NASA satellites and updates every three hours. This post covers what the data says and a little about how it works.
The good news, apparently
The official yardstick for stubble burning is the satellite fire count, and by that yardstick things are going brilliantly. Here is Punjab, counted by the same satellite (VIIRS on NOAA-20) over the same window every year, so the comparison is fair:
A 94% drop since 2020. Champagne, surely.
The burnt fields didn’t get the memo
Fire counts measure fires a satellite happened to see. What actually matters for the air is how much land got burnt, and India still has no official way to measure that. The Supreme Court asked about it in November 2024; two years later the protocol is still “under validation”, and the national farm research institute told a journalist under the Right to Information Act that it is “only researching” one.
Independent estimates exist, and they are awkward. According to iFOREST, as reported by the Indian Express, Haryana’s official fire count halved from 2024 to 2025 (1,406 to 662) while its burnt area grew from 7,117 to 8,812 km². Punjab’s count fell 53%; its burnt area fell 15%.
So the fires didn’t stop. They got better at timing.
A game of hide and seek
The satellites behind the official count are in polar orbits, which means they pass over a given spot at roughly the same times every day. Over Punjab that is around noon to 3 PM, and again around 1 to 3 AM. iFOREST found that over 90% of large fires in 2024 and 2025 burned after 3 PM, and an ISRO study in 2025 confirmed that peak burning had shifted to late afternoon and evening.
Here is what the satellites saw over Punjab this season, by hour of day:
The red bars were the surprise. I assumed the late-afternoon detections were a bug in my timezone handling. They are real, and they come almost entirely from Aqua, a NASA satellite launched in 2002. Late in its life its orbit has been drifting later in the day, and it now crosses Punjab at around 3 to 4:30 PM. It sees a lot of fire in that slot. The more modern satellites never do, because they’re never overhead then. After 5 PM, nothing is looking at all.
To be clear about the limits: a detection is a hot pixel seen on one pass, not a fire and not a measure of area. The point isn’t that these counts are wrong. It’s that a falling count can mean better hiding just as easily as less burning, and a policy built on the count rewards the hiding.
What the smoke costs
Farm smoke is the loudest act of a year-round problem, not the whole show. On the worst days it made up 38% of Delhi’s PM2.5 in 2024 and 22% in 2025, and Delhi’s December smog often gets worse after the fires stop. If Delhi’s air met the WHO guideline, its residents would live about 8.2 years longer. Stubble is a convenient guest to blame for the whole party.
The farmer is the last link, not the first
It is easy to blame the person holding the matchstick, and every year someone does: fines were doubled in 2024, and there are police cases and red marks in land records. But look at the choice. The rice is cut in late October, wheat has to go in within about two weeks, and the field is covered in straw. The machines that sow through the straw are shared by everyone in the same fortnight. Straw has almost no buyers. A match costs one rupee and one evening.
Underneath that is a bigger absurdity. Punjab pumps out 152 to 156% of its annual groundwater recharge to grow rice, while central rice stocks sit at about three times the required buffer. Meanwhile India spends ₹1.61 lakh crore a year importing edible oil and imports record amounts of pulses, crops Punjab could grow on far less water. Farmers grow rice because the government reliably buys it at a guaranteed price. Alternatives like maize have sold for as little as ₹800 a quintal against a support price of ₹1,850. Farmers grow whatever the government guarantees to buy. A fine fits in a press release. A fix costs money for years.
The dashboard goes further into all of this: a decade-long timeline of who did what (every party has had a turn), the alternatives Punjab could grow, and a bingo card of real, sourced excuses for your next press conference.
How it’s built
Parali Watch is a small Go program and a static site. No servers, no database.
- Data. NASA’s FIRMS service publishes every thermal anomaly seen by the VIIRS and MODIS satellites. The API returns CSV for a bounding box in windows of at most five days. For each day the fetcher picks the reprocessed archive when NASA has published it, and the near-real-time feed otherwise, and never lets the near-real-time version overwrite the archive.
- Storage. One gzipped CSV per day per satellite, committed to git. The gzip header’s timestamp is zeroed, so unchanged data produces byte-identical files and a 3-hourly job doesn’t churn the history. Seven years of detections for the six states plus Pakistani Punjab come to 3.1 million rows in 56 MB.
- Places. Each detection is matched to a district with point-in-polygon tests against embedded boundary files (
paulmach/orbis the only dependency). Points a couple of kilometres outside any polygon are kept, because two boundary datasets never quite agree along a border. - The site. The build writes one small JSON file per day. The browser loads only the days in the chosen window and does all the filtering, so any start and end time works without a backend.
- Gotchas. FIRMS signals its rate limit with HTTP 400 and a sentence of text rather than a 429, so the client has to read the body. A satellite (S-NPP) stopped sending data on 2 November 2026, which would show up as a fake drop in burning if the comparison mixed satellites. And when a number looks wrong, check the orbit before the code.
The source is on GitHub.
File status
Pending. Next review: October 2027, when the festival returns.