Skip to main content

Import

import { timeout } from 'hono/timeout'

Usage

const app = new Hono()

app.use(
  '/long-request',
  timeout(5000) // Set timeout to 5 seconds
)

app.get('/long-request', async (c) => {
  await someLongRunningFunction()
  return c.text('Completed within time limit')
})

Parameters

duration
number
required
The timeout duration in milliseconds.
exception
HTTPException | HTTPExceptionFunction
The exception to throw when the timeout occurs. Can be:
  • An HTTPException object
  • A function that receives the context and returns an HTTPException
  • Default: HTTPException(504, { message: 'Gateway Timeout' })

Signature

timeout(
  duration: number,
  exception?: HTTPExceptionFunction | HTTPException
): MiddlewareHandler

type HTTPExceptionFunction = (context: Context) => HTTPException

Examples

Basic usage

app.use(
  '/long-request',
  timeout(5000) // 5 second timeout
)

app.get('/long-request', async (c) => {
  await someLongRunningFunction()
  return c.text('Completed within time limit')
})

Custom error message

import { HTTPException } from 'hono/http-exception'

app.use(
  '/api/*',
  timeout(
    10000,
    new HTTPException(408, {
      message: 'Request Timeout: Operation took too long',
    })
  )
)

Dynamic error based on context

app.use(
  '/api/*',
  timeout(5000, (c) => {
    const path = c.req.path
    return new HTTPException(504, {
      message: `Timeout occurred for ${path}`,
    })
  })
)

Different timeouts for different routes

const app = new Hono()

// 30 second timeout for uploads
app.use('/upload/*', timeout(30000))

// 5 second timeout for API
app.use('/api/*', timeout(5000))

// 1 second timeout for health checks
app.use('/health', timeout(1000))

With error handler

app.use('/api/*', timeout(5000))

app.onError((err, c) => {
  if (err instanceof HTTPException) {
    if (err.status === 504) {
      console.error('Timeout occurred:', c.req.path)
      return c.json(
        { error: 'Request timeout', path: c.req.path },
        504
      )
    }
  }
  return c.json({ error: 'Internal Server Error' }, 500)
})

Timeout for specific async operations

app.get('/data', timeout(10000), async (c) => {
  // This entire handler must complete within 10 seconds
  const data1 = await fetchData1() // 3 seconds
  const data2 = await fetchData2() // 4 seconds
  const data3 = await processData(data1, data2) // 2 seconds
  
  return c.json({ data3 })
})

Behavior

  • Races the handler execution against a timeout timer
  • Throws the specified HTTPException if timeout is reached
  • Default exception is 504 Gateway Timeout
  • Cleans up the timer after completion (whether success or timeout)
  • Works with async handlers
  • Timer is cleared even if handler throws an error
  • Can be applied globally or to specific routes
  • Multiple timeout middleware can be chained (innermost takes precedence)

Build docs developers (and LLMs) love