↓ Skip to main content
  1. Writing/

Re-fetch on a 409 when two Oban jobs create the same record

··

When two Oban jobs GET the same record at once, both get a 404 and both POST it. The second POST gets a 409 Conflict. That 409 means the record exists now, so fetch it again and carry on.

We returned the 409 as an error instead. Oban retried the job until a later GET found the record. The job got there in the end, but each retry reported an error to AppSignal.

The fix matches the conflict right after the create. Request.create/1 is the POST, and request_get/1 is the same GET the job started with:

params
|> Request.create()
|> case do
  {:error, [%{"title" => "Conflict"} | _]} ->
    # another job created it between our GET and POST
    request_get(params)

  result ->
    handle_result(result)
end

That match takes any 409 Conflict as “already exists”. On an endpoint that can conflict for another reason, match the error detail too.

Glenn Roberts
Written by
Glenn Roberts
Hands-on engineer and former CTO. I help companies build with AI.