The row changed. The timer did not care.

Drive Redis from the database change stream, so a cached value is dropped the moment its row changes instead of whenever its time to live happens to run out.

TTL remaining
00:20
user:4471:profile
Fresh
Pick your poison
Short TTL
The cache stops being a cache. Every few seconds the database answers the same question again, and you pay for the cache twice.
Long TTL
The cache works and the answers are wrong. A user updates a record and watches the old one come back for another four minutes.
The second writer

Invalidating from application code works right up until a second service writes the same row. The batch job, the admin tool, the migration you ran once: none of them call your invalidate helper, and none of them know they were supposed to.

Different problem · one runtime

This page is orders.yaml.

orders.yaml YAML
name: orders
connectors:
  - name: orders-db
    type: source/postgres
    host: "${POSTGRES_HOST}"
    port: "${POSTGRES_PORT}"
    database: "${POSTGRES_DATABASE}"
    user: "${POSTGRES_USER}"
    publication: "${POSTGRES_PUBLICATION}"
    slot_name: "${POSTGRES_SLOT_NAME}"
    secret_refs:
      - { field: password, ref: postgres-password }
  - name: redis-out
    type: sink/redis
    # required config: /connectors/redis
routes:
  - from: orders-db
    to: [redis-out]
zipline pipeline apply -f orders.yaml

Not every connector in this pair ships yet. The spec is what it will be · check the roadmap for dates.