Dragonfly moves transaction scheduling decisions into each shard
Dragonfly 1.15 lets shards decide independently when uncontended work can execute out of order. Lua reply compatibility and native macOS builds address different adoption barriers.
A transaction that touches several shards does not necessarily face contention on every one of them. Dragonfly previously allowed out-of-order execution only after all participating shards determined that their key locks were free. The independent scheduling change lets each shard make that decision for its own work. An uncontended shard can qualify for out-of-order execution even when another participating shard cannot.
That change is part of Dragonfly 1.15.0, released on March 4. The release also adds native macOS builds and several Lua compatibility adjustments. Its transaction work improves how the engine uses independent shards, while the compatibility changes address assumptions that applications bring from Redis.
I am interested in Dragonfly because a process that uses a large machine's cores can postpone the operational work of running a distributed cache. Transaction scheduling is central to that argument. More worker threads help only if the coordination between them permits useful concurrency without changing the meaning of the commands.
Eligibility belongs to the shard
The scheduling patch replaces a coordinator-wide out-of-order state with a per-shard flag. In the earlier arrangement, the coordinator counted the shards that had obtained their locks. It marked the transaction out of order only when that count matched the transaction's full shard count. The new code records local eligibility while scheduling on each shard.
This is a change in the granularity of the decision. A transaction can contain work with different contention conditions. Requiring a single answer for the entire transaction throws away that distinction. The patch retains checks for consistent scheduling order and still acquires the required intent locks. Independent eligibility does not mean a shard ignores conflicts on its own keys.
The code also rejects a scheduling attempt when inserting a transaction into a queue would produce an inconsistent order under the documented lock conditions. That detail limits the interpretation of the optimization. The change permits more local progress within the locking algorithm. It does not grant arbitrary permission to reorder conflicting commands.
The new consistency test runs concurrent transactions over overlapping selections of keys. Each transaction increments its selected keys and then decrements them. The expected replies require increments to observe one and decrements to observe zero. By checking intermediate results, the test examines more than whether the final totals eventually cancel out. An incorrect interleaving could produce a plausible final value while violating those reply expectations.
The test skips the explicitly non-atomic transaction mode. That qualification prevents a misleading reading of its guarantees. The change concerns scheduling within the selected transaction semantics, and the regression test exercises the atomic case. A performance improvement in that mode does not make every possible server configuration equivalent.
The metrics change with the decision
Moving eligibility into each shard also changes how Dragonfly counts out-of-order execution. The patch removes the old coordinator transaction classification and adds a shard-level counter. Its INFO output includes tx_shard_ooo_total. This follows the implementation's new unit of observation, since one transaction can now have different scheduling outcomes on different shards.
A dashboard that interpreted the old category as a count of whole transactions cannot assume the new counter means the same thing. This is an operational consequence of the design, rather than a cosmetic metric rename. Comparing the figures requires knowing whether the count represents transactions or shard executions. The source does not provide a universal throughput improvement, and the scheduling mechanism alone cannot supply one.
I prefer this explanation to a general claim that transactions are faster. It identifies where the engine has removed an unnecessary all-shard condition. Workloads with contention distributed unevenly across participating shards have a clear reason to care about that condition, even though the gain still depends on their actual key access patterns.
Lua compatibility can require returning less precision
The Lua numeric-reply change addresses a different kind of compatibility. Its example is a script returning 42.9. Dragonfly supports integer and floating-point values in its Lua engine. For a RESP2 connection, its usual floating-point reply is a bulk string because RESP2 has no native floating-point reply type. RESP3 can return the double directly.
An application expecting the Redis-style integer reply can object even though Dragonfly preserves more numeric information. Version 1.15 therefore adds the optional --lua_resp2_legacy_float flag. The implementation applies floor and returns a long integer for the RESP2 case when the flag is enabled. The test checks that the same script still returns a double after switching the connection to RESP3.
EVAL "return 42.9" 0
HELLO 3
EVAL "return 42.9" 0
With the legacy flag enabled, the first request returns the integer 42. After HELLO 3, the second returns a RESP3 double containing 42.9. The flag is false by default in the patch. It supplies a specific compatibility behaviour without changing the RESP3 result.
The separate redis.log addition is narrower than its name might suggest. Dragonfly recognizes the function as a no-op. The tests call it with both arbitrary arguments and a warning-level constant. Accepting those calls lets a script continue, but it does not provide logging output. That distinction matters when a script's diagnostic calls are part of how an operator investigates it.
A native macOS build includes allocator work
The release's macOS support also involved runtime details beyond getting the linker to succeed. The initial build correction explicitly reports remaining test failures. A subsequent allocator-size fix explains that the macOS build used one allocation implementation while querying sizes through an incompatible function. The correction selects the matching size function when Dragonfly uses its configured allocator.
The final macOS adjustments restore search files to the build after their linker errors were resolved and provide a default memory limit for regression-test processes. These sources support the release's native-build announcement without implying a complete equivalence between every platform's deployment characteristics. Native compilation removes a development barrier, while the allocator and test changes show which platform assumptions needed explicit treatment.