Skip to content

Concurrency controls and flow limits#1421

Draft
NathanColosimo wants to merge 17 commits intovercel:mainfrom
NathanColosimo:codex/flow-limits-types-first-pass
Draft

Concurrency controls and flow limits#1421
NathanColosimo wants to merge 17 commits intovercel:mainfrom
NathanColosimo:codex/flow-limits-types-first-pass

Conversation

@NathanColosimo
Copy link
Contributor

@NathanColosimo NathanColosimo commented Mar 17, 2026

Context: Issue #1206 and discussion #301

Current status:

  • stubbed out the interfaces, construction, basic tests
  • Built initial world-local implementation
  • Built world-postgres implementation
  • have e2e basic nextjs stable + turbopack running
  • have temporary FLOW_LIMITS.md file explaining stuff

Todo:

  • clean up types so that they are shared if possible
  • review the pg db schema
  • try and share a single test contract to reduce test duplication & so all limit implementations follow the same spec

@NathanColosimo NathanColosimo requested a review from a team as a code owner March 17, 2026 19:33
@changeset-bot
Copy link

changeset-bot bot commented Mar 17, 2026

⚠️ No Changeset found

Latest commit: a6b603a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link
Contributor

vercel bot commented Mar 17, 2026

@NathanColosimo is attempting to deploy a commit to the Vercel Labs Team on Vercel.

A member of the Team first needs to authorize it.

@NathanColosimo NathanColosimo marked this pull request as draft March 17, 2026 19:33
@NathanColosimo
Copy link
Contributor Author

@VaguelySerious @pranaygp

Read:
workbench/example/workflows/99_e2e.ts
packages/world/FLOW_LIMITS.md

what do you think?

Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
I, nathancolosimo <nathancolosimo@gmail.com>, hereby add my Signed-off-by to this commit: b0e2f2a

Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
@NathanColosimo NathanColosimo force-pushed the codex/flow-limits-types-first-pass branch from e0ac4eb to b761df2 Compare March 18, 2026 21:22
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
@NathanColosimo NathanColosimo force-pushed the codex/flow-limits-types-first-pass branch from b761df2 to 1677f3d Compare March 18, 2026 21:52
I, nathancolosimo <nathancolosimo@gmail.com>, hereby add my Signed-off-by to this commit: 4b918ca

Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
@NathanColosimo
Copy link
Contributor Author

NathanColosimo commented Mar 18, 2026

I have await using lease = lock() working for both workflow level and step level

workflow level will block at that time and only re enqueue once lock can be acquired in FIFO order. and doesn't take up a concurrency slot for infra-level env vars like WORLD LOCAL MAX CONCURRENCY or whatever - which makes sense.

step level however:
if the lock is called as the first line or main thing in the step, it makes sense to abort the step (don't count it as an error towards max retries), and just come back once lock can be acquired - preAcquire the lock before resuming (so we don't spin up a step just to fail acquire) and pass the lock down to the step via the shared storage interface

what do we do if await using lease = lock() is called in the middle of a step?

  • we could either wait in process (taking up concurrency slot)
  • or we could wait in queue (which doesnt take up concurrency slot, but will re-rerun all the step code up until that point, so there will be extra side effects unless pre-lock code is idempotent) ? (right now I think this is best, I would rather not take up a concurrency slot)

@VaguelySerious @pranaygp

@VaguelySerious
Copy link
Member

@NathanColosimo We spent some time today discussing this and I'll get back to you with some ideas and thoughts tomorrow

Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
@VaguelySerious
Copy link
Member

VaguelySerious commented Mar 19, 2026

@NathanColosimo thank you for your patience. I just posted a WIP implementation spec for locks in the RFC discussion here. Curious to hear what you think.

This does not block your PR directly. This PR can still ship and add lock for local/postgres worlds, under a few assumptions:

  • The user-land code/DX stays the same (already true)
  • We get rid of the step_deferred event, since it's missing forward-compat. This can be resolved by, instead of storing an event, re-use step_retrying, but adding an attribute step_deferred to the queue message that calls the step, so that the step runtime knows to avoid increasing the retry counter.
  • We validate that as long as no lock statement is encountered, the added code in this PR does trigger for world-vercel, with the exception of checking for the lock statements (should be simple)
  • We ensure forward-compat when upgrading world-postgres to a spec similar to the proposed spec, not requiring active concurrency/rate-limits to be maintained (though could potentially write a migration to do so)

Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Signed-off-by: nathancolosimo <nathancolosimo@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants