Skip to content

On-Demand Report Generation

On-demand process — instantiates Demand-Triggered Deferred Evaluation

Builds a report only when a user actually requests it, and re-checks — at generation time — who is asking and whether they still want to wait.

On-demand report generation produces a report only when a user actually requests it, running the query-compute-render pipeline at request time instead of manufacturing and storing every possible report on a schedule. What distinguishes it from the code-level members of this archetype is that the trigger is a human pull arriving unpredictably, often long after the request was authored or queued. The report is defined up front but realized just-in-time, which means the generation step must re-establish, at the moment of the pull, the things that may have changed since it was requested: who is asking, whether they may still see this data, and whether they are still waiting for it.

Example

A finance app offers a "Board Pack" export. Pre-generating one nightly for every eligible user would render hundreds of packs, almost all unopened and stale by morning, some now visible to people who left overnight. Instead the pack renders when a user clicks Export: the job re-checks that this user still holds the finance-viewer role now — not when they last logged in — pulls current numbers, and streams a PDF. If the user closes the tab mid-render, the server detects the dropped connection and abandons the job rather than burning minutes rendering 60 pages no one will read.

Contrast a queued, emailed report: a pack requested Friday and generated Monday must be authorized against Monday's permissions, or a since-revoked user receives numbers they should no longer see. Deferral moved the work later; it must also move the checks later.

How it works

  • Trigger on the request. The user's action is the demand signal; nothing renders until it arrives.
  • Run the pipeline fresh. Query → compute → render executes at request time against current data.
  • Re-authorize at generation, not at request. Entitlement is checked when the data is actually assembled, closing the gap that deferral opens.
  • Abandon on cancel. If the requester disconnects or cancels, stop generating and release the work.

Tuning parameters

  • Freshness vs. cache — regenerate every time vs. serve a recent cached copy within a staleness window. Caching cuts cost but reopens the staleness and authorization gaps deferral was meant to close.
  • Sync vs. async delivery — render inline while the user waits vs. queue and notify. Async survives long reports but widens the request-to-generation gap that re-authorization must cover.
  • Cancellation sensitivity — how quickly to abandon a job whose requester has gone. Aggressive frees resources but may kill a report the user still wants.
  • Rate limiting — how many concurrent generations a user or tenant may trigger. Protects shared capacity; too tight and legitimate exports queue.

When it helps, and when it misleads

Its strength is large catalogs of possible reports of which any given one is rarely wanted, and reports whose correctness depends on being current and on the viewer's live permissions. Generating on the pull avoids manufacturing a warehouse of stale, mostly-unread artifacts.

It misleads in two ways. A heavy report generated synchronously on a click produces a latency cliff — the user stares at a spinner — and an unbounded on-demand endpoint is a denial-of-service amplifier, where a handful of expensive requests exhaust the worker pool. The classic misuse is deferring generation for efficiency but leaving the authorization check back at request time, so a queued report is rendered and delivered under stale permissions.[1] The discipline is to bound and rate-limit generation and to bind the entitlement check to the moment of data assembly, not the moment of request.

How it implements the components

On-Demand Report Generation fills the human-pull realization side of the archetype — triggering, running, re-checking, and abandoning — not caching or low-level suspension:

  • demand_signal — the user's request is the demand that triggers the pipeline.
  • realization_path — the query-compute-render pipeline, run only when requested.
  • authorization_revalidation_rule — re-verify the requester's entitlement at generation time, closing the gap deferral opens between request and access.
  • cancellation_and_abandonment_rule — abandon generation when the requester cancels or disconnects.

It does not store and reuse generated artifacts keyed to inputs — that is Memoization — nor hold the report's query as a composable deferred object, which is the Deferred Database Query Object.

References

[1] Time-of-check to time-of-use (TOCTOU) — a class of bug where a condition is validated at one time but relied upon later, during which it may have changed. Deferring generation opens exactly such a gap between the request-time check and the generation-time data access, which is why the authorization check must move to generation.