Context
Public header ticker data is served by GET /api/activity/ (blog/api/data/router.py). Payload is built by build_activity_payload() in blog/api_views.py (raw SQL with CTEs) and cached under ACTIVITY_CACHE_KEY with ACTIVITY_CACHE_TTL (blog/api/constants.py).
Goals
Improve latency, database load, and observability for this hot read path without breaking the JSON contract consumed by the React header ticker.
Suggested work (pick / split)
- Baseline: Profile with Django Silk (
silk_profiler already lists /api/activity/) and/or EXPLAIN ANALYZE on the raw SQL; record p50/p95 and query plans.
- SQL / indexes: Confirm filters and
ORDER BY match existing indexes on Post (status, published_at, created_at); add or adjust indexes if plans show seq scans or heavy sorts at scale.
- Correctness vs “latest post”: Review ordering for latest published post (
lp CTE uses published_at only); align with product rules (e.g. COALESCE(published_at, created_at) if drafts/unpublished edge cases matter).
- Caching: Evaluate TTL (300s), cache stampede, optional cache versioning or invalidation hooks when posts/comments/users change (tradeoffs vs simplicity).
- API layer: Optional HTTP caching (
Cache-Control, ETag) if CDN/browser caching is desired (coordinate with ticker refresh UX).
- Tests / contract: Extend or add tests around payload shape and cache-miss behavior (
tests/unit/test_views_activity.py).
References
- Router:
blog/api/data/router.py — activity
- Payload:
blog/api_views.py — build_activity_payload
- Constants:
blog/api/constants.py — ACTIVITY_CACHE_KEY, ACTIVITY_CACHE_TTL
Tracking
Create a Linear issue with the same scope; link that Linear ID here once filed.
Context
Public header ticker data is served by
GET /api/activity/(blog/api/data/router.py). Payload is built bybuild_activity_payload()inblog/api_views.py(raw SQL with CTEs) and cached underACTIVITY_CACHE_KEYwithACTIVITY_CACHE_TTL(blog/api/constants.py).Goals
Improve latency, database load, and observability for this hot read path without breaking the JSON contract consumed by the React header ticker.
Suggested work (pick / split)
silk_profileralready lists/api/activity/) and/orEXPLAIN ANALYZEon the raw SQL; record p50/p95 and query plans.ORDER BYmatch existing indexes onPost(status,published_at,created_at); add or adjust indexes if plans show seq scans or heavy sorts at scale.lpCTE usespublished_atonly); align with product rules (e.g.COALESCE(published_at, created_at)if drafts/unpublished edge cases matter).Cache-Control,ETag) if CDN/browser caching is desired (coordinate with ticker refresh UX).tests/unit/test_views_activity.py).References
blog/api/data/router.py—activityblog/api_views.py—build_activity_payloadblog/api/constants.py—ACTIVITY_CACHE_KEY,ACTIVITY_CACHE_TTLTracking
Create a Linear issue with the same scope; link that Linear ID here once filed.