Your store accepts a lifetime only alongside a write, and the entries already hold values you must not lose. How do you give them a deadline?
answer
- no way in without touching the value
- read-modify-write, and its race
- the bytes travel twice
- windowed keys end together
- make every write carry it
basics
~20 sWrite the value again with a lifetime — that costs a read first and can replace a concurrent update. Or carry the deadline inside the value, which readers must enforce. The repair that lasts is making every write carry its deadline.
solid answer
~50 sWhere a store takes a lifetime only as a parameter of a write, there is no operation that puts a deadline on an entry without touching its value, so every option has a cost. The direct route is a read-modify-write: read the current value, write it back with a lifetime. That pays an extra round trip, sends the value's bytes a second time, and replaces whatever another caller stored in between — contain that with a conditional write or a sole-writer path. The alternatives are to carry the deadline inside the value and have every reader treat a past-deadline value as absent, which frees no memory and pushes enforcement back into application code, or to name entries by a time window so a whole window shares one deadline set at write. The real repair is to make every write carry its deadline.
go deeper
Take away the fact underneath this: not every store lets you add a deadline to an entry that already exists, and where it does not, the only way in is writing the value again.
Explain the read-modify-write and its price — an extra round trip, the value sent twice, and the window in which another caller's write can be replaced by yours.
Show the judgment: pick the containment that fits (conditional write, sole-writer path, time-windowed keys), pace a bulk repair against the tier's latency, and say plainly that a deadline inside the value frees no memory.
Treat it as an interface decision — expiry handling behind one narrow surface, so a store that lacks a standalone attach is a fallback in one implementation rather than an assumption baked into every call site.
## The constraint, stated precisely Stores in this class differ in how a deadline may reach an entry. Some expose a standalone operation that attaches, replaces or clears a deadline without touching the value. Others accept a lifetime only as a parameter of a write — and there, an entry written without one cannot be given a deadline except by writing it again. A design that assumed the first posture and is deployed onto the second has a population of **permanent entries** and no cheap way to fix them. Everything below is an answer to that constraint, and every one of them costs something. ## Option 1 — write the value again with a lifetime The direct route: read the current value, then write it back with a lifetime attached. What it costs: - **Two round trips instead of none**, for every entry you repair. - **The value's bytes on the wire twice.** For a large value this is the dominant cost, and repairing many of them at once is a self-inflicted load spike on the tier. - **A race.** Between your read and your write, another caller may have stored a newer value; your write replaces it. That is the ordinary interleaving hazard of any read-modify-write, and the containment is the same: use a conditional write where the store offers one, do the repair only from a path that is the sole writer of that entry, or accept the loss where the value is regenerable. - **Side effects of writing.** A write is a write: it replaces the value wholesale rather than amending it, and any per-entry bookkeeping the store keys off writes is touched. Where you already hold the value — because you just computed it — none of the read cost applies, and this is simply the correct write. ## Option 2 — carry the deadline inside the value Store a deadline as a field of the value and have every reader compare it against the current time, treating a past-deadline value as absent. | Property | Result | |---|---| | Removal of the memory | Never happens on these grounds; the entry stays until something else removes it | | Enforcement | In every reader, including ones written later by other teams | | Correctness under a wrong clock | Depends on whichever host reads it | | Attaching to existing entries | Still needs a write, so it does not solve this problem on its own | | Useful for | Reporting how long is left, and finer granularity than the entry allows | The honest summary is that this is not an expiry mechanism. It is an application-level staleness check that happens to live in the same value, and it reintroduces exactly the application-side obligation an attached deadline was supposed to remove. ## Option 3 — put the lifetime in the shape of the keyspace Name entries so that a whole group ends together — a window identifier in the key, with every entry in that window written with a lifetime that covers the window. New writes land in the current window, old windows end on their own, and no repair operation is needed for an entry that already exists because entries never outlive the window they were written into. This is a genuine fix for counters, rollups and anything naturally bucketed by time, and useless for an entry whose identity is a single long-lived thing. The naming scheme itself is a keyspace-design concern; what belongs here is the consequence: the deadline arrives with the write, which is the only posture this kind of store supports. ## Option 4 — make every write carry the deadline The permanent repair. Route writes through one place that requires a lifetime, so an entry with no deadline can only be created deliberately and with a named reason. On a store that accepts a lifetime only at write, this is not a nicety — it is the only posture that does not need a repair mechanism, because a repair mechanism does not exist. ## Choosing between them | Situation | Reach for | |---|---| | You already hold the value | Write it again with a lifetime | | Large values, many entries | Time-windowed keys, or accept a paced repair | | Concurrent writers on the same entry | A conditional write, or leave the repair to the writer that owns it | | The design needs finer granularity than the entry | Deadline inside the value, with every reader enforcing it | | Anything greenfield | Every write carries its deadline | ## What to say out loud The answer that marks experience is the first sentence: *this store has no way to attach a deadline without touching the value, so every option is a write or an application-level check.* Then the costs — the extra round trip, the bytes twice, the race — and then the observation that the same design on a store with a standalone attach operation would have none of this, which is precisely why expiry handling should sit behind one interface rather than being assumed at each call site.
- Does writing the value again change anything besides the deadline?Yes. It replaces the value wholesale rather than amending it, so any change another caller made since your read is lost, and any per-entry bookkeeping the store keys off writes is refreshed. On a design where the deadline is meant to move only on real updates, a repair write is indistinguishable from a real one — which is why the repair should be issued from the path that owns the entry.
- How do you repair a large population of entries without a load spike?Pace it. Repair in small batches with a bounded rate, prefer the path that already holds each value so no read is needed, and watch the tier's latency while it runs rather than the job's throughput. A repair that sends every value back over the wire as fast as it can is a self-inflicted incident on a tier whose whole value is a fast round trip.
saying these in an interview costs you the question
- Assumes a standalone attach operation exists on every store.
- Rewrites values to attach deadlines with no regard for concurrent writers.
- Thinks a deadline held inside the value gets the memory back.
- Repairs a whole keyspace in one pass and calls the latency unrelated.
- Believes reading a value before rewriting it makes the pair atomic.