Skip to content
About
Main content

The false-alarm floor of a cross-table check

Simulate a modelNeeds Python

Problem

A referential-integrity check (every order's customer must exist) assumes both tables are complete at the moment of the check. When they load on different schedules, they are not: an order from a customer who signed up after the last customer load looks orphaned until the next one. That produces a floor of false alarms set by the load schedule, which no threshold can tune away. The fix is to check only rows old enough that their references must have arrived: .

Simulate two loaders. Customers load every L minutes, orders every 10 minutes. Let 2% of orders come from customers who signed up less than 60 minutes earlier. For L in 5, 15, 30, 60, 120 minutes, count how many orders are "orphans" at the moment each order arrives. Plot the false-alarm rate against L. Then add "allowed lateness" (only check orders older than L + 10 minutes).

The question. How does the false orphan rate grow with the customer load interval, and what does allowed lateness do to it?


Predict

With customers loaded every 120 minutes, what share of orders is falsely flagged as orphaned?

Run it

  1. 1Install uv once. It fetches Python and the lab's packages for you.

    Terminal
    curl -LsSf https://astral.sh/uv/install.sh | sh
  2. 2Get the script. It is the whole lab: read it, then download it.

    the-false-alarm-floor-of-a.py51 linesDownload
    View the code
    the-false-alarm-floor-of-a.py
    # /// script
    # requires-python = ">=3.10"
    # ///
    # Copyright (c) 2026 Aayush Sharma · SPDX-License-Identifier: MIT
    # https://thedataengineering.com/lab-code/LICENSE.txt
    """The false-alarm floor of a referential-integrity check.
    
    Customers load every L minutes, orders every 10 minutes; 2% of orders come
    from customers who signed up less than 60 minutes earlier. At each order
    batch, count orders whose customer is not loaded yet ("orphans"), for L from
    5 to 120 minutes. Then allow lateness: check only orders older than L + 10.
    """
    import argparse, json, random
    
    p = argparse.ArgumentParser(description=__doc__.splitlines()[0])
    p.add_argument("--days", type=int, default=7, help="Simulated days.")
    p.add_argument("--orders-per-min", type=float, default=50, help="Orders per minute.")
    p.add_argument("--new-share", type=float, default=0.02, help="Share of orders from customers who signed up in the last hour.")
    p.add_argument("--loads", type=lambda s: [int(v) for v in s.split(",")], default=[5, 15, 30, 60, 120], help="Customer load intervals L, minutes.")
    p.add_argument("--seed", type=int, default=0, help="Random seed.")
    p.add_argument("--json", help="Also write the results to this JSON file.")
    args = p.parse_args()
    random.seed(args.seed)
    minutes = args.days * 1440
    
    orders = []                                                 # (order time, customer signup time)
    for m in range(minutes):
        for _ in range(int(args.orders_per_min)):
            t = m + random.random()
            signup = t - random.uniform(0, 60) if random.random() < args.new_share else t - random.uniform(60, 60 * 24 * 365)
            orders.append((t, signup))
    
    rows = []
    for L in args.loads:
        alarms = checked = alarms_late = checked_late = 0
        for t, signup in orders:
            batch_at = (int(t // 10) + 1) * 10                 # the order arrives with the next 10-minute batch
            loaded_until = (batch_at // L) * L                  # customers loaded as of the last customer load
            checked += 1; alarms += signup > loaded_until
            if batch_at - t >= 0:                               # allowed lateness: check the order once it is L + 10 old
                check_at = t + L + 10
                loaded_then = (check_at // L) * L
                checked_late += 1; alarms_late += signup > loaded_then
        rows.append({"L": L, "false_alarm_pct": alarms / checked * 100, "with_lateness_pct": alarms_late / checked_late * 100})
        print(f"customers every {L:>3} min: {alarms / checked:6.3%} of orders look orphaned   "
              f"with lateness L + 10: {alarms_late / checked_late:6.3%}")
    
    if args.json:
        with open(args.json, "w") as f:
            json.dump({"tables": {"loads": rows}}, f)
    
  3. 3Run it in the folder you saved it to, with the defaults first. Then change a knob from the table below and run it again.

    Terminal
    uv run the-false-alarm-floor-of-a.py
    uv run the-false-alarm-floor-of-a.py --help     # every knob
Knobs
Knob · defaultWhat it changes
--days7 Simulated days.
--orders-per-min50 Orders per minute.
--new-share0.02 Share of orders from customers who signed up in the last hour.
--loads5, 15, 30, 60, 120 Customer load intervals L, minutes.
--seed0 Random seed.

Our run

Orders that look orphaned, by customer load intervalApple M2 · 8 cores · 8 GB
Checked on arrivalChecked after L + 10 min
Data table
Orders that look orphaned, by customer load interval
Customer load interval L (minutes)Checked on arrivalChecked after L + 10 min
50%0%
150.067%0%
300.214%0%
600.681%0%
1201.32%0%
macOS 26.6.2 · Python 3.13.3 · run 2026-10-20
Output · uv run the-false-alarm-floor-of-a.py
customers every   5 min: 0.000% of orders look orphaned   with lateness L + 10: 0.000%
customers every  15 min: 0.067% of orders look orphaned   with lateness L + 10: 0.000%
customers every  30 min: 0.214% of orders look orphaned   with lateness L + 10: 0.000%
customers every  60 min: 0.681% of orders look orphaned   with lateness L + 10: 0.000%
customers every 120 min: 1.315% of orders look orphaned   with lateness L + 10: 0.000%

What we found

The false-orphan rate rose with the customer load interval, from 0% at 5 minutes to 0.681% at 60 and 1.32% at 120, as expected: every order from a new customer waits for the next customer load. With allowed lateness of L + 10 minutes, the rate was 0% at every interval.


Read it

Every threshold is a classifier and inherits two error types, but this floor is not a threshold problem: it is a timing problem, and its cause is in the load schedule. Check a reference only after the latest time it can legitimately arrive, and the alarms that remain are real.