What Do You Owe Society? Building an Honest Lifetime Contribution Calculator

A calculator that weighs what society spent on you against what you gave back, year by year, with every assumption on show and no data kept.

Share
A balance scale with schooling, healthcare, shared services and social protection on the Received side, and paid work, unpaid care and volunteering on the Given side
💡
TL;DR
• I built Lifetime Contribution Balance. It estimates what society has spent on you against what you have given back.
• The model is one line, LCB(A) = Contribution(0..A) − Consumption(0..A), applied to every year of a life using published national statistics, and every result shows an honest range.
• There is no database. Your answers stay in the browser, and the tool says plainly that it must never be used to make decisions about people.

The dinner-table question nobody can answer

Sooner or later, at most dinner tables, someone says it. "I've paid in my whole life and got nothing back." Everyone has an opinion. Nobody has a number.

I kept wondering about the honest version of that question, asked of myself. I have been given a lot: years of school, doctors, roads, a safety net. I have also given back through work, through looking after people, and through the odd Saturday helping out. How do the two compare?

It turns out you can estimate this. Governments publish what they spend per student, per patient and per person. Statistics offices publish how much an hour of work produces. What was missing was something that puts it together for one life and shows its working.

Lifetime Contribution Balance is a small web app with a calculation engine behind it. You answer six short steps (You, Learning, Work, Home, Giving, Support). Every question has a sensible default, so you can skip any of them.

The engine walks through your life one age-year at a time. It returns a balance to date, an honest range around it, a break-even age, and two extra accounts that are deliberately never folded into the money.

Diagram: six questionnaire steps feed an engine that walks every age-year using a versioned coefficient pack, producing a balance, an unpriced account and an environmental account
Six questions in, one honest balance out.

The welcome screen sets the tone: "Not a score of your worth. Not a test you pass." That line shaped almost every design decision that followed.

How it works at a glance

Here is the whole idea:

LCB(A) = Contribution(0..A) − Consumption(0..A)

Add up everything you have given from birth to age A, subtract everything you have received, and the gap is your balance at A. Think of a bank statement for your relationship with society, with one row per year of your life.

For each year, the engine asks where you lived, which calendar year it was, and whether you were studying, working, caring or retired. Years after today use projected figures plus your own assumptions.

Illustrative stacked bar chart: received bars dominate childhood and old age, given bars dominate working years; a running balance line dips during education, crosses zero at a break-even age and falls again in retirement
The typical shape of a life (illustrative, not real data).

That shape is the key to the tool. A negative balance at 25 is not a verdict. It is the dip after years of school, before a working life has had time to happen.

What you received:

  • Everyday living: household spending
  • Education: spending per student, in the country where you studied
  • Healthcare: health spending per person, by age
  • Shared public services: policing, roads, environment, culture
  • Benefits and pensions

What you gave:

  • Paid work: the value your hours add to the economy
  • Unpaid care: hours spent raising children or caring for adults
  • Volunteering: hours given, priced at a replacement wage

One detail matters a lot. Paid work counts as value added, not as salary. Wages and taxes are just two ways of dividing up the same output, so adding either on top would count it twice.

Results page with the headline balance, cards and the year-by-year chart
The results page: headline balance with its honest range, then given and received, year by year.

How it works under the hood

Architecture diagram: browser talks to nginx on port 8080, which proxies /api to a FastAPI service on port 8000; the API reads the active pack from a packs volume; a methodology console and a build_pack tool can add new packs
Two containers and one volume. No database anywhere.

The whole thing runs as two Docker containers and one volume.

  • The browser app (React, Vite, Tailwind) shows the questionnaire, a running balance that updates with every answer, and the results. Your answers live in a small in-memory store in the page itself.
  • web, an nginx container, serves the app and forwards anything under /api to the calculator. The browser only ever talks to one address.
  • api, a FastAPI service, walks your timeline and looks up each statistic for a given country and year.
  • The packs volume holds the only thing saved on disk: versioned coefficient packs of published statistics, with nothing about any person.

When you change an answer, the whole profile goes to the API and a fresh estimate comes back as JSON. Nothing is written anywhere on the server. If you type fast, an older, slower reply is thrown away, so the meter never jumps backwards.

Questionnaire Work step with the running balance meter at the top
Step 3 of 6: the running balance at the top updates as you answer.

For whoever maintains the numbers, a build_pack tool fetches fresh statistics from the World Bank, the OECD, ILOSTAT and Eurostat. It prints a diff and writes nothing unless you pass --publish.

Four design decisions

  • Don't hold the data. No database, no accounts, no server-side copy of anyone's answers. The questions cover health, benefits, caring, migration and income, so rather than guard that data, I chose never to have it. The trade-off: close the tab and your answers are gone.
  • Put every assumption in versioned data, not code. Every statistic lives in a versioned "coefficient pack" with its source, its year and a label saying how solid it is. When the evidence is weaker, the uncertainty band widens on its own.
  • When a choice is unavoidable, make it a switch. How much of defence spending should one person "use"? How should an hour of care be priced? These choices move the result, so the tool exposes them as options instead of quietly picking one.
  • Write tests that guard honesty, not just code. One test fails if the double count of wages comes back. Another compares every pack value the engine actually touches with what the methodology page says it uses. Documentation drifts silently, and a failing build is the only reviewer that never gets tired.
🔎
Key idea: a number without its source, its year and its strength of evidence is just an opinion in a nice font. Make the provenance part of the data, and the honesty takes care of itself.

A tool with a warning label

A number like this could be misused, and I'd rather say that up front. The welcome screen, the methodology page and the PDF export all carry the same sentence: this estimate must not be used for hiring, lending, insurance, immigration or any other decision about a person.

That guard is a stated rule, not a technical lock. But the design avoids making misuse easy: it holds no data to mine and no profiles to look up. Illness, caring, study and unemployment all move the number, "and none of them makes a person a cost."

What was hard, and what I learned

  • Double counting hides in plain sight. My first version multiplied an occupation factor by an education premium. But the published degree premium already includes the fact that graduates hold more productive jobs. A graduate professional came out at 1.89 times the average worker. Now the occupation sets the level, and education only nudges it.
  • The model penalised a carer for being educated. Imagine someone who spent twenty-two years as a full-time carer and holds a master's degree. The model counted the cost of the degree and never credited anything back, because they had no paid work. I fixed that, and added a second, unpriced account that reports hours of care and people raised, never converted into money. The deeper lesson: the model only sees flows, not what people become. That is still open.
  • People move. Primary spending per student is roughly ten times higher in Germany than in India, so costing a whole school chain in one country got movers wrong by multiples. Now each stage is costed where you were actually living at the time.
  • Six countries, each chosen to break something. Germany, the Netherlands, the UK, the US, India and Argentina. Similar countries would have agreed with each other and proved nothing.

Try it yourself

The quickest way is the live version at play.sanyal.net/life-balance. There is nothing to install and no sign-up, and nothing you enter is stored.

To run your own copy instead, you only need Docker. No database, no environment file, no accounts.

docker compose up --build

Then open http://localhost:8080 for the app.

Closing thought

This project began as a philosophical conversation with my wife and a few very close friends. What do we owe to society? Have we done our share for the environment and for the people around us, or are we, honestly, net consumers? All of us come from different backgrounds, with different educations and different paths through life, and the question turned into one of the most engaging conversations we've had. Lifetime Contribution Balance was born from that evening.

It is not an exact calculation, and it never will be. But whatever the numbers say for any one person, my own sincere takeaway is this: most of us have taken more from society than we have given back to it so far. For me, that isn't a reason for guilt. It's a reason to keep giving.

Another side project that started with a conversation at home is Last Words, an online table for inventing (and losing) a language with friends.

If you try it, I'd love to hear what surprised you, or which assumption you'd argue with. Leave a comment below, and subscribe if you'd like the next build in your inbox.