Skip to content

Releases: fwdthinkers/sp_SQLFlightRecorder

sp_SQLFlightRecorder 1.1.3

Choose a tag to compare

@github-actions github-actions released this 28 Aug 00:15

[1.1.3] - 2026-08-27

Bug-fix release. @OutputFormat = N'Markdown' silently rendered only one
finding
, regardless of how many the report produced. No behavior or contract
change otherwise: rule IDs, output columns, and the forward-only schema are
untouched, and the D-085 Markdown header keeps its 14 keys.

If you ran a Markdown report on 1.0.0 through 1.1.2 and acted on it,
re-run it.
The findings you were shown were incomplete. The header's
Finding-Count and the Recommendation Summary were correct throughout, so a
saved report that shows Finding-Count: 32 above a single bullet is evidence
of this defect, not of a quiet server — the other 31 findings were evaluated
and then dropped at render time.

Fixed

  • Markdown output rendered exactly one finding of N (@Mode = 'Report',
    @OutputFormat = 'Markdown'; all rules). The Findings body was built by
    concatenating into a variable with an ORDER BY over computed CASE
    expressions — a construct SQL Server does not guarantee, and which in this
    shape keeps only the last row in sort order. Because Informational sorts
    last (D-068), the surviving row was almost always the FR_R0026
    coverage summary. The render path now materialises the D-068 display rank
    as a column and orders by it, so Markdown and FindingsOnly return the same
    findings in the same order by construction.
    • @MinSeverity never affected the symptom: the post-evaluation filter
      (D-070) was always correct and #fr_findings was always fully populated —
      the rows were lost at render time, not at filter time. At
      @MinSeverity = 'Critical' the Findings section would have been empty
      entirely, since the Informational row that had been surviving is itself
      filtered out.
    • Default, FindingsOnly, and TimelineOnly were never affected.
      They emit plain result sets with no variable concatenation. Anyone using
      those formats has complete output and needs to do nothing.
  • The Markdown timeline used the same unguaranteed construct. It rendered
    correctly (its ORDER BY used plain columns, which happens to survive), but
    was one refactor away from the identical silent truncation. It now uses the
    same materialised-rank approach.

Added

  • CI assertion that the Markdown header counts match the rendered bodies
    (ci-tier1): Finding-Count must equal the number of rendered finding
    bullets, and Timeline-Event-Count the number of timeline bullets. Both
    numbers derive from the same temp tables in the same code block, so any
    disagreement is a defect by definition. The step previously asserted only
    that the report's H1 was present, which is why this shipped. The check also
    refuses to run against a fixture yielding fewer than two rows, where the
    equality could not fail.

sp_SQLFlightRecorder 1.1.2

Choose a tag to compare

@github-actions github-actions released this 27 Aug 15:34

[1.1.2] - 2026-08-27

Documentation accuracy patch on 1.1.1, and a version-convention change
(D-201): from this release on, every release bumps the in-proc
ToolVersion and Build-Date-Utc — documentation-only releases included

and a version/tag gate fails any tagged build whose artifact header does not
match the tag. This release therefore ships ToolVersion = 1.1.2 (build date
2026-08-27) with no behavior change. For the record: 1.1.1 shipped with
the artifact intentionally untouched, so its About output reports
ToolVersion 1.1.0 — that was the stated convention at the time, and this
release supersedes it.

Fixed

  • Finding-field column names were wrong in the user guide
    (docs/user-guide.md §13): the documented list included FirstSeenUtc and
    LastSeenUtc, which do not exist in the 16-column Findings contract
    (D-067). The actual columns are StartTimeUtc and EndTimeUtc, and the
    full 16-column list is now documented in contract order. If you scripted
    against the old documented names, switch to StartTimeUtc/EndTimeUtc
    the result set itself never changed.
  • Heuristic removed from the documented evidence types
    (docs/user-guide.md §13): it appears nowhere in the artifact and has never
    been emitted. The closed EvidenceType set is Observed, Inferred.
    (Confidence values remain High, Medium, Low, and severity values are
    unchanged; the old docs listed Heuristic as an evidence type that did not
    exist.)

Added

  • Version/tag consistency gatescripts/check-version-tag.sh (D-201):
    fails a tagged build when the artifact's Tool-Version header does not
    match the tag. Wired into release.yml (replacing its inline check, same
    behavior, single implementation) and into the ci-tier1 static-analysis
    job, where it is a no-op on untagged builds. Locally runnable.
  • README: "How it fits with other SQL Server tools" section, and the missing
    @TimeZone parameter-table row (the parameter has existed since v1.0.0 but
    was absent from the README table).

Changed

  • README safety notes and all remaining hedged phrasing rewritten as verified
    statements of fact: exact collector row caps (most collectors cap at
    MaxRowsPerCollector; file stats at TOP (5000); perf counters at
    TOP (100) over an 8-counter allow-list; FR_Configuration stores all of
    sys.configurations; Query Store and schema activity cap per database
    across up to 50 databases; @TopN validated 1–1000 while the
    MaxRowsPerCollector config key is not range-checked), @WhatIf preview
    behavior for Purge/Uninstall, @PreserveRunLog's timestamped
    FR_RunLog_Archive_<yyyymmdd_hhmmss> rename, opt-in Agent job creation,
    the per-collector capability-gated skip list, and Report's
    repository-only evaluation (plus the fixed two-value capability probe that
    runs on every invocation).
  • README lead reordered (what the tool is before the release note), the
    Requirements heading reconciled with the SQL Server 2012 legacy row,
    @Debug documented precisely (routes Collect to CollectDebug, no
    collector rows), repository file paths linked consistently, and a stray
    horizontal rule removed.

sp_SQLFlightRecorder 1.1.0

Choose a tag to compare

@github-actions github-actions released this 26 Aug 18:33

[1.1.0] - 2026-08-26

Retention and repository-performance hardening (D-199). Root cause
addressed: when purge was not scheduled or not enforced, FR_* repository
tables grew without bound in real deployments (35M+ rows observed in
FR_SchemaActivity, 12M+ in FR_QueryStoreTopN) and Report ran for hours.
SQLFR must not silently become its own performance problem, so retention is
now operationally safe by default. ToolVersion is 1.1.0 (build date
2026-08-26); SchemaVersion advances to 0.5.0 (index-only DDL, forward-only
per D-038); RulePackVersion stays 0.4.3 (no rule logic or catalog change —
the Report changes below are access-path and evidence-cap work, not rule
behavior). Upgrades from 1.0.0 are in place: the first Install over an
existing repository builds the new indexes (one-time cost on large tables).

Added

  • Post-collect purge step in the collector job (@Mode = Install,
    @CreateAgentJob = 1): the SQLFlightRecorder Collect Agent job now has two
    steps — Collect, then Purge (@WhatIf = 0) as normal cleanup. Existing
    single-step jobs from earlier releases are upgraded in place (the step is
    added and the Collect step is pointed at it). Job, step, and schedule
    creation are idempotent: re-running Install never duplicates any of them.
  • Daily purge backstop job (@Mode = Install, @CreateAgentJob = 1): a
    second Agent job, SQLFlightRecorder Purge, runs
    EXEC dbo.sp_SQLFlightRecorder @Mode = N'Purge', @WhatIf = 0; daily at
    02:30 server time, protecting retention when the collector job is disabled,
    changed, or failing before its cleanup step. Recorded in FR_Config as
    PurgeAgentJobName / PurgeAgentJobCreatedBySQLFlightRecorder.
  • Retention/purge-support indexes (@Mode = Install; the SchemaVersion
    0.5.0 DDL): a nonclustered SnapshotId index on every FR_Snapshot child
    table, IX_FR_Snapshot_RunId, IX_FR_RunLogStep_RunId, and
    IX_FR_Request_QueryHash. Purge deletes verify child foreign keys per
    deleted FR_Snapshot row; without these indexes each check was a full
    child-table scan, which is what made purge (and run-log cleanup, and
    FR_QueryText orphan cleanup) unusable on grown repositories. Created
    idempotently on fresh installs and upgrades — the first Install over a large
    old repository pays a one-time index build.
  • Retention guardrails (@Mode = Configure): SnapshotRetentionDays now
    accepts 1–31 and RunLogRetentionDays 1–124; out-of-range values return a
    clean InvalidConfigValue error and FR_Config is not updated. New tunable
    RepositoryTableWarnRows (default 5,000,000) drives the Status size warning.
  • Status retention-health result set (@Mode = Status; additive seventh
    result set CheckName, CheckStatus, Detail per D-023): warns when the
    oldest snapshot exceeds SnapshotRetentionDays, when purge appears not to
    be keeping up (oldest data > retention + 2 days, with last-purge evidence),
    when the collector job lacks a Purge step, when the daily purge job is
    missing on Agent-capable platforms, and when an FR_* table exceeds
    RepositoryTableWarnRows. msdb job checks are capability-gated and
    permission-safe (Unknown, never an error).
  • Schema-activity evidence cap warning (@Mode = Report, RuleId
    FR_R0026_CoverageAndCapabilitySummary): when the window holds more
    distinct schema/stats events than @MaxFindings, the timeline is capped and
    one Informational Coverage finding says so and recommends narrowing the
    window or reducing retention.
  • Scheduling guidance by platformdocs/operations/scheduling.md. Which
    scheduler to use is a capability question, not a preference: cron + sqlcmd on
    Linux; a SQL Agent job step on Azure SQL Managed Instance (HasAgent = 1);
    Azure Elastic Jobs or an external scheduler on Azure SQL Database, which has
    neither Agent nor msdb. Includes copy-paste snippets and the all-platform
    defaults (leave CollectErrorLog and EnableBufferPoolCollector off unless
    needed, periodic Report, scheduled Purge, UTC, and a documented uninstall
    path).

Changed

  • Uninstall removes both Agent jobs (@Mode = Uninstall): the collector
    job and the daily purge job are dropped when this tool created them;
    @WhatIf = 1 previews both; already-missing jobs never fail the uninstall;
    @PreserveRunLog semantics are unchanged.

  • Install on platforms without SQL Agent (@Mode = Install,
    @CreateAgentJob = 1 on Azure SQL Database / Express): no job is attempted;
    the Install result now states that BOTH
    EXEC dbo.sp_SQLFlightRecorder @Mode = N'Collect'; and
    EXEC dbo.sp_SQLFlightRecorder @Mode = N'Purge', @WhatIf = 0; must be
    scheduled externally.

  • Report window-first reads (@Mode = Report; performance only, output
    contract and rule behavior unchanged): the baseline builder, restart
    detection, FR_R0005's corroborating counter read, FR_R0021–FR_R0024's
    window scans, and the v0.4 timeline events now carry child-side
    SnapshotUtc range predicates (the child value always equals its parent's),
    so every read rides the clustered index instead of joining through the
    parent alone. The schema-activity timeline is rewritten window-first with
    bounded SnapshotUtc access, deduplicated per distinct event (the collector
    re-captures each event on every snapshot in its 7-day lookback; the timeline
    previously emitted those duplicates), and capped at @MaxFindings with the
    Coverage warning above.

  • Repository footprint row counts (@Mode = Status result set 5 and
    FR_v_RepositoryFootprint): RowCount now counts heap/clustered rows only
    (index_id IN (0, 1)), so the new nonclustered indexes do not inflate it;
    UsedKb still includes index pages.

  • CriticalWaitTypes honoring is not part of this release (RuleId
    FR_R0003_TopWaitTypeSpike): D-105 originally targeted "v1.1"; 1.1.0 ships
    retention hardening only, so FR_R0003 still uses the hard-coded D-093 list
    and the honoring moves to a later 1.x minor (D-200). The config key
    remains defined and settable, exactly as in v1.0.0.

  • Upgrade harness (tests/upgrade/run-upgrade.sh) now asserts that
    SchemaVersion advances to the current artifact's value (measured from a
    fresh reference install, not a hard-coded string) and that the new
    SnapshotId indexes exist after upgrade.

  • Purge is documented as mandatory operational maintenance across README,
    the user guide, docs/configuration.md (retention ranges and the
    not-a-warehouse note), docs/operations/scheduling.md (per-platform purge
    scheduling, including Azure SQL Database external scheduling of both
    statements), docs/operations/troubleshooting.md (huge-repository /
    slow-Report recovery), and the regenerated mode pages for Install,
    Uninstall, Status, Configure, and Purge.

  • Azure SQL Managed Instance and Azure SQL Database are certified as
    supported
    (D-196), both Verified by manual Tier-2 attestation against
    v1.0.0. MI ran the full collector set with only AlwaysOnState skipped;
    Azure SQL Database returned Success with four collectors skipped by design —
    AgentJobs, BackupHistory, Deadlocks, AlwaysOnState — each reason
    carried in the FR_R0026 coverage finding. Both installed 25 core FR_*
    tables plus 5 FR_v_* views and uninstalled leaving RemainingFrObjects = 0.
    No equivalence is claimed between the two, or between either and on-prem.

  • The compatibility matrix now lists every version and platform explicitly
    no collapsed "2017+" row — including separate rows for SQL Server on Azure VM
    (IaaS)
    , which is the ordinary engine on a VM you administer and inherits its
    matching on-prem row, as distinct from the Azure PaaS products.

  • The matrix states plainly that Tier-2 "Verified" is not Tier-1 verified: it
    is one manual run at one point in time, where Tier 1 is an automated per-push
    gate that blocks the build on failure.

  • Primary supported range is now SQL Server 2014–2025 (D-195, amending
    D-108's range framing). SQL Server 2012 is demoted to legacy best-effort:
    the v1.0.0 lifecycle was manually tested on 2012 Windows and completed, but
    with a known SchemaActivity collector degradation — both Collect runs
    returned PartialSuccess (dbsDone=0; dbErrors=1; budgetHit=0). Platform
    split now stated wherever compatibility is claimed: 2017+ on Linux and
    Windows
    , 2014/2016 Windows-only, 2012 Windows-only best-effort.

  • SQL Server 2014 and 2016 (Windows) are now Tier-2 Verified on manual
    v1.0.0 attestations — full lifecycle Success, evidence and caveats recorded
    in the compatibility matrix. This is the first upgrade of a Tier-2 status on
    real evidence, which is the only path D-192 permits.

  • Note for anyone comparing docs with the tool: the released 1.0.0 artifact
    reports SupportedSqlServerRange = 'SQL Server 2012–2025'. That is not false
    — 2012 remains supported best-effort — but it is coarser than this policy, and
    the artifact is immutable.

sp_SQLFlightRecorder 1.0.0

Choose a tag to compare

@github-actions github-actions released this 29 Jul 17:53

[1.0.0] - 2026-07-29

First stable release. The v1.x contract starts here: rule IDs, output
columns, and the forward-only schema are now "1.0 is forever" promises — see
docs/compatibility/support-policy.md.

Relative to 1.0.0-rc.1 the only artifact change is version metadata:
ToolVersion 1.0.0-rc.11.0.0 and the build date. Everything else in this
entry is documentation and process. SchemaVersion stays 0.4.0 (no DDL,
forward-only, D-038) and RulePackVersion stays 0.4.3 — it names the release
that last changed rule logic or the rule catalog, not the tool release (D-085),
and no rule has changed since 0.4.3.

Compatibility, stated by tier. Tier-1 verified in automated CI: SQL
Server 2017 / 2019 / 2022 / 2025 Developer, plus 2022 Express and Standard.
Tier-2 Unverified — no attestation received, meaning untested, not "works"
and not "broken": SQL Server 2012 / 2014 / 2016 (Windows), Azure SQL Managed
Instance, Azure SQL Database. The two tiers are separate claims; see
docs/compatibility/matrix.md before relying on a
Tier-2 target.

Upgrades from 0.4.1 / 0.4.2 / 0.4.3 / 1.0.0-rc.1 are validated and
migration-free (tests/upgrade/run-upgrade.sh). v0.4.0 has no public tag and
is untested — not faked, not claimed.

Changed

  • ToolVersion is now 1.0.0 (surfaced by About, Help, Status, and the
    Markdown report header; build date 2026-07-29). No behavior change.
  • Security reporting now has a dedicated private contact. SECURITY.md
    directs vulnerability reports to
    sqlflightrecorder-security@forwardthinkersconsulting.com. GitHub private
    vulnerability reporting is not enabled on this repository, and the policy
    says so rather than pointing reporters at a Report a vulnerability button
    that is not available to them.
  • Conduct reporting has a designated v1.0.0 path. CODE_OF_CONDUCT.md
    routes reports to the repository owner through GitHub maintainer channels,
    with a fallback for reporters who have no private channel, marked explicitly
    as the v1.0.0 path rather than a placeholder. No address invented. It also
    states that a single-maintainer project cannot independently review a report
    about that maintainer, and points to GitHub's own abuse reporting as an
    independent route.
  • Owner sign-off is sufficient for the v1.0.0 wording lock (D-193),
    superseding D-158's two-reviewer rule and D-189's second-reviewer eligibility
    for that sign-off only. Two-maintainer review resumes automatically once a
    second maintainer exists or the project moves to an organization/team model.
    This narrows who signs off, not what §6.7 requires of the wording.
  • Cost-regression (D-143) and soak (D-145) are not a v1.0.0 gate
    (D-194). No green evidence exists for either and none is claimed: both
    workflows are schedule/dispatch-only by design, and scheduled workflows run
    only from the default branch, where neither file exists yet.
  • Tier-2 attestation is no longer a v1.0.0 release gate (D-192). The
    earlier §11.6 rule required at least 4 of 5 Tier-2 targets attested before
    final v1.0.0; final v1.0.0 may now ship with those targets Unverified.
    What replaces the count is a wording obligation: compatibility claims must
    keep Tier-1 verified (automated CI evidence) and Tier-2 pending /
    unverified
    (no attestation received) visibly separate, and no unattested
    target may be described as verified or tested. SQL Server 2012, 2014 and 2016
    and the Azure targets stay Unverified — untested, not "works", not "broken"
    — until a real attestation is recorded. Attestation collection continues as
    post-1.0 work under D-164 and the D-190 18-month review.
  • The Tier-2 attestation issue template now requires the capability snapshot
    and takes it as a multi-line field. The process always listed it as required
    evidence — it is what pins which target the evidence describes — but the
    template marked it optional, so an attestation could arrive unrecordable.
  • The upgrade harness now includes 1.0.0-rc.1 as a source version, so the
    RC-to-final upgrade path is covered. Fixed a latent bug it exposed: database
    names were built by stripping dots only, so a prerelease version's hyphen
    produced an illegal identifier.
  • The hotfix process (D-174) was rehearsed before this release: branch from
    the latest tag, minimal fix, validation, forward-merge. Recorded with its
    limits in docs/release-readiness-v1.0.0-rc.1.md — the rehearsal used a
    docs-only fix, so it did not exercise the regression-test leg.

sp_SQLFlightRecorder 1.0.0-rc.1

Pre-release

Choose a tag to compare

@github-actions github-actions released this 28 Jul 19:10

[1.0.0-rc.1] - 2026-07-21

First release candidate for v1.0.0. This is a documentation, CI/release-process,
and version-metadata
stabilization on top of 0.4.3. It changes no schema,
output contract, rule ID, rule logic, collector, or mode
: SchemaVersion stays
0.4.0, and RulePackVersion stays 0.4.3 because no rule logic or catalog
entry changed since 0.4.3 (the rule-pack version names the last rule change, not
the tool release — D-085). Upgrades from 0.4.1 / 0.4.2 / 0.4.3 are validated and
migration-free.

Changed

  • ToolVersion is now 1.0.0-rc.1 (surfaced by About, Help, Status, and
    the Markdown report header; build date 2026-07-21). No behavior change.

Added

  • Documentation completeness (§11.6): a page for every mode, rule, and
    config key, enforced by a CI doc-coverage gate (scripts/check-doc-coverage.sh)
    plus rule/mode/compat-matrix generators.
  • CI / release wiring: rule fixtures + demo golden in CI; a dry-runnable
    release workflow (release.yml) that builds a byte-identical artifact with a
    checksum and attaches the compatibility matrix; out-of-band cost/soak harnesses
    (non-blocking).
  • Compatibility: six Tier-1 verified targets (2017/2019/2022/2025 Developer +
    2022 Express/Standard) and a documented Tier-2 attestation process for
    2012/2014/2016 Windows + Azure MI/DB (pending attestation).
  • Upgrade-path validation harness (tests/upgrade/run-upgrade.sh).
  • Security / support / governance docs: threat-model, support policy,
    contributing guides, CODEOWNERS, and eight issue templates.

Notes

  • The D-076 / D-189 wording lock was reviewed with no changes required: every
    rule recommendation is advisory and evidence-gated ("consider … only after
    validating"), with explicit guards against reflexive action; no unsafe advice
    is present (no kill / force / NOLOCK / shrink; no unqualified root-cause
    claims). See docs/wording-lock-review.md.
  • Must resolve before final v1.0.0: a dedicated private security contact or
    GitHub private vulnerability reporting; a dedicated conduct contact; the
    two-maintainer wording sign-off; ≥ 4 of 5 Tier-2 attestations; and,
    optionally, the historical v0.4.0 upgrade artifact (no public v0.4.0 tag
    exists). SECURITY.md and CODE_OF_CONDUCT.md describe the channels that
    exist today rather than promising contacts that do not — no placeholder
    addresses are published.
  • CODEOWNERS routes to the repository owner account @forward-thinkers-lab.
    The repository is owned by a user account, not an organization, so GitHub team
    syntax cannot resolve here; D-185's @core-maintainers team routing is
    superseded by D-191 and reactivated only if the project moves under an
    organization.