We're seeing a strange pattern in production: the first call to a Dapper-backed endpoint is instant, but the next few within the same minute crawl. SQL Server 2019, same query plan every time according to the actual execution plan.
I enabled SET STATISTICS IO, TIME ON and logical reads jump after the initial execution. Could parameter sniffing be locking the optimizer onto a bad plan from the first parameter set? We don't use OPTION (RECOMPILE). Is there a lightweight way to diagnose or mitigate this without rewriting the whole data layer?
It could be, particularly if your database is SQL Server and the query runs quickly for some parameter values but slowly for others. Dapper sends parameterized SQL, so SQL Server can reuse a cached execution plan for later calls. If that plan suits one set of values but not another, performance can vary sharply.
The timing is a clue, though: parameter sniffing usually means different calls get different performance, not that every call necessarily gets slower over time. If the first requests are fast and later ones are consistently slow, also check for growing load, blocking, connection-pool pressure, or a change in the number of rows returned. Dapper’s own query caching is generally not the same thing as SQL Server’s execution-plan cache.
What to compare
As a diagnostic, test the query with
OPTION (RECOMPILE)orOPTIMIZE FOR UNKNOWNin a safe environment. If performance changes substantially, plan sensitivity is worth investigating—but these hints are not automatic fixes. Recompiling has a cost, and a better long-term option may be updated statistics, a query or index change, or SQL Server’s parameter-sensitive plan optimization where supported.So yes, parameter sniffing is plausible, but compare the parameter values, plans, and database waits before changing Dapper code or adding a hint.