Skip to content

ref(manual-jobs): bound the manual jobs Redis keys - #8397

Merged
strongs merged 3 commits into
masterfrom
strongs/infreng-480-manual-jobs-ttl
Aug 27, 2026
Merged

ref(manual-jobs): bound the manual jobs Redis keys#8397
strongs merged 3 commits into
masterfrom
strongs/infreng-480-manual-jobs-ttl

Conversation

@strongs

@strongs strongs commented Aug 26, 2026

Copy link
Copy Markdown
Member

Manual jobs leave four keys behind: start_time, execution_status, log, job_type. Most especially the log key grows one entry per log line (no cap). lock is already bounded at 24hr, so we're using the same pattern here, w/ a different TTL.

Notes:

  • Retention window is 90 days - chose this because if a record is dropped, a job that already ran will report NOT_STARTED and the UI will make it look like the job is re-runnable. So we want a TTL that gives re-runs plenty of time to happen and avoid this issue. Also 90 days is the standard retention cap via snuba/state/retention.py. After that point the rows the job acts on have aged out anyways
  • Capping log lines at 500 since view_job_logs already refuses to render more than 500 lines anyways
  • TTL windows start at end of runs, so we won't age out even massively long runs (although reealistically that ain't happening with a 90 day ttl let's be real)

Refs INFRENG-480

🤖 Generated with Claude Code

Every manual job run left four Redis keys behind for good: the start
time, the execution status, the log list and the job type. Nothing
removed them, and the log list grew one entry per log line with no cap.
These sit on a long-lived cluster in US, DE and US2, so the growth was
slow but monotonic. The job lock in the same file was already bounded at
24 hours, and this applies the same pattern to the rest.

All four keys now expire from one shared constant, 90 days. The record
is human-facing history, not operational state, but it is also a re-run
guard: run_job refuses a manifest job whose status key exists, and the
admin UI shows View Logs instead of Run for the same reason. So a window
that is too short makes a job that already ran look re-runnable. 90 days
is the cap that snuba/state/retention.py puts on standard retention, and
the row-touching jobs write only to tier-1 tables. Past that the rows a
job acted on have aged out, so the question the record answers no longer
has a target.

The log list is capped at 500 lines and keeps the newest ones.
view_job_logs already refused to render more than 500 lines, so a longer
list was unreadable anyway, and a failing run appends its error and
traceback last. The expiry is refreshed on every log line and every
status write, so a long run does not lose its own state while it is
still going.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 26, 2026

Copy link
Copy Markdown

@strongs
strongs marked this pull request as ready for review August 26, 2026 22:22
@strongs
strongs requested a review from a team as a code owner August 26, 2026 22:22
@strongs
strongs requested a review from a team August 26, 2026 22:22
_redis_client = get_redis_client(RedisClientKey.MANUAL_JOBS)

# One run of a job may hold the lock for this long
MANUAL_JOB_LOCK_TTL_SECONDS = 24 * 60 * 60

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on timedelta(days=1) instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'd be fine and probably more readable but also every other redis expiry uses plain seconds, and keeping it in plain numbers makes it a bit harder to mix up the units since it's pinned to the type. i'll probably just leave for now 🤷

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh whoops, I've been using timedelta for mine

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's fine too

Comment thread snuba/manual_jobs/redis.py Outdated
@strongs
strongs merged commit be3965d into master Aug 27, 2026
66 checks passed
@strongs
strongs deleted the strongs/infreng-480-manual-jobs-ttl branch August 27, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants