Search over 45M Hacker News posts and comments, and see how any term trends over time, powered by Upstash Redis Search
See the codeType a word and you get two things at once: a month-by-month trend line of how often Hacker News talked about it, and the real posts and comments behind every spike. Search one term, or stack several on the same chart to see which one the internet actually cared about.
The whole thing is a thin UI over Upstash Redis Search.
There's no separate search engine to run - you store plain Redis hashes and
define one index over them, and every search and every trend line is a single
@upstash/redis call.
1. Ingest. scripts/ingest.ts streams monthly Hacker News Parquet files
from HuggingFace for backfills, and a daily GitHub Action pulls new items from
the official HN API (--live). Each item
is HSET as a plain hn:<id> hash in Upstash Redis.
2. Index. Before loading, the same script defines one search index over those hashes:
await redis.search.createIndex({
name: "hn",
dataType: "hash",
prefix: "hn:",
schema: s.object({
title: s.string(),
text: s.string(),
by: s.keyword(),
type: s.keyword(),
time: s.date().fast(),
score: s.number("F64"),
ndesc: s.number("F64"),
parent: s.number("F64"),
}),
});
3. Query. Every search the UI runs is one hn.query({ filter, ... }), and
every trend line is one hn.aggregate({ filter, aggregations }). Both are built
from the same options in src/lib/hn-query.ts.
const hn = redis.search.index({ name: "hn", schema });
// matching posts, newest first
const { documents } = await hn.query({
filter: { title: { $eq: "rust" }, time: { $gte: "2024-01-01" } },
orderBy: { time: "DESC" },
limit: 30,
});
// mentions per month
const { aggregations } = await hn.aggregate({
filter: { title: { $eq: "rust" } },
aggregations: {
by_month: { $dateHistogram: { field: "time", fixedInterval: "30d" } },
},
});
Add your Upstash Redis REST credentials to .env.local:
UPSTASH_REDIS_REST_URL="..."
UPSTASH_REDIS_REST_TOKEN="..."
Then install, load some data, and start the dev server:
bun install
# ingest one quarter to play with (creates the index on first run)
bun scripts/ingest.ts 2026 Q1
# build the "Who is hiring?" postings index for the same months
# (/who-is-hiring reads it by default; set NEXT_PUBLIC_JOBS_INDEX_READY=0 to skip)
bun scripts/ingest-jobs.ts 2026-01 2026-03
bun dev
Open localhost:3000 and start searching.
@upstash/redis - the entire search + analytics backend.MIT © Upstash
4,596 followers · starred Jun 2026
180 followers · starred Jun 2026
34 followers · starred Jun 2026
148 followers · starred Jun 2026
Search over 45M Hacker News posts and comments, and see how any term trends over time, powered by Upstash Redis Search
See the codeType a word and you get two things at once: a month-by-month trend line of how often Hacker News talked about it, and the real posts and comments behind every spike. Search one term, or stack several on the same chart to see which one the internet actually cared about.
The whole thing is a thin UI over Upstash Redis Search.
There's no separate search engine to run - you store plain Redis hashes and
define one index over them, and every search and every trend line is a single
@upstash/redis call.
1. Ingest. scripts/ingest.ts streams monthly Hacker News Parquet files
from HuggingFace for backfills, and a daily GitHub Action pulls new items from
the official HN API (--live). Each item
is HSET as a plain hn:<id> hash in Upstash Redis.
2. Index. Before loading, the same script defines one search index over those hashes:
await redis.search.createIndex({
name: "hn",
dataType: "hash",
prefix: "hn:",
schema: s.object({
title: s.string(),
text: s.string(),
by: s.keyword(),
type: s.keyword(),
time: s.date().fast(),
score: s.number("F64"),
ndesc: s.number("F64"),
parent: s.number("F64"),
}),
});
3. Query. Every search the UI runs is one hn.query({ filter, ... }), and
every trend line is one hn.aggregate({ filter, aggregations }). Both are built
from the same options in src/lib/hn-query.ts.
const hn = redis.search.index({ name: "hn", schema });
// matching posts, newest first
const { documents } = await hn.query({
filter: { title: { $eq: "rust" }, time: { $gte: "2024-01-01" } },
orderBy: { time: "DESC" },
limit: 30,
});
// mentions per month
const { aggregations } = await hn.aggregate({
filter: { title: { $eq: "rust" } },
aggregations: {
by_month: { $dateHistogram: { field: "time", fixedInterval: "30d" } },
},
});
Add your Upstash Redis REST credentials to .env.local:
UPSTASH_REDIS_REST_URL="..."
UPSTASH_REDIS_REST_TOKEN="..."
Then install, load some data, and start the dev server:
bun install
# ingest one quarter to play with (creates the index on first run)
bun scripts/ingest.ts 2026 Q1
# build the "Who is hiring?" postings index for the same months
# (/who-is-hiring reads it by default; set NEXT_PUBLIC_JOBS_INDEX_READY=0 to skip)
bun scripts/ingest-jobs.ts 2026-01 2026-03
bun dev
Open localhost:3000 and start searching.
@upstash/redis - the entire search + analytics backend.MIT © Upstash
4,596 followers · starred Jun 2026
180 followers · starred Jun 2026
34 followers · starred Jun 2026
148 followers · starred Jun 2026