mikeboone Claude Fable 5 commited on
Commit
2d09335
Β·
1 Parent(s): a22a600

docs: build-time deep dive notes (root cause, verified results, next bottleneck)

Browse files

Captures the 2026-08-10 research: scoped-connection root cause + evidence,
what shipped and where (hf-test + MCP Space df44611, rollback 3d735c7),
verified timings (e2e 655s, MCP 9.2min), API research findings, and the
model-semantics phase (~5 min of sequential LLM batches) as the documented
next bottleneck with optimization options β€” deferred, no code changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

docs/build_time_deep_dive_2026_08_10.md ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Build-time deep dive β€” 2026-08-10
2
+
3
+ Research notes from the investigation into "why does the model take so long to
4
+ create." Companion to `docs/sre_slow_tml_import.md` (now RESOLVED) and
5
+ `docs/async_tml_import_handoff.md` (superseded as a fix, kept as the 504
6
+ safety net). Probe script: `tests/ts_table_create_deepdive.py`.
7
+
8
+ ---
9
+
10
+ ## 1. Root cause of the ~250s table imports
11
+
12
+ ThoughtSpot's logical-table TML import **scans all external-warehouse metadata
13
+ visible to the connection**. This is documented behavior for the v2 connection
14
+ APIs: when the database scope is omitted, *"all databases in the data warehouse
15
+ are accessible for metadata operations."* Our connection TML had no `database`
16
+ property, and the Snowflake role (`SE_ROLE`) can see **~507 databases** β€” so
17
+ every table create/join import paid a full metadata scan.
18
+
19
+ Measured 2026-08-10, same instance, same trivial 2-column table:
20
+
21
+ | Connection | Table import time |
22
+ |---|---:|
23
+ | Unscoped (app behavior before the fix) | **246–251s** |
24
+ | Scoped to `DEMOBUILD` (1,003 schemas / 6,084 tables of accumulated demo debris) | **33s** |
25
+ | Scoped to a fresh, tiny database | **0.7s** |
26
+
27
+ Key evidence that killed the earlier theories:
28
+
29
+ - **Prod (secloud) measured identical ~250s unscoped** β€” never sebe-specific,
30
+ never "instance load."
31
+ - Duplicate-name create errors return in 0.17s; model TML imports are
32
+ near-instant β€” parsing/validation/auth were never the cost.
33
+ - Flat ~250s per call regardless of payload (1 trivial table vs 4-table batch)
34
+ β€” a scan proportional to *visible metadata*, not to the payload.
35
+ - July's conclusion ("server-side, not reducible, raise with SRE") was wrong;
36
+ the async-import work from July remains useful only as the 504 safety net.
37
+
38
+ ## 2. The fix that shipped (commit `21ee86d` + follow-ups)
39
+
40
+ 1. **Scoped connections** β€” every demo connection now carries a
41
+ `database` property in its TML (`create_connection_tml` /
42
+ `create_connection_with_reconcile` require it; fail loudly without).
43
+ 2. **Monthly-rotating demo database** β€” demos write to
44
+ `<SNOWFLAKE_DATABASE>_<YYYY_MM>` (e.g. `DEMOBUILD_2026_08`). Single source:
45
+ `get_demo_database()` in `snowflake_auth.py`, consumed by the session
46
+ params, `cdw_connector`, env injection, and the deploy path.
47
+ `ensure_demo_database()` creates it on connect. The admin setting
48
+ `SNOWFLAKE_DATABASE` stays the base name.
49
+ 3. **Test harnesses** (`e2e_quality.py`, `settings_test.py`) resolve the
50
+ database from the model TML / `get_demo_database()` β€” no hardcoded
51
+ `DEMOBUILD` anywhere.
52
+
53
+ Operational notes:
54
+
55
+ - `get_demo_database()` is **memoized per process** β€” a long-running Space
56
+ crosses a month boundary only on restart/redeploy. Harmless (old DB keeps
57
+ working), just means rotation isn't mid-process.
58
+ - **Old-demo redeploys**: data written before 2026-08-10 lives in old
59
+ `DEMOBUILD`; re-running ThoughtSpot deployment for such a schema will fail
60
+ "schema not found" (deploy looks in the rotated DB). Already-deployed old
61
+ demos are untouched. If old-schema redeploys become a need, thread the
62
+ original database through instead.
63
+ - Old monthly DBs can be dropped as their demos expire β€” that, not cleanup
64
+ jobs, is the bloat story now.
65
+
66
+ ## 3. Verified results (same day)
67
+
68
+ | Path | Before | After |
69
+ |---|---|---|
70
+ | App e2e, per test (Aug 7–10 pre-fix record) | 1,084–2,711s, 12/24 timeouts | **655s, Grade B, 0 timeouts** (TreeHouse) |
71
+ | MCP solo build (6 rehearsals on old deploy) | 16–20 min | **9.2 min, PASS, zero errors** (Tixr, owner=jack) |
72
+
73
+ Both paths verified writing to `DEMOBUILD_2026_08` with scoped connections.
74
+ MCP Space `thoughtspot-demoprep/mcp` deployed at `df44611`; rollback point is
75
+ `3d735c7` (`git push hf-mcp 3d735c7:main --force`).
76
+
77
+ ## 4. Related API research (documented, for future reference)
78
+
79
+ - The v2 connection APIs also accept a **`databases` list** in
80
+ `data_warehouse_config` (persisted scope across multiple DBs) β€” an
81
+ alternative to the single `database` property if we ever need >1 DB visible.
82
+ - The UI's "edit connection β†’ select tables" path is
83
+ `POST /api/rest/2.0/connections/{id}/update` with an `externalDatabases`
84
+ hierarchy β€” a table-registration path that skips TML entirely. Not needed
85
+ now (scoped TML import is <1s) but a known fallback.
86
+ - **No join/relationship API exists in REST v2.0** β€” TML is the only public
87
+ way to define joins; our two-phase create+joins stays.
88
+ - `skip_diff_check: true` (10.6.0.cl+) is an undocumented-beyond-one-line
89
+ import knob; untested, might shave validation time. Not needed at current
90
+ speeds.
91
+ - Search indexing on table add is a background process (docs) and was ruled
92
+ out as the latency source.
93
+
94
+ ## 5. The NEXT bottleneck: model semantics (~5 min, LLM-bound)
95
+
96
+ Current solo MCP build profile (Tixr, 9.2 min total):
97
+
98
+ | Phase | Time | Bound by |
99
+ |---|---:|---|
100
+ | Dataset + DDL authoring | ~2.5 min | LLM |
101
+ | Snowflake load + TS tables + joins | **~30s** | (was ~8–10 min) |
102
+ | **Model create + semantic enrichment** | **~5 min** | **LLM, sequential** |
103
+ | Liveboard create + enhance | ~2 min | MCP + LLM titles |
104
+
105
+ The model phase is NOT ThoughtSpot: model TML import is near-instant. The time
106
+ is `model_semantic_updater.py` β€” per-column description + 3–5 synonyms +
107
+ Spotter `ai_context` for every model column, generated in **sequential batches
108
+ of 25 columns per LLM call** (a 60–110 column model = 3–5 back-to-back calls),
109
+ plus one model-description call.
110
+
111
+ Optimization options (deliberately NOT implemented β€” decision 2026-08-10 was
112
+ to hold code changes):
113
+
114
+ 1. **Parallelize the batches** β€” the batch calls are independent; running them
115
+ concurrently collapses ~4–5 min to roughly the latency of one call (~1 min).
116
+ Contained change in `model_semantic_updater.generate_column_semantics`.
117
+ Biggest win, lowest risk.
118
+ 2. **Overlap phases** β€” column set is known from the blueprint before Snowflake
119
+ loads; semantics could generate during the data-load wait and be applied
120
+ after model creation. Bigger restructuring, saves the same wall-clock.
121
+ 3. **Cheaper model** β€” descriptions/synonyms are formulaic; a Haiku-class model
122
+ would cut latency and cost. Quality check needed on `ai_context` hints.
123
+
124
+ With option 1 alone, a solo build lands ~5–6 min end to end.
sprint_2026_04.md CHANGED
@@ -257,6 +257,8 @@ should tell. KPI targets, growth trends, and anomaly patterns live in the matrix
257
  ### Sprint 4 (this sprint)
258
 
259
  - [x] **Table-create latency root cause + fix (Aug 10)** β€” ~250s/import was the unscoped TS connection scanning all ~507 Snowflake DBs visible to SE_ROLE (measured identical on sebe AND secloud; NOT instance load, July SRE docs corrected). Fix: (1) connection TML now scoped via required `database` property (`create_connection_tml`), (2) demos write to monthly-rotating DB `<SNOWFLAKE_DATABASE>_<YYYY_MM>` (`get_demo_database()`/`ensure_demo_database()` in `snowflake_auth.py`) since bloated DEMOBUILD (1,003 schemas) still cost 33s vs 0.7s fresh. Probe: `tests/ts_table_create_deepdive.py` βœ…
 
 
260
 
261
  - [x] **Branching / Release Strategy** β€” `main`/`develop`/hotfix workflow documented in CLAUDE.md; `develop` branch confirmed; `v1.0.0` tagged on `main`; `hf-test` remote wired βœ…
262
  - [x] **Settings Redesign β€” accordion** β€” Right panel: TS Environment + AI Model always visible; collapsible `βš™οΈ Settings` accordion with Liveboard Name, Data Size, Geo Scope, Tag Name, Column Naming Style, Object Naming Prefix, Share With βœ…
@@ -289,4 +291,4 @@ should tell. KPI targets, growth trends, and anomaly patterns live in the matrix
289
 
290
  ---
291
 
292
- *Last updated: July 23, 2026 β€” share fix (`$message` required-variable 400 on model + liveboard auto-share)*
 
257
  ### Sprint 4 (this sprint)
258
 
259
  - [x] **Table-create latency root cause + fix (Aug 10)** β€” ~250s/import was the unscoped TS connection scanning all ~507 Snowflake DBs visible to SE_ROLE (measured identical on sebe AND secloud; NOT instance load, July SRE docs corrected). Fix: (1) connection TML now scoped via required `database` property (`create_connection_tml`), (2) demos write to monthly-rotating DB `<SNOWFLAKE_DATABASE>_<YYYY_MM>` (`get_demo_database()`/`ensure_demo_database()` in `snowflake_auth.py`) since bloated DEMOBUILD (1,003 schemas) still cost 33s vs 0.7s fresh. Probe: `tests/ts_table_create_deepdive.py` βœ…
260
+ - [x] **Perf fix verified + deployed (Aug 10)** β€” app e2e: 655s Grade B, 0 timeouts (pre-fix record: 1,084–2,711s, 12/24 timeouts). Deployed to `hf-test` AND MCP Space `thoughtspot-demoprep/mcp` (`df44611`, rollback `3d735c7`); MCP Tixr rehearsal on new code: PASS, 9.2 min vs 16–20 min. Full research notes: `docs/build_time_deep_dive_2026_08_10.md` βœ…
261
+ - [ ] **Next bottleneck: model semantics ~5 min** β€” `model_semantic_updater.generate_column_semantics()` runs sequential LLM batches (25 cols/call); parallelizing collapses it to ~1 min β†’ ~5–6 min total builds. Deliberately deferred (no code changes during demo window); see deep-dive doc Β§5
262
 
263
  - [x] **Branching / Release Strategy** β€” `main`/`develop`/hotfix workflow documented in CLAUDE.md; `develop` branch confirmed; `v1.0.0` tagged on `main`; `hf-test` remote wired βœ…
264
  - [x] **Settings Redesign β€” accordion** β€” Right panel: TS Environment + AI Model always visible; collapsible `βš™οΈ Settings` accordion with Liveboard Name, Data Size, Geo Scope, Tag Name, Column Naming Style, Object Naming Prefix, Share With βœ…
 
291
 
292
  ---
293
 
294
+ *Last updated: August 10, 2026 β€” table-create perf fix verified + deployed (test + MCP); build-time deep dive documented*