Switch SqlDataReader.ReadAsync to SqlDataReader.Read in SqlSessionStateProviderAsync because of a known performance issue with reading large data asynchronously - #119
Conversation
…nchronous versions in SqlSessionStateProvicerAsync because there exists a performance issue with reading large data asynchronously (dotnet/SqlClient#593)
565cf6a to
38675a3
Compare
|
@dotnet-policy-service agree |
|
Thank you for investigating this performance problem and submitting this change. The poor performance of large asynchronous reads in older versions of However, the change replaces the provider’s primary session-payload read with synchronous calls. That holds an ASP.NET worker thread while data is read from SQL Server and works against the central purpose of this async session-state provider. Although blocking reads can provide lower latency in isolation, making them the default could reduce scalability and increase request queuing under network latency or high concurrency. And the primary expectation for
<runtime>
<AppContextSwitchOverrides value="Switch.Microsoft.Data.SqlClient.UseCompatibilityAsyncBehaviour=false;Switch.Microsoft.Data.SqlClient.UseCompatibilityProcessSni=false" />
</runtime>This substantially reduces the large-read performance problem while preserving asynchronous I/O and its worker-thread scalability benefits. Packet multiplexing remains opt-in for compatibility, so applications should validate it against their workloads before deployment. Given that an application-level upgrade addresses the underlying Microsoft documentation: |
In one project, we suddenly encountered a major performance issue. The problem arose after deploying a new release. We spent a considerable amount of time searching for the cause within our release. Ultimately, the issue was traced back to the
SqlSessionStateProviderAsync.Since we use Application Insights for logging and tracing, we observed unusual gaps after reading the ASP.NET session. Initially, it appeared as if the session had already been read, and then the gap occurred. After extensive analysis and significantly extending the
SqlSessionStateProviderAsyncwith telemetry, we (my colleague @opneu and I) discovered that time was being lost within this session provider implementation.The calls to
SqlDataReader.ReadAsyncandSqlDataReader.GetFieldValueAsyncwithinSqlSessionStateProviderAsyncwere taking an extremely long time. Further research led me to this ticket:dotnet/SqlClient#593
After switching to the synchronous versions of the aforementioned methods, the session could be loaded again within just a few milliseconds.
We attribute the sudden occurrence of the massive performance problems to the fact that, with the new release, we are writing more to the ASP.NET session than before the release.
Looking back at past logs, we can say that we were not only able to resolve the new, truly severe performance issue, but the average access times to the ASP.NET session have also been faster since the fix.