{"id":50419789,"url":"https://github.com/tirion-tools/calliper","last_synced_at":"2026-05-31T08:00:39.928Z","repository":{"id":359324210,"uuid":"1245124392","full_name":"tirion-tools/calliper","owner":"tirion-tools","description":"A fast, cross-platform SQL Server query plan analyzer in the spirit of SQL Sentry Plan Explorer, but native, lighter, and built on a fully open data format.","archived":false,"fork":false,"pushed_at":"2026-05-29T01:41:08.000Z","size":10,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-29T03:21:56.947Z","etag":null,"topics":["sql-plan-analyzer","sql-plan-management","sql-query-analysis","sql-server"],"latest_commit_sha":null,"homepage":"https://tirion.tools","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tirion-tools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-20T23:55:59.000Z","updated_at":"2026-05-29T01:41:12.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tirion-tools/calliper","commit_stats":null,"previous_names":["tirion-tools/assay","tirion-tools/calliper"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tirion-tools/calliper","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tirion-tools%2Fcalliper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tirion-tools%2Fcalliper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tirion-tools%2Fcalliper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tirion-tools%2Fcalliper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tirion-tools","download_url":"https://codeload.github.com/tirion-tools/calliper/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tirion-tools%2Fcalliper/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33723549,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-31T02:00:06.040Z","response_time":95,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["sql-plan-analyzer","sql-plan-management","sql-query-analysis","sql-server"],"created_at":"2026-05-31T08:00:29.187Z","updated_at":"2026-05-31T08:00:39.907Z","avatar_url":"https://github.com/tirion-tools.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Calliper\n\n\u003e A fast, cross-platform SQL Server query plan analyzer in the spirit of SQL Sentry Plan Explorer, but native, lighter, and built on a fully open data format.\n\nBy **Tirion** · [tirion.tools](https://tirion.tools)\n\nCalliper reads `.sqlplan`, `.queryplan`, `.pesession` (SentryOne / SolarWinds) and its own `.osession` container, then renders the plan tree, statement breakdown, wait stats, captured rowsets, and runtime profile in a single desktop app. It can also drive ambient XEvent captures and replay them side-by-side with prior runs to spot regressions.\n\nThe desktop binary is closed-source; the on-disk format and every parser it depends on are open and unencumbered. See [Open-source libraries](#open-source-libraries) below.\n\n---\n\n## Status\n\n1.0. Format is stable. Subsequent releases will carry forward-compat readers for any breaking schema changes.\n\nTested platforms:\n\n- Windows 10/11. Primary target; Inno Setup `.exe` installer.\n- Linux (X11; Wayland under XWayland). GLFW 3.3+; `.deb` for Debian / Ubuntu.\n- macOS. Native build planned.\n\n---\n\n## Features\n\n### File formats\n\n- **`.sqlplan` / `.queryplan`.** Raw ShowPlanXML, read direct.\n- **`.pesession`.** SentryOne / SolarWinds Plan Explorer session container. Parsed clean-room from public Microsoft NRBF / ShowPlanXML specs; no decompilation of vendor binaries. Inner streams supported:\n  - `\u003cn\u003e.queryanalysis` (NRBF: plans, TraceRowEx, QueryStats, waits)\n  - `\u003cn\u003e.runtime` (per-statement aggregates)\n  - ConnectionParameters / batch text / Index Analyzer JSON\n- **`.osession`.** Calliper's native SQLite container. Same data shape as a pesession but indexed, compressed (deflate), and trivially diff-able. See [`libosession`](#libosession).\n\n### Plan diagram\n\n- Operator tree rendered with SQL Sentry-style stacked layout (cost %, rows, icon, op name, sub-type, object, index).\n- Operator icons sourced from Microsoft's `vscode-mssql` repo (MIT-licensed), visually consistent with SSMS.\n- Heat coloring by Total / CPU / IO / Rows.\n- Pan (right-/middle-drag), zoom (wheel), fit-to-view, click-to-select.\n- Hover tooltips: Seek Predicates (bulleted, one per column), Predicate, Warnings, Output List, Information.\n- Long IN-list compression in Seek Predicates (`RangePartitionNew([…], (0), …[64 values]…, (2000000000))`).\n\n### Statements grid\n\n- One row per `sp_statement_completed` / `TraceRowEx` event, ordered in **call-tree pre-order** (parent EXEC dispatcher above its L+1 descendants, matching Plan Explorer's display order).\n- Auto-deduped against `plan_id` for live captures (a sproc fired in a loop produces one row + N per-execution trace events, not N rows of the same plan).\n- Hideable columns: Statement, Object, Est Cost %, Compile, Duration, UDF Duration, CPU, UDF CPU, Est CPU %, Reads, Writes, Est IO %, Est Rows, Actual Rows, Key Lookups, RID Lookups, Flags, Start, End. Sort by any column.\n- Tree-mode collapse/expand on parent rows.\n- **Scope to this subtree** (Ctrl+E or right-click): drills into one EXEC and renormalises Cost % so the scoped sproc reads 100%.\n- Breadcrumb above the grid: `All › sproc1 › sproc2 (scoped, costs renormalised)`. Click any segment to pop back.\n- Keyboard navigation: ↑/↓, PgUp/PgDn, Home/End.\n- Mouse side-buttons (X1/X2) navigate the scope stack like a browser back/forward. Also responds to `ImGuiKey_AppBack` / `AppForward` for drivers that route those as keystrokes.\n- Hover tooltip per row: full call chain `at: schema.name, Line: N, Nest Level: M, Start Offset: X, End Offset: Y`.\n\n### Version compare\n\n- Load any two captures into the same tab.\n- Per-statement diff classification: Unchanged, CostShift (≥20% delta), ShapeChange (RelOp tree differs), Both, OnlyInA, **ResultDiff**.\n- ResultDiff (saturated red) escalates the other states when the captured **output rows** differ. Semantic divergence is a stronger signal than the plan that produced it.\n- Result-row equality uses an FNV-1a 64-bit hash computed at load time, so the diff stays sub-millisecond on thousand-row rowsets.\n- Per-(item × compare) diff cache invalidates on item reload or compare swap, so the diff doesn't recompute every frame.\n\n### Live capture\n\n- Server-side XEvent session (auto-named, ring-buffer target): `sp_statement_completed`, `sql_batch_completed`, `rpc_completed`, `query_post_execution_showplan`, `wait_info`.\n- Streams directly into a `.osession` tab. The Statements grid auto-refreshes at 750 ms; the status row carries the live counters (`● LIVE   snapshots: N   events: M   waits: W`).\n- Toolbar Stop button doubles as the live-capture stop. After stop: Ctrl+S to save, or Discard from the same toolbar row.\n- Captured statements deduped by plan_id; per-execution metrics aggregate into one statement row via `trace_events`.\n\n### Script-tab capture\n\n- Editable Command Text tab, bound to a SQL Server connection.\n- **Get Estimated Plan** (SHOWPLAN_XML). Server-side restriction worked around by sending the SET as its own batch.\n- **Get Actual Plan** (STATISTICS XML). Every run creates a new History version. Rowset capture is opt-in.\n- Optional add-ons (server-version gated):\n  - **Wait Stats**: diffs `sys.dm_exec_session_wait_stats` around the run (SQL Server 2016+).\n  - **Live Query Statistics**: sibling connection polls `sys.dm_exec_query_profiles` every 250 ms during execution (SQL Server 2014+).\n- F5 binds to Get Actual Plan.\n\n### Wait stats panel\n\n- Batch-level diff from `sys.dm_exec_session_wait_stats`.\n- Sorted by total duration; signal-wait percent column.\n\n### Live Query Statistics panel\n\n- Operator-level row/percent-complete heatmap from `sys.dm_exec_query_profiles`.\n- Updates in-place from the sibling poller's last snapshot.\n\n### Captured result rows\n\n- \"Include query results\" option on Get Actual Plan or live capture stores every emitted row-set alongside the plan.\n- Result rows are diff-able across versions (see ResultDiff above).\n- Displayed in the Results tab per statement.\n\n### Plan XML \u0026 Index Analyzer\n\n- Plan XML tab shows the original ShowPlanXML for the selected statement, no normalisation applied.\n- Index Analyzer reads the gzipped JSON pesession carries and renders missing-index recommendations alongside SQL Server's own `\u003cMissingIndexes\u003e` block.\n\n### Other\n\n- **HiDPI auto-scale** via `glfwGetMonitorContentScale`.\n- **Font size control** (Ctrl+= / Ctrl+- / Ctrl+0; View → Font size).\n- **Dark / Light themes**.\n- **Connection manager** with recent-connection history. Opt-in \"Remember password\" stores credentials in the OS-native keychain (Windows Credential Manager, Linux libsecret / GNOME Keyring).\n- **Plan-shape dedup** in `.osession`. Re-emissions of the same plan share a single row in the `plans` table keyed by FNV-1a of the normalised XML (RuntimeInformation / QueryTimeStats / WaitStats / MemoryGrantInfo stripped before hashing). Original XML kept verbatim in `plan_snapshots` for lossless round-trip.\n\n---\n\n## Quick start\n\n```bash\n# Open a saved plan\ncalliper path/to/plan.sqlplan\n\n# Open a SentryOne capture\ncalliper path/to/capture.pesession\n\n# Open a Calliper osession\ncalliper path/to/run.osession\n\n# CLI conversion: .pesession → .osession (lossless verified)\npesession2osession in.pesession out.osession\nverify_lossless    in.pesession out.osession\n```\n\nLive capture and script execution are GUI-only. Start `calliper` with no argument, then click **Live Capture…** or **+ New Script**.\n\n---\n\n## Open-source libraries\n\nThe format and every parser Calliper uses are open source under permissive licenses (MIT), maintained by Tirion at [github.com/tirion-tools](https://github.com/tirion-tools). Linking from a separate project is explicitly supported.\n\n| Library | Purpose | License |\n|---|---|---|\n| [`libshowplan`](https://github.com/tirion-tools/libshowplan) | SQL Server ShowPlanXML parser. RelOp tree, runtime stats, missing indexes, warnings, parameters, statistics. pugixml-based. | MIT |\n| [`libnrbf`](https://github.com/tirion-tools/libnrbf) | .NET Binary Remoting Format (NRBF / MS-NRBP) reader. Visitor API, forward-ref string dictionary, handles the lpstr varint length convention. | MIT |\n| [`libpesession`](https://github.com/tirion-tools/libpesession) | SentryOne / SolarWinds `.pesession` reader. Walks the NRBF tree, decodes queryanalysis / runtime / TraceRowEx streams, and converts to osession. | MIT |\n| [`libxesession`](https://github.com/tirion-tools/libxesession) | SQL Server Extended Events session reader (`.xel` / ring-buffer XML). Used by live capture to ingest server-side events. | MIT |\n| [`libosession`](https://github.com/tirion-tools/libosession) | SQLite container format: plans, plan_snapshots, statements, runtime, trace_streams, waits, objects, statement_results, items. Includes deflate-compressed trace-event batches and the schema docs. | MIT |\n| [`libliveconnect`](https://github.com/tirion-tools/libliveconnect) | ODBC connector wrapping nanodbc for the live-capture + script-execution paths. Archived: folded into the Calliper app once it shrank to a thin nanodbc wrapper. | MIT (archived) |\n\nLibrary READMEs cover the on-disk layout in detail. The osession schema is stable enough that any consumer (Python, Go, .NET) can read a Calliper capture by just opening it as SQLite.\n\nThe Calliper desktop binary is closed source. Source-license inquiries: \u003ccontact@tirion.tools\u003e.\n\n---\n\n## Roadmap\n\nTracked in [Issues](https://github.com/tirion-tools/calliper/issues). Notable in-flight work:\n\n- **macOS native build**: app bundle, Keychain integration, signed + notarized .dmg.\n- **Curated `clang-tidy` adoption** across all repos.\n\n---\n\n## Building from source\n\nCalliper's source isn't public, but the open-source libraries (all under Tirion at [github.com/tirion-tools](https://github.com/tirion-tools)) build standalone:\n\n```bash\ngit clone https://github.com/tirion-tools/libshowplan\ncmake -B build libshowplan \u0026\u0026 cmake --build build\nctest --test-dir build\n```\n\nEach library is dependency-light. pugixml is vendored, `libosession` vendors miniz and depends only on `sqlite3` from the system.\n\n---\n\n## Reporting issues\n\nFile against the relevant repo:\n\n- Plan-parsing weirdness → [`libshowplan`](https://github.com/tirion-tools/libshowplan)\n- pesession parsing → [`libnrbf`](https://github.com/tirion-tools/libnrbf) + the Calliper repo\n- osession content / schema → [`libosession`](https://github.com/tirion-tools/libosession)\n- UI / capture / live features → [`calliper`](https://github.com/tirion-tools/calliper)\n\nAttach the source `.sqlplan` / `.osession` when filing. Calliper writes everything needed for a repro into the osession.\n\n---\n\n## Acknowledgments\n\n- **Microsoft.** Public ShowPlanXML schema, the `vscode-mssql` operator-icon set, and the NRBP / NRBF format docs.\n- **SolarWinds / SentryOne.** Plan Explorer set the UX bar. Calliper's pesession reader is built clean-room from public Microsoft specs; no SentryOne binary is decompiled or referenced. Plan Explorer's EULA restricts reverse engineering of its redistributables and Calliper respects that.\n- **Dear ImGui**, **GLFW**, **pugixml**, **miniz**, **SQLite**, **nlohmann/json.** The libraries that do the heavy lifting.\n\n---\n\n## License\n\nThe closed-source desktop binary ships under a commercial license. Open-source libraries are MIT (see each repo's `LICENSE`).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftirion-tools%2Fcalliper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftirion-tools%2Fcalliper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftirion-tools%2Fcalliper/lists"}