Oxygen API Route failing after 30 seconds

Topic summary

A developer is experiencing an API route timeout issue in production that doesn’t occur locally. The route polls third-party APIs and terminates after exactly 30 seconds despite using waitUntil() to extend the worker’s lifecycle.

Key Technical Details:

  • Using waitUntil() with a promise that should keep the worker alive until the underlying async handleEvent function completes
  • The code creates a promise wrapper (refreshWorkerUntilPromiseFinishes) that repeatedly calls waitUntil() with promiseToWaitFor
  • Request logs show the worker lives for exactly 30 seconds (first log at 19 seconds, last at 49 seconds) before dying

Current Status:

  • The issue appears to be with the underlying worker API’s waitUntil property not functioning as expected in the deployed environment
  • Code snippet provided shows the implementation pattern being used
  • Developer is seeking advice on why waitUntil() isn’t preventing the 30-second timeout

No resolution or responses have been posted yet.

Summarized with AI on November 11. AI used: claude-sonnet-4-5-20250929.

My API route which polls 3rd party APIs is failing after exactly 30seconds even though I am calling waitUntil repeatedly.

It seems the waitUntil property from the underlying worker API is not working properly.

Very frustrating because everything works locally, but the deployed environment doesn’t work.

Please help and provide advice where you can.

Here is the essence of my code:

export async function action({request, params, context}: ActionFunctionArgs) {
  const body = (await request.json()) as TrainingCompleteResponse;

  // Moving this below the action led to some webhook handling bugs for me. Maybe moving it above so it's defined before it's used would work too? Leaving it here for now.
  const handleEvent = async (
    body: TrainingCompleteResponse,
    context: AppLoadContext,
  ) => {
    // lots of fetches
  };

  // Kick off event handler asynchronously and use waitUntil() repeatedly until
  // handler finishes to prevent worker from killing the handleEvent()
  // function early
  const handleEventPromise = handleEvent(body, context)
    .then(() => {
      console.log('Trained model event handler finished successfully');
    })
    .catch((error) => {
      console.error('Error handling trained model event: ', error.message);
    });

  const refreshWorkerUntilPromiseFinishes = async (
    promiseToWaitFor: Promise

As you can see I am calling waitUntil with a promise until the underlying promise is resolved, which should continually extend the life of my worker. However, looking at the logs for this request indicate it lives for exactly 30secs then dies.

Request id:

o2-c993991c-bd5e-43e0-adad-154e3471c468.86685b880b1a43fb

Logs (notice first log seconds time is 19, last is 49, indicating exactly 30secs elapsed):

![Screenshot 2024-03-18 at 10.48.23 PM.png|1478x158](upload://nboeMaEarswJq9UVaPOWy424X9k.png)

![Screenshot 2024-03-18 at 10.48.29 PM.png|1724x178](upload://2zdpYJrtFL6LXKEFjqAujdW4xhJ.png)