How the vibes are measured
Published 2026-09-27 · updated 2026-09-28 · every number links to the public page it was read from · corrections welcome
In one breath. Every three hours the engine reads the local papers and the city's open data. A fixed list of words gives each story a number between -1 and +1. A borough's number is the average of its stories, nudged by how busy 311 has been, and then named with an emotion word: Lifted, Hopeful, Even, Weighed down or Raw. Since September 28 it also reads what people post in public about each borough, and how busy the streets are. Posts are counted and scored, never quoted, never kept.
What it is, and what it is not
The reading on the board is the mood of each borough right now, read from two places: its local news, and what people post in public about it. It is not a poll: nobody is asked anything, and nothing private is read. It is not a forecast, and it is not weather; the real forecast comes from the National Weather Service and is shown separately. Every name on the scale is an emotion word so it cannot be mistaken for a temperature.
It is also not a language model deciding how the city feels. It is arithmetic over a word list, which is slower to fool and easy to explain. What follows is the whole method, in order, with the exact numbers the engine uses. The only things kept back are the full word list and its weights, so nobody can write a headline to the list.
The people's pulse (added September 28)
News alone reads what reporters chose to print. So the engine now also reads what people themselves post in public about each borough:
- Bluesky: the public post search, one search per borough, the last two days.
- Mastodon: public hashtags such as #brooklyn and #bronx.
- Lemmy: the public New York City forum; a post counts for a borough only when it names one.
- YouTube: titles and descriptions of public videos posted about each borough in the last day.
Every post is scored with the same word list as the news, in memory, and then dropped. What is kept is a count and a mood per borough, nothing else: never a post, a name, a handle, a photo, a face or anyone's location. Posts that are off topic (a sitcom called Brooklyn Nine-Nine, a band called Queens of the Stone Age), not in English, or only a link are skipped.
How much the people count. The people's mood is blended with the news mood, and it counts for more as more people post: with 30 posts it carries a quarter of the reading, and with 60 or more it carries half. With fewer than 8 posts it is left out.
Rally energy. Protests, marches and vigils often follow a big event within hours. When three or more public posts about a borough mention one, the borough is marked Rally energy, so anyone going out knows.
Streets. The city's live traffic speeds (NYC DOT open data, a few hours behind) are compared with each borough's own normal speed, which the engine learns slowly over time. Much slower than normal reads Busy or Packed; much faster reads Quiet. This says how busy a borough is, not how it feels, so it never changes the mood score.
Left out on purpose: Reddit (it refuses programs), TikTok and Instagram (no public way for a program to read them), anything private, and cameras pointed at people.
When the map flashes
A borough surges when its reading jumps by 0.25 or more since the last run, when more than a third of at least ten public posts carry strong feeling, or when it has rally energy. A surging borough flashes a loud color for its leading emotion: gold for joy, amber for gratitude and pride, red for anger, violet for fear, blue for sadness, cyan for surprise and rally energy.
The four steps (the news)
1Read. Every three hours the engine pulls the latest headlines and summaries from local papers (Gothamist, amNY, THE CITY, Brooklyn Paper, QNS, Bronx Times, SILive and others) and from the city's open data. Each story is tagged to a borough: the borough papers tag their own, and city-wide stories are tagged by the place names in them. A story with no borough in it counts for the city but for no borough.
2Score each story. A dictionary of a few hundred words carries a weight from about -4 to +4.
Rescued is +2.2,
volunteers +2,
celebrates +2.5,
free +1.4;
eviction is -2.4,
hurt -2.2,
delays -1.5. The engine walks the story word by word and adds up the weights it finds, with three adjustments:
- Boosters. A word like very or extremely just before a scored word pushes it a little further in its own direction.
- Negations. Not, never, no and the like within three words flip the sign and keep three quarters of the strength. "Not hurt" reads as good news, slightly softer than "safe".
- Exclamation marks add a small push in the word's direction.
The total is then squashed into the range -1 to +1, so a long story full of strong words cannot outshout a short one. Alongside the number, eight emotion word families (gratitude, pride, joy, surprise, anger, fear, sadness, disgust) are counted; the family with the most hits is the story's dominant emotion.
3Add up the borough. The borough's stories are averaged, with stories that had more scored words counting a little more (a story with four or more scored words counts double a story with none). Then two corrections:
- The news baseline. Local news runs negative on an ordinary day, because crime and complaints are what gets reported. So an ordinary day is re-centred: a fixed +0.2 is added to every borough and to the city, which puts "an ordinary mix of news" at Even instead of Weighed down.
- The 311 nudge. If the borough's 311 requests in the last full day are more than 25% above its seven-day average, 0.1 is taken off. If they are more than 25% below, 0.05 is added. It is a small nudge on purpose: 311 is a measure of how much people are asking the city for, not of mood.
The result is rounded to one decimal place and held between -1 and +1.
4Name it. The number becomes a word on a five-step scale:
| Reading | Score | What it means |
|---|
| ✦Lifted | 0.3 and up | gratitude and pride outweigh the rest |
| ◆Hopeful | 0.1 and up | more good news than bad |
| ◈Even | -0.1 and up | an ordinary mix |
| ◇Weighed down | -0.3 and up | worry or loss is leading |
| ▼Raw | below -0.3 | anger or fear is leading |
Two readings get a truer name when a particular emotion leads: Weighed down becomes
On edge when fear leads and
Grieving when sadness leads; Raw becomes
Frightened when fear leads and
Grieving when sadness leads.
The rest of the card
- Trend arrow. The new score against the previous run's score. Up by 0.1 or more is Rising, down by 0.1 or more is Falling, anything else is Stable. A borough read for the first time shows New.
- Top emotion. The emotion family with the most hits across the borough's stories. If the top two are nearly tied and pull in opposite directions, it says Mixed. A borough with no stories says Quiet.
- Most discussed concern. The most negative story that is about one of the concern topics: safety, housing, transit, environment, civic life, health or cost of living. If none fits, the most negative story of any kind.
- Most uplifting highlight. The most positive story, as long as it scored above +0.05.
- Stories read (n). How many stories the borough's reading rests on. Treat a small number with suspicion; three stories is a coin toss, thirty is a reading.
- City score and shift. The same arithmetic over every story at once, plus the change from the previous run.
A worked example
Four made-up headlines, scored by the engine's real word list:
"Volunteers rescued a dog from the Gowanus Canal; the dog was not hurt" → +0.83 · 3 scored words (volunteers +2, rescued +2.2, hurt -2.2 flipped by "not") · gratitude leads
"Rent hikes leave Bronx tenants facing eviction as landlord ignores repairs" → -0.76 · 4 scored words · sadness leads
"Queens library celebrates 100 years with a free block party this weekend" → +0.71 · 2 scored words · pride leads
"Subway delays again after signal problems on the A line" → -0.60 · 2 scored words · no emotion family hit
Average of the four (weighted by scored words): +0.02 · plus the news baseline +0.2 · = 0.2 → Hopeful ◆, top emotion gratitude
Notice that the second headline has words the list does not carry (ignores, repairs). A word the list does not know scores nothing. That is the honest limit of the method and the reason the number is a reading, not a verdict.
What the reading cannot do
- It cannot read sarcasm or context. "The Knicks killed it last night" scores as bad news. This happens, and it averages out over many stories, but it can swing a borough with few stories.
- It reads papers, not people. A borough whose paper ran a crime round-up reads lower that day whatever its residents felt.
- Coverage is uneven. Boroughs with their own paper in the source list (Brooklyn, Queens, the Bronx, Staten Island) get many tagged stories. Manhattan mostly gets stories tagged by place name, so its reading often rests on a handful. The stories-read count on each card is there so you can see this.
- A word list is fixed. New slang, new names and new events score nothing until the list is updated. The list is revised by a person, and each revision is noted in the log.
- Two small constants shape it. The +0.2 baseline and the 311 nudge are judgment calls, written down above so they can be argued with.
Where to check
The readings are on the board with each borough's stories-read count. The weekly report averages the daily readings across the week. The source list and their health are on how it works. The engine's rule that the scale uses emotion words and never temperature words, and that the real forecast is shown separately, is written in the same place.
Written to the studies standard. If a figure here does not match the page it links to, the page is right and this study is wrong: write to us and it gets corrected in place, with a note.