Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
645cf33
feat(run-engine): concurrency-key virtual-time key builders
1stvamp Jul 23, 2026
e0e40bb
feat(run-engine): ckVirtualTimeScheduling options flag
1stvamp Jul 23, 2026
5d8d5ef
feat(run-engine): two-pass virtual-time CK dequeue command
1stvamp Jul 24, 2026
258e37f
feat(run-engine): register CK variants in vtime index on enqueue
1stvamp Jul 24, 2026
955befb
feat(run-engine): re-register CK variants in vtime index on nack
1stvamp Jul 24, 2026
d2de5cd
test(run-engine): fairness scenarios on the real batched dequeue path
1stvamp Jul 24, 2026
ac64ab6
test(run-engine): multi-consumer correctness + op-count budget
1stvamp Jul 24, 2026
44eeb5a
test(run-engine): default-off regression proof
1stvamp Jul 24, 2026
b2be0b7
feat(run-engine,webapp): wire ckVirtualTimeScheduling env flag (code-…
1stvamp Jul 24, 2026
6d8504a
chore(run-engine): ship note + comment/format cleanup
1stvamp Jul 24, 2026
0f860c8
fix(run-engine,webapp): address whole-branch adversarial review
1stvamp Jul 24, 2026
707b13c
docs(run-engine): record CK vtime known limitations for GA decision
1stvamp Jul 24, 2026
ef1e0b9
docs(run-engine): plan + references for virtual-time CK fair scheduling
1stvamp Jul 23, 2026
906509c
docs(run-engine): add fairness explainer diagrams
1stvamp Jul 24, 2026
14cadf4
fix(run-engine): move design docs out of the Mintlify docs/ tree; format
1stvamp Jul 24, 2026
903df26
docs(run-engine): tighten CK fairness server-changes note
1stvamp Jul 24, 2026
0e9d9ac
docs(run-engine): fix stale references in the CK fairness design docs
1stvamp Jul 26, 2026
6d18ea7
docs(run-engine): add CK virtual-time A/B benchmark plan and harness
1stvamp Jul 27, 2026
9083eac
docs(run-engine): make the e2e bench harness work on self-hosted
1stvamp Jul 27, 2026
d4e463d
docs(run-engine): add CK virtual-time benchmark results
1stvamp Jul 27, 2026
2b4e9c5
chore(run-engine): gitignore benchmark output artifacts
1stvamp Jul 27, 2026
dcf81fd
docs(run-engine): benchmark Redis CPU and memory vs concurrency-key c…
1stvamp Jul 28, 2026
03ab09d
chore(run-engine): drop benchmark, e2e, and design docs from the branch
1stvamp Jul 28, 2026
69173b3
fix(run-engine): stop an unservable variant pinning the ck virtual-ti…
1stvamp Jul 31, 2026
9bbc0e1
fix(run-engine): advance the ck virtual-time floor from servable vari…
1stvamp Jul 31, 2026
1a6d1a5
fix(run-engine): keep unservable ck variants in the fair order
1stvamp Jul 31, 2026
9053f34
fix(run-engine): make ck vtime pass 2 discover unregistered variants
1stvamp Aug 3, 2026
61d0aa4
test(run-engine): bound the ckManyKeys first-serve claim
1stvamp Aug 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .server-changes/2026-07-24-ck-fair-scheduling.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: feature
---

The run queue can now serve concurrency keys fairly, so one key with a large backlog no longer starves runs waiting on other keys. It is opt-in and off by default.
Comment thread
1stvamp marked this conversation as resolved.
Comment thread
1stvamp marked this conversation as resolved.
7 changes: 7 additions & 0 deletions apps/webapp/app/env.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -992,6 +992,13 @@ const EnvironmentSchema = z
RUN_ENGINE_TTL_CONSUMERS_DISABLED: BoolEnv.default(false),
RUN_ENGINE_TTL_WORKER_BATCH_MAX_WAIT_MS: z.coerce.number().int().default(5_000),

// Fair (virtual-time) ordering across concurrency-key variants of a base queue.
// Off by default; when off the run queue behaves exactly as before.
RUN_ENGINE_CK_VTIME_SCHEDULING_ENABLED: BoolEnv.default(false),
RUN_ENGINE_CK_VTIME_QUANTUM: z.coerce.number().int().positive().default(1),
RUN_ENGINE_CK_VTIME_WINDOW_MULTIPLIER: z.coerce.number().int().positive().default(3),
RUN_ENGINE_CK_VTIME_STATE_TTL_SECONDS: z.coerce.number().int().positive().default(86400),

/** Optional maximum TTL for all runs (e.g. "14d"). If set, runs without an explicit TTL
* will use this as their TTL, and runs with a TTL larger than this will be clamped. */
RUN_ENGINE_DEFAULT_MAX_TTL: z.string().optional(),
Expand Down
8 changes: 8 additions & 0 deletions apps/webapp/app/v3/runEngine.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ function createRunEngine() {
batchMaxSize: env.RUN_ENGINE_TTL_WORKER_BATCH_MAX_SIZE,
batchMaxWaitMs: env.RUN_ENGINE_TTL_WORKER_BATCH_MAX_WAIT_MS,
},
ckVirtualTimeScheduling: env.RUN_ENGINE_CK_VTIME_SCHEDULING_ENABLED
? {
enabled: true,
quantum: env.RUN_ENGINE_CK_VTIME_QUANTUM,
scanWindowMultiplier: env.RUN_ENGINE_CK_VTIME_WINDOW_MULTIPLIER,
stateTtlSeconds: env.RUN_ENGINE_CK_VTIME_STATE_TTL_SECONDS,
}
: undefined,
},
runLock: {
redis: {
Expand Down
1 change: 1 addition & 0 deletions internal-packages/run-engine/src/engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export class RunEngine {
workerItemsSuffix: "ttl-worker:{queue:ttl-expiration:}items",
visibilityTimeoutMs: options.queue?.ttlSystem?.visibilityTimeoutMs ?? 30_000,
},
ckVirtualTimeScheduling: options.queue?.ckVirtualTimeScheduling,
});

this.worker = new Worker({
Expand Down
5 changes: 4 additions & 1 deletion internal-packages/run-engine/src/engine/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
} from "@trigger.dev/redis-worker";
import type { ControlPlaneResolver } from "./controlPlaneResolver.js";
import type { FairQueueSelectionStrategyOptions } from "../run-queue/fairQueueSelectionStrategy.js";
import type { RunQueueMetricsEmitter } from "../run-queue/index.js";
import type { RunQueueMetricsEmitter, RunQueueOptions } from "../run-queue/index.js";
import type { MinimalAuthenticatedEnvironment } from "../shared/index.js";
import type { LockRetryConfig } from "./locking.js";
import type { workerCatalog } from "./workerCatalog.js";
Expand Down Expand Up @@ -126,6 +126,9 @@ export type RunEngineOptions = {
/** Max time (ms) to wait for more items before flushing a batch (default: 5000) */
batchMaxWaitMs?: number;
};
/** Fair (virtual-time) ordering across concurrency-key variants of a base queue.
* Passed through to RunQueue; off by default (undefined = today's behaviour). */
ckVirtualTimeScheduling?: RunQueueOptions["ckVirtualTimeScheduling"];
};
runLock: {
redis: RedisOptions;
Expand Down
Loading
Loading