tellemiller

tellemiller

Cache hit ratio on oban_jobs at 65% - large completed backlog, is this expected?

We recently started running Oban with Oban Web on PostgreSQL (AWS RDS gp3) and noticed our oban_jobs buffer cache hit ratio sitting at 65%, with ~600 block reads per second. We investigated and wanted to share findings and ask a few questions.

What we found

Our table has ~434k rows, of which 433,371 (99.97%) are in the completed state. We have max_age: 7 days configured on the Pruner. Table size is 301 MB, index size 229 MB (560 MB total). Autovacuum is healthy, dead tuples at 8.1%.

The main query we traced the block reads to was Oban Web’s queue typeahead suggestion:

SELECT DISTINCT o0."queue" FROM "public"."oban_jobs" AS o0

The composite index from v08, (state, queue, priority, scheduled_at, id), has state leading, so this query can’t use it efficiently and falls back to a large sequential scan. It’s worth noting, we also suspect some of our sequential scan count was inflated by developers running diagnostic queries during the investigation itself.

Actual performance metrics are all fine: avg read latency 0.6ms (peak 0.8ms), ReadIOPS at 650 of 3,000 available, 1.2GB freeable memory. So this isn’t causing a real problem today.

Questions

  1. Is a 65% cache hit ratio on oban_jobs expected at this scale with a large completed backlog? Given our real metrics are healthy, is this simply a normal consequence of the table size relative to shared_buffers?

  2. We’re reconsidering our 7-day retention, but job retrospection is genuinely useful to us. What does effective pruning look like in production for teams that want to retain some history without the table growing unbounded?

  3. For the Web typeahead query: queue names are statically defined in our config, so a full table scan to populate suggestions feels unnecessary. The hint_query_limit(:queues) resolver callback seems like the right lever to limit the scan, but has a resolve_queues style callback been considered, to allow serving suggestions directly from known config rather than the DB?

First Post!

sorentwo

sorentwo

Oban Core Team

That query would only run once every 5 minutes because it is cached locally. A sequential scan is expected in this case. Most of the typeahead queries, and the composite filters they help compse, aren’t index backed because they’re infrequent.

That’s entirely possible. Most of that data wouldn’t be accessed frequently under normal circumstances, and Oban will hit indexes for frequent queries.

The fewer jobs you retain, and the leaner you keep the table, the better performance you’ll have in general. One solution for keeping older jobs is DynamicPruner’s before_delete callback.

Active queues are vailable via Oban.Met.labels/1, or Oban.Met.checks/1, but queues you want to filter by aren’t always actively running. Or, you’re running multiple Oban instances that share a single database, or using Web to inspect Python jobs. In all of those cases, the database is the only real source of truth.

Where Next?

Popular in Troubleshooting Top

rayex
When I compile hex package io_ansi_plus, I get error “Codepoint failed”. Why? and why are the “Got:” and “Hint:” codepoints identical? It...
New
bugnano
Hello everyone. I’m the author of GitHub - bugnano/wtransport-elixir: Elixir bindings for the WTransport WebTransport library · GitHub ,...
New
anotherpit
Summary A downstream job that deps on a graft correctly waits for the grafted jobs at one graft level, but stops waiting when the workflo...
New
rathoud96
Environment Elixir 1.18.3-otp-27 / OTP 27.3.4 Oban 2.20.2 Phoenix 1.7.x db_connection 2.8.1 / Postgrex 0.21.1 Infrastructure: Google Cl...
New
ktayah
Environment Oban Pro: 1.7.6 Oban: 2.22.1 Issue When a sub-workflow built with Workflow.put_context/2 is attached to a parent via ...
New
Lotoen
Hello, I am currently using Elixir 1.18.4 and OTP 27 with Linux Mint 22.3 - Cinnamon 64-bit as my operating system. I came across this er...
New
tellemiller
We recently started running Oban with Oban Web on PostgreSQL (AWS RDS gp3) and noticed our oban_jobs buffer cache hit ratio sitting at 65...
New
rayex
For hex package islands_score the source @spec for function format/2 is as such: @spec format(t, keyword) :: :ok Why does it show on 4 ...
New
ndan
Oban.Pro.Migration.up(version: "1.7.0", only: :indexes) fails on partitioned oban_jobs table when upgrading Oban Pro from 1.6 to 1.7 def...
New
hakarabakara1
I have three modules, a Business which is associated Tags and Categories though join tables business_tags and business_categories. I inte...
New

Other popular topics Top

New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41989 114
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31265 143
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement