Skip to content

Bug: Reduce perceived latency in the CIEL Lab Concept Editor core flow #2774

Description

@filiperochalopes

User story

As a CIEL curator, I want the Concept Editor's view → QA in edit → save loop to feel responsive, so I can iterate on concepts without repeatedly waiting on blocking spinners.

Use case

Concept editing is a core, high-iteration CIEL Lab workflow. A curator repeatedly opens a concept, reviews and edits it while QA runs, and saves the result. Local measurements are mostly sub-second, but the same QA workload in production is materially slower and users report the accumulated wait across the flow.

This issue is a performance and user-experience investigation, not only benchmark documentation. The goal is to reduce both actual and perceived latency. Improvements such as progressive rendering, background work, optimistic acknowledgement, and scoped pending indicators are in scope even when they do not reduce the total API or OCL durability time.

Requirements

  • Investigate production slowness across the complete view → QA in edit → save flow.
  • Define and measure separate user-visible milestones: editor usable, local QA/save gate complete, deferred QA available, save acknowledged, and save durable in OCL.
  • Keep only local QA rules on the blocking save path; deferred QA must not block typing or saving.
  • Prefer progressive content and localized pending states over a page-level spinning loader when non-essential data is still loading.
  • Acknowledge saves promptly, process remote durability in the background where safe, and clearly surface pending, success, and failure states.
  • Evaluate replacing REST fan-out/hydration with OCL GraphQL and minimal selection sets where this reduces request count, payload, or database hydration.
  • Record before/after p50 and p95, including a stage breakdown, using the committed benchmark harnesses. Production measurements must be read-only or otherwise explicitly production-safe.

Acceptance criteria

  • Opening a concept presents a usable editor without waiting for non-essential hydration; still-loading sections have scoped, understandable states.
  • Local QA remains the only QA tier that gates Save; deferred QA does not block editing or saving and exposes pending/results states.
  • Save acknowledgement unblocks the editor promptly while durable OCL completion and failures remain accurately communicated.
  • A production-safe before/after report includes p50/p95 for every measured stage and explicitly distinguishes measured values from estimates.
  • The OCL GraphQL option is evaluated against the current REST path, including request count, payload, latency, permissions, and required hydration; the selected approach and trade-offs are documented.
  • Regression guards assert the shape of the optimized work where possible (for example, preventing unnecessary remote calls or blocking hydration), rather than relying only on flaky duration thresholds.

More details

Current latency picture

The p50 is used below as the typical/median latency. It is not an arithmetic mean. The representative production multiplier is approximately 11×, calculated from the median local effective deferred-QA p50 (~9.0 ms) and the median production effective deferred-QA p50 (~98.6 ms).

Phase / user-visible milestone Local p50 Production p50 Evidence
View: editor detail load / usable baseline 355.9 ms ~3.9 s Production estimate using ~11×
QA: local save gate 0.3–0.4 ms 1.3–2.4 ms Measured in both environments
QA: effective deferred result ~9.0 ms ~98.6 ms Representative medians measured in both environments
Save: asynchronous acknowledgement / UI unblocked 11.4 ms ~125 ms Production estimate using ~11×
Save: asynchronous durable completion in OCL 333.8 ms ~3.67 s Production estimate using ~11×
Save: synchronous blocking reference 202.1 ms ~2.22 s Production estimate using ~11×

The ~11× factor is directional, not a pure hardware coefficient: the local and production QA runs used different concept samples and enabled-rule configurations, and the factor includes the whole execution environment. View and save have not yet been directly benchmarked in production, so their production values above must be validated before being treated as targets or factual timings.

Production QA distribution

Profile 0–2 mappings p50 / p95 3–8 mappings p50 / p95 9+ mappings p50 / p95
Cold effective QA 30.45 / 106.15 ms 126.81 / 756.88 ms 142.18 / 419.78 ms
Warm effective QA 29.36 / 103.05 ms 70.39 / 147.77 ms 288.20 / 549.43 ms

The external-lookup portion reached a production p95 of 872.27 ms in the warm 9+ mappings sample. This variability is important for UX design: eliminating a global spinner and separating blocking from deferred work can improve the curator experience even before every backend tail is optimized.

GraphQL opportunity

The benchmark documented in ocl_issues#2757 loaded 20 predefined concepts after 3 warm-ups and across 10 repeats:

Retrieval path Requests p50 Payload
GraphQL, Elasticsearch-only fields 1 65 ms 4.9 KB
GraphQL, including mappings 1 158 ms 15 KB
REST, concurrency 8 20 1,472 ms 241 KB

For that workload, GraphQL with mappings was 9.3× faster and transferred about 94% less data than REST. Mapping selection still required database hydration in that measurement, so the result does not imply that every Concept Editor field is Elasticsearch-only.

oclapi2#897 adds permission-aware source/concept projections and selection-set-driven hydration: minimal payloads can be served directly from Elasticsearch, while fields that require authoritative relational data can hydrate the database. The Concept Editor should investigate using this capability to consolidate REST fan-out and request only the data needed for each progressive UI milestone.

Existing reproducible evidence

  • api/scripts/bench/bench_concept_editor_detail_load.py and docs/lab/bench-concept-editor-detail-load.md
  • api/scripts/bench/bench_concept_qa_validation.py and docs/lab/bench-concept-editor-qa-latency.md
  • api/scripts/bench/bench_concept_editor_save.py and docs/lab/bench-concept-editor-save-latency.md

The next investigation should directly measure the complete browser-visible production flow and preserve the existing benchmark standard: warm-up rounds, at least 10 repeats, cold/warm cache reporting where applicable, and p50/p95 stage decomposition.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

signal/needs-specMissing detail or ambiguous requirementsstage/triagedAI triage complete — scored and classifiedtype/bugSomething is broken

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions