Skip to content

SQLite-backed workflow runner storage becomes unhealthy under concurrent runner/control-plane access #6179

Description

@schickling-assistant

I’m seeing SQLite-backed @effect/workflow / @effect/cluster runner storage become unhealthy when a long-lived runner process and multiple short-lived control-plane clients access the same workflow store concurrently.

Reproduction

https://github.com/schickling-repros/2026-04-effect-workflow-sqlite-lock

npm install
npm run repro

The repro uses:

  • one long-lived runner process backed by SingleRunner.layer({ runnerStorage: "sql" })
  • SQLite via @effect/sql-sqlite-node
  • many one-shot control-plane processes that concurrently call workflow start / poll operations against the same SQLite file

Expected

Concurrent control-plane access should stay healthy when talking to the same SQLite-backed workflow store as the runner.

Actual

The setup becomes unhealthy under contention. In the minimized repro, many control-plane operations time out. In the larger integration where I first hit this, the same family of failures also surfaced as PersistenceError and SqliteError: database is locked.

Versions

  • @effect/cluster: 0.58.0
  • @effect/workflow: 0.18.0
  • @effect/sql-sqlite-node: 0.52.0
  • effect: 3.21.0
  • Node: v24.14.0
  • OS: Darwin arm64

If useful, I can try a second reduced repro that focuses specifically on the PersistenceError path rather than the timeout/lockup symptom.


Filed by an AI assistant on behalf of @schickling

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.0Used for issues, pull requests, etc. that are relevant for the `v3` branch targeting Effect v3.bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions