PR-3 Performance: Swap and trade quote latency is ~3 seconds; no input debounce means every keystroke fires a simulation #346

Closed
opened 2026-06-09 11:46:10 +00:00 by totdking · 11 comments
totdking commented 2026-06-09 11:46:10 +00:00 (Migrated from gitlab.com)
No description provided.
totdking commented 2026-06-09 11:50:44 +00:00 (Migrated from gitlab.com)

Summary

On both the /swap and /trade pages, typing an amount into the input field produces a ~3-second delay before a quote estimate appears. The PR-3 criterion requires sub-second latency under normal conditions. The delay compounds because there is no debounce on the amount input: each keystroke immediately changes rawInputAmount, which is part of the simulation query key, which fires a new React Query simulation before the previous one completes.


Observed behavior

  • Swap page: ~3 seconds from input to visible quote estimate
  • Trade page: ~3 seconds from input to visible quote estimate
  • Typing a 3-digit amount (e.g. "100") fires 3 sequential simulation queries ("1", "10", "100") before settling
  • The delay is consistent across multiple test runs on LocalTerra

Root cause area

Two contributing factors identified in code:

1. No debounce on amount input

In SwapPage.tsx, rawInputAmount is derived directly from inputAmount state and is included in simQueryKey (line 347). There is no debounce between input change and query dispatch. Each character the user types changes the query key and fires a fresh simulation immediately.

2. Sequential indexer + LCD calls

The simulation query function (simQuery, line 374) calls the indexer for route optimization and then calls the Terra LCD for simulate_swap_operations. On LocalTerra, both calls are slower than on a production node. The two calls are not parallelized for the common case.


Reproduction steps

  1. Navigate to /swap or /trade on LocalTerra
  2. Open DevTools Network tab
  3. Select a valid pair (e.g. EMBER/CORAL)
  4. Type "100" into the amount input one character at a time
  5. Observe: three separate simulation requests fire for "1", "10", "100"
  6. Observe: quote appears approximately 3 seconds after the final keystroke

Expected behavior

Quote estimate should appear within ~1 second of the user finishing input. A debounce of 300-500ms on the amount input field would prevent intermediate keystrokes from firing simulations and would reduce the effective query rate to one per user pause.


Actual behavior

Quote latency is ~3 seconds. Every keystroke fires a simulation. The user sees a loading state for the full round-trip time of each query.


Impact assessment

  • Degrades the perceived responsiveness of the trade UI
  • Wastes LCD and indexer capacity on intermediate keystrokes that are never submitted
  • Fails the CEX-grade sub-second quote latency standard set in PR-3

Environment

  • Chain: localterra
  • LCD: http://localhost:1317
  • Wallet: Keplr (Terra Classic)
  • Browser: Chromium
  • Pages tested: /swap, /trade
  • Network throttle applied: No

Severity: P2(Polish) -- UX degradation; does not affect correctness of quotes or fund safety.

Related checklist items: PR-3

cc: @PlasticDigits

### Summary On both the `/swap` and `/trade` pages, typing an amount into the input field produces a \~3-second delay before a quote estimate appears. The PR-3 criterion requires sub-second latency under normal conditions. The delay compounds because there is no debounce on the amount input: each keystroke immediately changes `rawInputAmount`, which is part of the simulation query key, which fires a new React Query simulation before the previous one completes. --- ### Observed behavior - Swap page: \~3 seconds from input to visible quote estimate - Trade page: \~3 seconds from input to visible quote estimate - Typing a 3-digit amount (e.g. "100") fires 3 sequential simulation queries ("1", "10", "100") before settling - The delay is consistent across multiple test runs on LocalTerra --- ### Root cause area Two contributing factors identified in code: **1. No debounce on amount input** In SwapPage.tsx, `rawInputAmount` is derived directly from `inputAmount` state and is included in `simQueryKey` (line 347). There is no debounce between input change and query dispatch. Each character the user types changes the query key and fires a fresh simulation immediately. **2. Sequential indexer + LCD calls** The simulation query function (`simQuery`, line 374) calls the indexer for route optimization and then calls the Terra LCD for `simulate_swap_operations`. On LocalTerra, both calls are slower than on a production node. The two calls are not parallelized for the common case. --- ### Reproduction steps 1. Navigate to `/swap` or `/trade` on LocalTerra 2. Open DevTools Network tab 3. Select a valid pair (e.g. EMBER/CORAL) 4. Type "100" into the amount input one character at a time 5. Observe: three separate simulation requests fire for "1", "10", "100" 6. Observe: quote appears approximately 3 seconds after the final keystroke --- ### Expected behavior Quote estimate should appear within \~1 second of the user finishing input. A debounce of 300-500ms on the amount input field would prevent intermediate keystrokes from firing simulations and would reduce the effective query rate to one per user pause. --- ### Actual behavior Quote latency is \~3 seconds. Every keystroke fires a simulation. The user sees a loading state for the full round-trip time of each query. --- ### Impact assessment - Degrades the perceived responsiveness of the trade UI - Wastes LCD and indexer capacity on intermediate keystrokes that are never submitted - Fails the CEX-grade sub-second quote latency standard set in PR-3 --- ### Environment - Chain: localterra - LCD: [http://localhost:1317](http://localhost:1317) - Wallet: Keplr (Terra Classic) - Browser: Chromium - Pages tested: `/swap`, `/trade` - Network throttle applied: No --- **Severity:** P2(Polish) -- UX degradation; does not affect correctness of quotes or fund safety. **Related checklist items:** PR-3 cc: @PlasticDigits
totdking commented 2026-06-09 11:51:01 +00:00 (Migrated from gitlab.com)

mentioned in issue #291

mentioned in issue #291
Brouie commented 2026-06-10 02:21:26 +00:00 (Migrated from gitlab.com)

mentioned in issue #355

mentioned in issue #355
PlasticDigits commented 2026-06-10 03:39:37 +00:00 (Migrated from gitlab.com)

mentioned in commit b6fb88bce2

mentioned in commit b6fb88bce2e7f148c673384a65e07a9baeafcbd1
PlasticDigits commented 2026-06-10 03:39:51 +00:00 (Migrated from gitlab.com)

MR opened. 350ms debounce + keepPreviousData on Swap/Trade market sim queries.

MR opened. 350ms debounce + keepPreviousData on Swap/Trade market sim queries.
PlasticDigits commented 2026-06-10 03:39:52 +00:00 (Migrated from gitlab.com)

mentioned in merge request !855

mentioned in merge request !855
PlasticDigits commented 2026-06-10 05:32:58 +00:00 (Migrated from gitlab.com)

mentioned in commit 338947b1c2

mentioned in commit 338947b1c262a6b36bb0303c766b0fc8b3af4356
PlasticDigits (Migrated from gitlab.com) closed this issue 2026-06-10 05:32:58 +00:00
PlasticDigits commented 2026-06-10 05:35:36 +00:00 (Migrated from gitlab.com)

marked as related to #356

marked as related to #356
PlasticDigits commented 2026-06-10 05:35:37 +00:00 (Migrated from gitlab.com)

mentioned in issue #356

mentioned in issue #356
PlasticDigits commented 2026-06-11 10:28:43 +00:00 (Migrated from gitlab.com)

mentioned in issue #360

mentioned in issue #360
PlasticDigits commented 2026-07-13 10:33:12 +00:00 (Migrated from gitlab.com)

mentioned in issue #485

mentioned in issue #485
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#346
No description provided.