Skip to content

@cloudflare/vitest-pool-workers: Same-type RPC calls to Durable Objects occasionally arrive out of order #13433

@threepointone

Description

@threepointone

Summary

When firing multiple stub.rpc() calls on a Durable Object stub without awaiting each one, adjacent calls occasionally swap order in vitest. This does not happen in production, wrangler dev, or vite dev — only in @cloudflare/vitest-pool-workers.

The reordering is non-deterministic: different runs show swaps at different positions, and small N (like 20) sometimes passes. The effect is more pronounced at higher N.

Reproduction

Repo: https://github.com/threepointone/test-do-rpc-fetch-ordering

npm install
npm test

The "rpc calls preserve send order" test will intermittently fail, and "rpc with N=100" fails consistently. Example output:

expected: [..., "call-5", "call-6", ...]
actual:   [..., "call-6", "call-5", ...]

With N=100, multiple swap pairs are scattered throughout the sequence.

For comparison, the same test logic passes reliably when run via wrangler dev or in production:

# wrangler dev — always passes
npx wrangler dev
curl http://localhost:8787/test-rpc-ordering?n=100

# production — always passes
curl https://test-ordering.threepointone.workers.dev/test-rpc-ordering?n=100

Likely Cause

The vitest pool communicates with workerd over a WebSocket transport. The dispatching of individual RPC calls through this transport likely introduces a race condition where adjacent calls can be reordered before they reach workerd's event loop. workerd's InputGate correctly processes them in arrival order, but they arrive in the wrong order.

This is supported by the fact that:

  • The swaps are always between adjacent calls (not large jumps)
  • The issue is non-deterministic (consistent with a race, not a logic bug)
  • Production and wrangler dev (which don't use the WebSocket transport) never exhibit this

Related

There is a separate, more severe ordering bug in workerd itself where mixed stub.rpc() + stub.fetch() calls are always reordered. That is tracked at cloudflare/workerd#6561 and is unrelated to this vitest-specific issue.

Metadata

Metadata

Labels

vitestRelating to the Workers Vitest integration

Type

No type
No fields configured for issues without a type.

Projects

Status

Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions