Step through your stored procedures. See what every line costs.

SpDev is a VS Code extension for SQL Server. Its debugger is free: breakpoints, variables, temp tables and result sets, one statement at a time. SpDev Pro measures every statement and reads the actual execution plans, so you know which line is slow and why.

For SQL Server 2016 and later, and Azure SQL Database. 2,400 installs on the VS Code Marketplace.

usp_CustomerStatement.sql Profiled run: 22.9 ms, 924 logical reads, 2 findings
  1. CREATE PROCEDURE dbo.usp_CustomerStatement
  2. @CustomerId INT,
  3. @Status NVARCHAR(20)
  4. AS
  5. BEGIN
  6. SET NOCOUNT ON;
  7. DECLARE @Open INT, @Total DECIMAL(12, 2);
  8. SELECT @Open = COUNT(*) 15 ms (65%) · 251 reads · 1 row
  9. FROM dbo.ProOrders
  10. WHERE Status = @Status;

    Implicit conversion of ProOrders.Status prevents an index seek

    SQL Server converts the column ProOrders.Status to nvarchar(20) to compare it with a value of a different type, so it cannot seek an index on it. Declare the variable or parameter with exactly the column's type.

    Index Scan reads 100,000 rows of dbo.ProOrders to keep 10,000.

  11. SELECT @Total = SUM(Total) 8 ms (35%) · 671 reads · 1 row
  12. FROM dbo.ProOrders
  13. WHERE CustomerId = @CustomerId;

    Missing index on dbo.ProOrders (CustomerId)

    SQL Server estimates this index would make the statement 99% cheaper.

    CREATE NONCLUSTERED INDEX [IX_ProOrders_CustomerId] ON [dbo].[ProOrders] ([CustomerId]);
  14. SELECT c.Name, c.Country, @Open AS OpenOrders, @Total AS Total 0 ms · 2 reads · 1 row
  15. FROM dbo.ProCustomers AS c
  16. WHERE c.CustomerId = @CustomerId;
  17. END
A procedure after one run with SpDev Pro: each statement's cost at the end of its line, lines tinted by their share of the run, and the problems found in the actual execution plans.

A T-SQL debugger, back in your editor

SQL Server Management Studio dropped its T-SQL debugger after version 17.9. SpDev puts one in VS Code, and it works the way you debug C#.

Free, MIT-licensed, and it never contacts our servers.

Breakpoints and stepping
Step over, into and out with F10, F11 and Shift+F11. Step Back goes backwards, one statement at a time.
Every variable, at every line
Parameters, variables, table variables, temp tables, table-valued parameters and XML, as they were before each statement.
Nested procedures
Step into the procedures you call. SpDev runs your local .sql files, so you can edit and run again without deploying.
Result sets where they happen
Hover a SELECT that has run to see the rows it returned. PRINT output goes to the Debug Console.
Errors on the right line
SQL Server errors are mapped back to the line in your file, and the debugger stops on errors nothing caught.
Calls from your app
Attach to a running .NET app and stop inside the procedures it calls through EF Core, Dapper or ADO.NET.

SpDev Pro shows why a procedure is slow

Click Profile above a procedure. SpDev runs it once and measures the time, CPU, reads, writes and rows of every statement. Then it reads the actual execution plans and puts each problem on the line that causes it, with the fix.

What SpDev Pro finds in execution plans
Finding What SpDev tells you
Missing indexes Scans that read far more than they keep, such as "reads 200,000 rows of dbo.Orders to keep 39", with the CREATE INDEX to copy.
Implicit conversions The column SQL Server had to convert, and the type your parameter or variable should have so the index can be used.
Parameter sniffing A plan compiled for one value and reused for another: "compiled for @Kind = 'C', ran with 'A'".
Key lookups Lookups that ran thousands of times, and the INCLUDE columns that remove them.
Functions on columns Predicates like YEAR(CreatedAt) = 2024 that can't seek, with the rewrite that can.
Bad estimates Where SQL Server expected 1 row and got 90,000, including the row counts table variables hide.
Spills and memory grants Sorts and hashes that spilled to tempdb, and grants much larger than the query used.
Scalar functions User-defined functions that run once for every row.
Row-by-row code Cursors and WHILE loops whose statements dominate the run.
Transactions and waits Transactions held open across slow statements, and statements that waited on locks or disk.

How it works, without AI

Every number comes from SQL Server, and every finding comes from a fixed rule. Run the same procedure twice and you get the same findings, each pointing at a value in the plan you can check yourself.

  1. Measure each statement

    Before each statement, SpDev reads your session's own counters from sys.dm_exec_requests. The difference between two readings is that statement's cost. SpDev measures its own overhead, a few microseconds, and subtracts it.

  2. Capture the actual plans

    For statements that read tables, SpDev turns on SET STATISTICS XML and keeps the plan SQL Server actually ran, with real row counts, warnings and waits. That needs the SHOWPLAN permission; without it you still get the line-by-line costs.

  3. Check the plans against known problems

    SpDev walks each plan and applies rules a performance specialist would apply by eye: rows read against rows kept, converted columns, compiled against runtime parameter values, estimates against actuals.

Also in Pro

Before and after
Every profile is kept. Change the code, profile again, and SpDev compares the two runs statement by statement. Logical reads are deterministic, so you can tell whether the fix worked or the server was just quieter.
Benchmarks
Run a procedure several times, each run rolled back, and get the median, p95 and spread of every statement.
Sandbox runs
Debug, run or profile inside a transaction that is rolled back afterwards, so testing doesn't change your data.
Coverage
Statement and branch coverage of your procedures in VS Code's Test Coverage view: which IF branches no test has reached.
Reports
Export a profile with its findings and the comparison as Markdown, ready for a ticket or a pull request.

Pricing

Try everything in Pro for 14 days, no card needed: run SpDev: Start Free Pro Trial in VS Code.

Debugger

$0 forever

 

Anyone, any number of machines

Step through stored procedures and scripts.

  • Breakpoints, step into, step out, step back
  • Variables, temp tables and table variables at every line
  • Result sets, PRINT output and errors on the right line
  • Nested procedures from your local files
  • Attach to a running .NET app (EF Core, Dapper, ADO.NET)
Install from the Marketplace

Pro

$79 per year

or $9 per month

1 developer, on up to 2 machines

Find out why a procedure is slow, and what to change.

  • Everything in the debugger
  • Line-by-line time, CPU, reads, writes and rows
  • Findings from the actual execution plans, with the fix
  • Before and after comparison of every run
  • Benchmarks, sandbox runs and procedure coverage
Buy Pro

Team

$590 per year

$59 per developer

10 developers, 2 machines each

SpDev Pro for a whole team on one licence key.

  • Everything in Pro, for 10 developers
  • One key; free a seat when someone leaves
  • Pay by card, or by invoice and bank transfer
  • Offline licences for machines without internet access
Buy for a team

Prices in US dollars. Taxes are added at checkout where they apply. Questions about licences, seats and invoices

Your code stays on your machine

SpDev connects only to the database you point it at. Your SQL, your data and your connection strings never leave your computer. Connection strings are kept in VS Code's secret storage.

The free debugger never contacts our server. SpDev Pro sends the licence server your licence key, a hash of VS Code's machine id and the computer's name, so a seat can be counted and freed.

From the blog

Practical notes on stored procedures, execution plans and SQL Server performance. All articles