Blog · Architecture

    Guide7 min read·Unix Calculator Editorial Team·Apr 5, 2026

    Caching Strategies for Time-Sensitive Data

    Quick answer: Set cache TTL by calculating seconds until the content is invalid: ttl = max(0, next_change_unix - now). For event-driven correctness, store a last_modified epoch in metadata and derive ETags or surrogate keys from it. Never deploy unbounded caches with no expiry or version — stale financial and auth-adjacent data is how incidents start.

    TTL-Based Cache Invalidation

    Absolute instants beat relative English phrases in configuration. When a feed publisher tells you the next quote refresh is at epoch T, your edge should not guess "five minutes" — compute the remaining seconds at write time. Store cached_at alongside payload bodies for observability so support can answer "how old was this JSON?" from logs without replaying user traffic.

    async function getCachedData(key, fetchFn, ttlSeconds = 300) {
      const raw = await redis.get(key);
      if (raw) {
        const { data, cached_at } = JSON.parse(raw);
        const age = Math.floor(Date.now() / 1000) - cached_at;
        console.log(`Cache hit — age: ${age}s`);
        return data;
      }
      const data = await fetchFn();
      await redis.setEx(
        key,
        ttlSeconds,
        JSON.stringify({ data, cached_at: Math.floor(Date.now() / 1000) })
      );
      return data;
    }

    Timestamp-Based ETags

    A strong ETag derived from a monotonic updated_at lets browsers and intermediaries skip body download entirely. Use quoting rules from RFC 9110; compare with byte-for-byte equality on If-None-Match.

    app.get('/api/rates', async (req, res) => {
      const rates = await getRates();
      const etag = `"${rates.last_updated}"`;
      if (req.headers['if-none-match'] === etag) {
        res.status(304).end();
        return;
      }
      res.setHeader('ETag', etag);
      res.setHeader('Cache-Control', 'public, max-age=60');
      res.json(rates);
    });

    CDN Cache with Surrogate Keys

    Fastly, Cloudflare Workers, and Varnish support surrogate key headers listing logical entities (article-42, user-7). When an upstream mutation completes, purge every key containing that entity without flushing the whole domain. The purge API itself should be idempotent and authenticated — attackers love wide bans triggered through stolen dashboard cookies.

    Cache Stampede Prevention with Timestamps

    When a hot key expires, thundering herds recompute the same expensive query. Mitigations include single-flight locks, stale-while-revalidate with a probabilistic early refresh, and jitter added to TTL so synchronized clients do not line up on the same second. Encode lock owner + lease deadline as integers for easy sorting in Redis streams or DynamoDB conditional writes.

    Best Practices Summary

    PracticeWhy
    Integer epochs in keysAvoid float serialization mismatch across stacks
    Server Date headersClients correlate skew without trusting device clock
    Derived ETags304 responses save bandwidth on immutable histories
    Purge tests in CISurrogate maps rot without automation

    Key takeaways

    • Compute TTL from authoritative next-change time, not vibes.
    • ETags from updated_at enable cheap revalidation.
    • Surrogate keys connect business events to CDN invalidation.
    • Add jitter and single-flight to prevent stampedes.
    • Log cached_at for debugging stale UI screenshots.

    Written by Unix Calculator Editorial Team — Senior Unix/Linux Engineers. Last verified May 2026.

    Timestamp converter

    Get the Unix Timestamp Cheatsheet

    One email. Instant cheatsheet. No drip sequence.

    Advertisement