341

How many users before I actually need a background job queue Backend

Small app, maybe 300 signups, everything currently happens inside the request. Sending the welcome email adds about 900ms to signup and generating a PDF invoice takes two to four seconds while the user watches a spinner. It works. I keep reading that I should have a queue and I don't know whether that's for me or for apps a hundred times bigger.

7 answers Share
Report

Answering anonymously — a moderator will review it first.

  • @midnight_pager · 4w ago · 3 replies

    It isn't a user count question, it's a latency and failure question, and you already crossed the line.

    The test I use: does the work need to finish before the user can be told what happened? Sending an email doesn't. Generating an invoice PDF doesn't either, you can show a link that appears when it's ready. Both of those belong out of the request at any scale, including ten users.

    The part that matters more than speed is failure. Right now, if your mail provider has a bad thirty seconds, your signup returns a 500 and the user thinks the account wasn't created. With a queue, the account is created and the email retries three times over ten minutes. That difference is worth more than the 900ms.

    You do not need a broker for this. If you already have Postgres, a jobs table plus select ... for update skip locked and a small worker loop is about eighty lines and will carry you a very long way.

    307
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @night_train_ned · 4w ago

      The failure framing changes it for me. I'd been thinking of the queue as a performance thing rather than a reliability thing.

      129
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
    • @midnight_pager · 4w ago

      That's how most people get sold on it. Add a attempts column and a run_after timestamp from day one, retries with a bit of backoff are the whole point.

      102
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report
  • @cold_storage_kim · 4w ago

    Two to four seconds of PDF generation in a request also means one slow user can occupy a web worker that someone else needed. At 300 users nobody notices, and the day you get a burst of traffic the whole app appears to be down for reasons that have nothing to do with the traffic.

    213
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @fg_stall · 4w ago

    Practical middle step if you don't want a worker yet: return the response first and do the email after, in whatever your framework calls an after-response hook. It's worse than a queue in every way, but it takes fifteen minutes and it gets the user out of the spinner today.

    122
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
  • @stack_trace_sy · 4w ago · 2 replies

    Counterpoint on scope: don't reach for a full queueing product at this size. A separate always-on worker process, a dashboard, a broker to keep alive, and now you're operating three things instead of one. Postgres-backed jobs first, migrate when the volume genuinely justifies it.

    170
    Share
    Reply

    Answering anonymously — a moderator will review it first.

    Report
    • @hotswap_hana · 4w ago

      Agreed, with one caveat. Make sure your jobs are idempotent from the start. Migrating queue technology later is easy, retrofitting idempotency onto a year of job handlers is not.

      106
      Share
      Reply

      Answering anonymously — a moderator will review it first.

      Report