Guides

How to make a year-in-review story for your app

By Lucency, the makers of Yearcap · Updated November 2, 2026

A year-in-review story is a short, swipeable recap of one person’s year in your app: their biggest numbers, their favorite things, and a card they can share. The big apps send one every December. Here is how to make one for your app, step by step, without a design team.

Why it works

People love seeing numbers about themselves, especially numbers that make them look good. A recap reminds active users how much they got out of your app, brings quiet users back for a look, and every shared card shows your app’s name to that person’s friends. It is one of the few marketing pieces your users want to post.

1. Pick your dates

Most recaps cover January 1 to the day you export. If you send in early December, export in the last days of November and say so in your email (“your year so far”). Nobody minds missing two weeks of December; they do mind getting the story after the holidays, when everyone has moved on.

2. Choose four to six stats

Fewer is better. A story with five strong slides beats one with twelve slides of filler. Good stats have three things in common: the user did them (not your app), they get bigger with use, and they mean something without explanation.

Leave out anything that could embarrass someone (weight, money lost, missed goals) and anything only your team understands (“sync events”, “XP” if users don’t know what it is). For more ideas by kind of app, see year-in-review examples.

3. Export one spreadsheet (CSV)

You need one file with one row per user and one column per stat. Column names become the starting point for the words on each slide, so name them plainly: km_run beats dist_sum_2.

If your data is in Postgres, one query usually does it. Here is the shape for a running app:

-- One row per user, one column per stat, twelve month columns for the chart.
select
  u.id                                   as user_id,
  u.first_name,
  u.email,
  count(*)                               as runs,
  round(sum(a.distance_km))              as km_run,
  round(max(a.distance_km), 1)           as longest_run_km,
  count(distinct a.started_at::date)     as active_days,
  count(*) filter (where extract(month from a.started_at) = 1)  as runs_jan,
  count(*) filter (where extract(month from a.started_at) = 2)  as runs_feb,
  -- ...one line per month...
  count(*) filter (where extract(month from a.started_at) = 12) as runs_dec
from users u
join activities a on a.user_id = u.id
where a.started_at >= '2026-01-01' and a.started_at < '2027-01-01'
group by u.id, u.first_name, u.email
having count(*) >= 3;  -- skip people who barely used the app this year

The same idea works in MySQL with sum(case when month(started_at) = 1 then 1 else 0 end), or in a spreadsheet with a pivot table. Not sure what the file should look like? Download a sample: running, reading, language learning, or habits.

4. Let ranks do the bragging

“You ran 561 km” is nice. “You ran more than 95% of runners on our app” is what gets posted. A rank needs every user’s numbers, which is why the whole user base goes in one file. Two rules keep ranks kind:

5. Write the words

Each slide is one short sentence before the number and one after. Write to the user, about the user:

Example slide

You ran

561 km

That’s Reykjavík to Akureyri and almost halfway back.

6. Test with real rows

Before anything goes out, look at the story for at least three people: your most active user, a typical one, and someone who barely used the app. Check long names, missing values, and a user with zero in a month. If the quiet user’s story looks sad, raise the minimum in your export (the having line above) and send those people a plain “we missed you” email instead.

7. Send it in early December

The first two weeks of December are the sweet spot: people are in a year-in-review mood and the big apps haven’t filled every feed yet. Give each user a private link to their own story and get it to them three ways:

The step-by-step for each is in how to send your stories.

Checklist

  1. Data cutoff picked, export date in the calendar.
  2. Four to six stats, plus twelve month columns and one favorite.
  3. One CSV, one row per user, plain column names.
  4. Ranks only where they flatter, small numbers hidden.
  5. Short lines in the second person, a persona, a summary card.
  6. Stories checked for a power user, a typical user and a quiet one.
  7. Email, banner and push ready for the first week of December.

Yearcap handles the ranks, the story and the sending for you: drop in the CSV, and AI suggests the stats and writes the words (it reads your column names and ranges, never a user’s row). You see the story play live while you edit it. Start with your file.

Make your users’ year in about ten minutes

Drop in one spreadsheet and watch the story build live. Free up to 500 users.

Make yours, free