Skip to content

feat(repo): schema encode slow metrics + entity state - #862

Merged
patroza merged 1 commit into
mainfrom
schema-encode-metrics-tail
Aug 12, 2026
Merged

feat(repo): schema encode slow metrics + entity state#862
patroza merged 1 commit into
mainfrom
schema-encode-metrics-tail

Conversation

@omegent-app

@omegent-app omegent-app Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Why

Prod Honeycomb (scanner APIs) shows event-loop delay max spikes of ~0.5–1.5s that line up with repository schema encode, not PDF work. The worst entity is BauhausOrder (max encode ~1.0s); MultiPickDeliveryNote / MakoOrder also have multi-hundred-ms tails. Existing metrics already label app.entity, but:

  • histogram buckets stop at 1s and are coarse in the 100–1000ms band, so p99 of the heavy entities looks “fine” (~17ms) while MAX is ~1s
  • there is no rate of slow encodes to alert on by entity

What

  • Widen app.schema.{encode,decode}.duration histogram buckets through multi-second stalls
  • Count app.schema.slow when duration ≥ 100ms, with app.entity + operation attributes
  • Annotate spans: app.schema.slow, and on encode app.entity.state from the first item’s _tag (so we can see which Bauhaus order states burn CPU)
  • Tests for slow flag + entity state annotation

Dig notes (BauhausOrder encode path)

Why a single-item save can still cost 0.5–1s:

  1. Full aggregate re-encode on every Repository.saveAndPublish — one Order document embeds nested items[] (tagged line-item phases) + packages[] (tagged package/BB phases) + ReadonlyMap packs, addresses, etc. Cosmos body ~30KB avg / ~80KB max.
  2. Schema shape is a deep TaggedUnion (OrderState × item/package unions) — encode walks the full tree even for tiny field changes.
  3. Encode is sync on the Node event loop (no worker); app.schema.encode.duration_ms on the save span has no child spans for the CPU portion.
  4. User fields use encodeKeys → id only; resolver is decode-path, not the encode stall.

After this lands + scanner bumps: alert on RATE(app.schema.slow) grouped by app.entity, and filter spans with app.schema.slow=true / app.entity.state.

How

timeSchema in packages/effect-app/src/Model/Repository/internal/internal.ts — histogram bounds, slow counter, span attrs; encode call sites pass state tag.

Remarks

  • Alert suggestion once published: Honeycomb metrics SUM/RATE app.schema.slow where app.entity in (BauhausOrder, MakoOrder, MultiPickDeliveryNote) — not overall encode p99.
  • Follow-up (scanner, not this PR): profile BauhausOrder encode by state; consider leaner persistence projections for hot writes if state tags show packed/closed docs dominate the tail.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Widen encode/decode duration histogram buckets into multi-second stalls,
count app.schema.slow (≥100ms) with entity labels, and annotate spans with
app.schema.slow plus app.entity.state on encode. Supports Honeycomb p99/rate
alerts on heavy aggregates (e.g. BauhausOrder) that block the event loop.

Co-authored-by: Patrick Roza <42661+patroza@users.noreply.github.com>
@pkg-pr-new

pkg-pr-new Bot commented Aug 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@effect-app/cli

npm i https://pkg.pr.new/effect-app/libs/@effect-app/cli@862

effect-app

npm i https://pkg.pr.new/effect-app/libs/effect-app@862

@effect-app/eslint-codegen-model

npm i https://pkg.pr.new/effect-app/libs/@effect-app/eslint-codegen-model@862

@effect-app/eslint-shared-config

npm i https://pkg.pr.new/effect-app/libs/@effect-app/eslint-shared-config@862

@effect-app/infra

npm i https://pkg.pr.new/effect-app/libs/@effect-app/infra@862

@effect-app/vue

npm i https://pkg.pr.new/effect-app/libs/@effect-app/vue@862

@effect-app/vue-components

npm i https://pkg.pr.new/effect-app/libs/@effect-app/vue-components@862

commit: 66cdf37

@patroza
patroza merged commit 9ea024d into main Aug 12, 2026
6 checks passed
@patroza
patroza deleted the schema-encode-metrics-tail branch August 12, 2026 17:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant