All 34 regions operational / Queues v2 is generally available — durable fan-out, ordered keys, replay from any offset Read the release→
Oxbow logo oxbow
NEWQueues v2 — ordered keys and replay→

Ship functions to the edge. Queue everything else.

Oxbow runs your handlers in 34 regions, a few milliseconds from every user, and hands the slow work — charges, emails, webhooks, fan-out — to durable queues that retry until it is done. One deploy. Every hop traced.

$ npm install -g @oxbow/cli then ox deploy
Trace 7f3a·c21 23.4ms edge · fra1 kv.get queue.publish
34regions, one deploy command
2.1msmedian cold start, TypeScript
1.9Tinvocations served in August
0messages lost since Queues v1

Running the request path for 4,200 teams — from two-person startups to a payments network settling in eleven currencies.

The platform

One deploy for the request path and everything after it

Most outages are not in the handler. They are in the retry you forgot, the cron that ran twice, the webhook nobody traced. Oxbow ships the four together so the seams are ours to get right.

Edge functions

Your handler, a few milliseconds from every user

Write a function, export it, deploy. It runs in all 34 regions with the same code, the same secrets and the same logs — no per-region config to drift.

export default handler(async (req) => { const cart = await kv.get(req.params.id) return Response.json(cart) }) 200 OK11ms · served from fra1 · 18.4 kB

Durable queues

Retries you do not have to write

At-least-once delivery with idempotency keys, backoff and a dead-letter queue by default.

184k messages a second at peak, one customer, last Black Friday

Schedules

Cron that runs once

Not once per region, not twice after a failover. Leader-elected, logged and replayable.

nightly-reconcile0 2 * * *in 11h 58m expire-carts*/15 * * * *in 4m weekly-digest0 9 * * 1Mon 09:00

Traces by default

Every request, every hop, no agent to install

The runtime writes the spans, so a trace follows a request from the edge through the queue into the consumer that finished the job — even when that was four retries and two hours later.

POST /api/checkout kv.get cart queue.publish consume · attempt 2

Cold starts

2.1ms

Median, TypeScript, measured from socket accept to first byte. Isolates are warmed on deploy, not on the first unlucky request.

Preview deploys

A live URL for every pull request

Readyfeat/split-payments Buildingfix/refund-retry Closedchore/bump-sdk

Data residency

Pin a function, a queue or a key to one jurisdiction

eu us ap uk

Requests from anywhere still land at the nearest edge; the data never leaves the region you chose.

Write it, read it

Sixteen lines of consumer. One trace that explains it.

Queues, retries and idempotency are arguments, not infrastructure. When a message takes a second attempt, the trace shows you both — and why the first one failed.

orders.tsoxbow.toml
1import { queue, kv } from '@oxbow/sdk' 2 3export const orders = queue('orders.created', { 4retries: 5, 5backoff: 'exponential', 6deadLetter: 'orders.failed', 7}) 8 9orders.consume(async (msg, ctx) => { 10if (await kv.get(`seen:${msg.id}`)) return 11await ctx.fetch('https://ledger.internal/charge', { 12method: 'POST', body: msg.body, 13}) 14await kv.set(`seen:${msg.id}`, 1, { ttl: '7d' }) 15}) 16// deploy: ox deploy --prod
Trace 9c41e0 · orders.created → consume 31.4ms
Delivered Attempt 2 of 5 fra1 · msg 01J8Z4K9 · idempotency key hit on replay
010ms20ms30ms
queue.deliver29.1ms
consume26.0ms
kv.get seen1.8ms
fetch ledger16.4ms
tls + connect3.9ms
kv.set seen2.2ms
ack0.9ms
Attempt 1 ledger.internal returned 503 after 5.0s · retried with 2s backoff

The network

34 regions. Your code in every one of them.

Requests land at the nearest region and run there. Queue messages move between regions on our private backbone, so a consumer in São Paulo can finish what a request in Frankfurt started.

A dot-matrix map of the world with Oxbow's regions marked sfo1 · 8ms iad1 · 6ms gru1 · 11ms fra1 · 7ms jnb1 · 14ms bom1 · 12ms sin1 · 9ms nrt1 · 8ms syd1 · 10ms
11Americasp50 to user 7ms
9Europep50 to user 6ms
11Asia-Pacificp50 to user 9ms
3Middle East and Africap50 to user 13ms

From the teams on call

Fewer pages. Shorter ones, too.

−71% checkout p99

We moved checkout off three regional clusters and onto one deploy. The p99 dropped because the request stopped crossing an ocean, not because anyone tuned anything.
MOMaren OstbyStaff engineer, Parcelry

0 double charges since

The idempotency key is a queue option, so nobody has to remember it. Our worst incident last year was a retry storm. This year we have not had one.
RARafael AmaralHead of platform, Sundial Pay

4 min median time to cause

When a webhook fails at 3am, the trace already has the consumer, the retry and the upstream 503 in one view. On-call went from archaeology to reading.
JTJoon TakaharaSRE lead, Kiteline

Free to start

Deploy your first function before this page finishes loading elsewhere

One million invocations and a hundred thousand queue messages a month on the free plan, no card. When you outgrow it, you pay for requests — never for idle.

$npm install -g @oxbow/cli $ox init hello --template queue $ox deploy ✓ Live in 34 regions3.8 s $