HarperFast / HarperFast/harper

Atomic increment racing TTL expiry is non-deterministic and diverges between RocksDB and LMDB

Open
#1,283 0 comments 0 reactions 1 assignee Claimed by @kriszyp View on GitHub
area:storage bug
Dominant language
JavaScript
Stars
89
Forks
10
Avg merge
2d 6h
Merged PRs (30d)
200

Description

## Summary
An atomic increment (`addTo`) applied to a record at the moment its TTL expires produces a **non-deterministic** result, and the two storage engines disagree.

## Repro
Found via exploratory QA (qa-explorer skill), harper `001bf7b9c` (v5.1.0, main).

Setup: a record with a short TTL and a numeric field; fire an atomic `addTo` increment timed to land right around the TTL-expiry instant.

**Observed:**
- **RocksDB:** flips run-to-run between resurrecting the pre-expiry value (e.g. old value 100 + 10 bids → 110) and starting fresh from 0 (→ 10), with identical code and timing.
- **LMDB:** consistently resurrects the pre-expiry value (110).
- The two engines disagree on the same workload.

**Expected:** deterministic, engine-consistent behavior — either the increment consistently operates on a fresh (post-expiry) record or it's consistently rejected/resurrected, the same way on both engines.

## Not affected
Plain concurrency is fine: 50 parallel atomic increments to a non-expiring record yield exactly 50 with zero lost updates on both engines. The issue is specifically the **increment ⨯ TTL-expiry race**.

## Notes
Not a crash or hang — a correctness/consistency surprise. A scratch reproduction test exists (qa-scratch/auction); run the TTL-race case several times to see the RocksDB flip. Can be promoted to `integrationTests/database/` (gating the race case until fixed).

_Filed from qa-explorer wave 1 (F-002). Medium confidence._

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.