tursodatabase / tursodatabase/libsql-client-ts

`concurrency: 0` is documented to disable the limit, but expandConfig turns it into 20

Open Beginner friendly
#351 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
576
Forks
69
PR merge metrics
No merged PRs in 30d

Description

api.ts documents concurrency: 0 as disabling the limit:

By default, the client performs up to 20 concurrent requests. You can set this option to a higher number to increase the concurrency limit or set it to 0 to disable concurrency limits completely.

https://github.com/tursodatabase/libsql-client-ts/blob/889a2ec3130b9fb3b32fda9e19ebd33864efc509/packages/libsql-core/src/api.ts#L59-L63

but expandConfig normalizes with a falsy-default:

concurrency = Math.max(0, concurrency || 20);

https://github.com/tursodatabase/libsql-client-ts/blob/889a2ec3130b9fb3b32fda9e19ebd33864efc509/packages/libsql-core/src/config.ts#L56

0 || 20 is 20, so the documented value silently becomes the default:

import { expandConfig } from "@libsql/core/config";

expandConfig({ url: "https://example.turso.io", concurrency: 0 }, true).concurrency;
// actual: 20 — expected: 0

The rest of the chain already handles 0 as documented: both clients feed config.concurrency straight into promise-limit, which treats a falsy limit as pass-through. Only the clamp in expandConfig loses the value, so the fix is one line:

concurrency = Math.max(0, concurrency ?? 20);

One semantic decision for you: with ||, negative values currently clamp to 0 and then mean "unlimited" further down; with ?? they still clamp to 0 and keep meaning unlimited, but you may prefer to reject them explicitly. Worth keeping "0 = unlimited" as the contract either way rather than redefining the docs — on serverless runtimes a finite limit is itself a hazard: one client instance is typically shared per isolate, so the semaphore queues query 21+ in module-scope state and starts it from whichever request's query finishes first. On Cloudflare Workers, where a finished request's continuations are canceled, that cross-request handoff can wedge the queue. concurrency: Infinity survives the || clamp and is the workaround that disables the limit today; concurrency: 0, the documented form, silently restores the cap of 20.

Happy to send the one-line PR with regression cases for undefined, 0, a positive number, and a negative number.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/libsql-core/src/config.ts at expandConfig and compare its concurrency normalization with the contract documented in packages/libsql-core/src/api.ts. Verify behavior through promise-limit and add regression cases for undefined, 0, positive, and negative values; done means 0 remains unlimited while the documented defaults and clamping behavior are preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.