‹ Build Your First Tool Lesson 13 of 16
Contents Lesson 13 of 16

5 min read · practitioner

How old is this number, really?

Your tool shows prices. Underneath every one of them sits a question almost no dashboard answers honestly: as of when?

Three different things that all look like "the price"

What you called What it is Typical age
/real-time/{ticker} latest quote your plan permits minutes, or delayed by the exchange's rule
/eod/{ticker} the official close of a completed session yesterday, or older over a weekend
a cached copy whatever your server stored as old as the cache

They render identically. A number is a number on screen, and nothing about 310.34 tells you whether it is from thirty seconds ago or last Friday. That is the whole problem.

Read the age from the data, never from the plan name

Every quote carries its own timestamp. Use it:

const ageMinutes = Math.round((Date.now() - quote.timestamp * 1000) / 60_000);

Do not infer freshness from your subscription tier. The plan name is a claim about what you should be getting; the timestamp is evidence about what you got, and the two disagree more often than you would expect. The market may be closed. The feed may lag. A cache may have served you. Only one of those is visible in the response, and it is the timestamp.

Say what the age supports, not what it is

"12 minutes old" is data. What a person needs is what they can do with it:

  • Under a minute — effectively live. An alert built on this is honest.
  • A few minutes to about a quarter of an hour — the usual delayed feed. Fine for watching, checking, reporting. An alert fires exactly that late, so do not build one that pretends otherwise.
  • Hours — a snapshot, not a quote. It answers "where did this close", never "where is it now".
  • More than a day — an end-of-day close wearing a quote's clothes. Useful for history, useless for anything measured in minutes.

Print the band next to the number. This is the panel that makes the wall in the next lesson honest rather than a sales message: when the limit bites, you will read it off your own screen instead of being told about it.

Prove it to yourself

On 2026-08-25, /eod/AAPL.US returned these completed sessions:

[{"date":"2026-08-20","close":311.3,"volume":40959200},
 {"date":"2026-08-21","close":309.35,"volume":46876800},
 {"date":"2026-08-24","close":310.34,"volume":34673600}]

And /real-time/AAPL.US at the same moment reported close: 310.34 with previousClose: 309.35.

Look carefully. The "live" close equals the 24 August end-of-day close, and previousClose equals the 21 August close. Nothing is broken: the session had not produced a newer print at that moment, so the freshest available number was the last close. A dashboard that labelled that "live" would be lying without a single wrong number in it.

This is why the label matters more than the value.

Caching is your quota strategy, and it must be visible

Serving a stored copy for a minute is a legitimate way to make a page cheap. It is also a way to show stale data silently, which is the exact sin this lesson is about. If you cache, the age you display must be the age of the data, not the age of the request that served it.

Try it now

Put a data-age line on your watchlist, computed from the response timestamp, with the band it belongs to. Then check it at three moments: during market hours, an hour after the close, and on a weekend. Write down the three ages. That table is the actual freshness of your tool, measured rather than assumed, and it is what the next lesson works from.