添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The issue

var multi = await _dbContext.Database.GetDbConnection().QueryMultipleAsync(querySql + summarySql, paramters);
var items = await multi.ReadAsync<ItemModel>();
var summary = await multi.ReadFirstAsync<SummaryModel>();

After upgrading to 8.0, the third line of code runs with the following error:

System.InvalidOperationException: The reader is closed
   at void Npgsql.ThrowHelper.ThrowInvalidOperationException(string message)
   at void Npgsql.NpgsqlDataReader.CheckClosedOrDisposed()+Throw(ReaderState state)
   at async Task<bool> Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming, CancellationToken cancellationToken)
   at async Task Dapper.SqlMapper+GridReader.OnAfterGridAsync(int index) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 148
   at async Task<IEnumerable<T>> Dapper.SqlMapper+GridReader.ReadBufferedAsync<T>(int index, Func<DbDataReader, object> deserializer) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 246

Further technical details

Npgsql version: 8.0
PostgreSQL version: 15.3
Operating system: Debian 12 in Docker

System.InvalidOperationException: The reader is closed System.InvalidOperationException: The reader is closed 8.0.0 Nov 21, 2023 System.InvalidOperationException: The reader is closed 8.0.0 System.InvalidOperationException: The reader is closed - 8.0.0 Nov 21, 2023

I have a feeling that this problem is actually caused by another issue. When the SQL query returns a lot of content, the first thing I encounter is a timeout before The reader is closed

Hopefully this will help in investing the problem

Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
 ---> System.TimeoutException: Timeout during reading attempt
   at async ValueTask Npgsql.Internal.NpgsqlReadBuffer.Ensure(int count, bool async)+EnsureLong(?)
   at async Task Npgsql.Internal.NpgsqlReadBuffer.Skip(int len, bool async)
   at async Task Npgsql.NpgsqlDataReader.ConsumeRow(bool async)+ConsumeRowSequential(?)
   at async bool Npgsql.NpgsqlDataReader.NextResult()+ConsumeResultSet(?)
   at async Task<bool> Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming, CancellationToken cancellationToken) x 2
   at async Task Dapper.SqlMapper+GridReader.OnAfterGridAsync(int index) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 148

I continued to try to write a runnable sample.

Could you make this a runnable sample? Adding the (if possible, simplified) definitions of querySql, summarySql, ItemModel and SummaryModel would help me investigate.

Hopefully this will help in investing the problem

It does help, it confirms my suspicion we're going off the rails somewhere, likely losing protocol sync.

I continued to try to write a runnable sample.

Thanks.

In the meantime could you try to rerun your code with AppContext.SetSwitch("Npgsql.EnableDiagnostics", true); added to your program.cs? (make sure it's set before any Npgsql code is called) The extra checks should help us get more precise exceptions. Ideally you might get an exception from the exact point where we lose sync.

Let us know what the results are, even if nothing changed!

Rerun your code with AppContext.SetSwitch("Npgsql.EnableDiagnostics", true); added to your program.cs

This is the exception after set AppContext.SetSwitch("Npgsql.EnableDiagnostics", true);

Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
 ---> System.TimeoutException: Timeout during reading attempt
   at Npgsql.Internal.NpgsqlReadBuffer.<Ensure>g__EnsureLong|54_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at Npgsql.Internal.NpgsqlReadBuffer.Skip(Int32 len, Boolean async)
   at Npgsql.Internal.PgReader.Consume(Boolean async, Nullable`1 count, CancellationToken cancellationToken)
   at Npgsql.Internal.PgReader.<CommitAsync>g__CommitSlow|99_0()
   at Npgsql.NpgsqlDataReader.<ConsumeRow>g__ConsumeRowSequential|129_0(Boolean async)
   at Npgsql.NpgsqlDataReader.<NextResult>g__ConsumeResultSet|52_0(Boolean async)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Dapper.SqlMapper.GridReader.OnAfterGridAsync(Int32 index) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 148
   at Dapper.SqlMapper.GridReader.ReadBufferedAsync[T](Int32 index, Func`2 deserializer) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 246

@NinoFloris After upgrade to 8.0.1 we still receive this error:

Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
 ---> System.TimeoutException: Timeout during reading attempt
   at async ValueTask Npgsql.Internal.NpgsqlReadBuffer.Ensure(int count, bool async)+EnsureLong(?)
   at async Task Npgsql.Internal.NpgsqlReadBuffer.Skip(int len, bool async)
   at async Task Npgsql.NpgsqlDataReader.ConsumeRow(bool async)+ConsumeRowSequential(?)
   at async bool Npgsql.NpgsqlDataReader.NextResult()+ConsumeResultSet(?)
   at async Task<bool> Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming, CancellationToken cancellationToken) x 2
   at async Task Dapper.SqlMapper+GridReader.OnAfterGridAsync(int index) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 148
   at async Task<IEnumerable<T>> Dapper.SqlMapper+GridReader.ReadBufferedAsync<T>(int index, Func<DbDataReader, object> deserializer) in /_/Dapper/SqlMapper.GridReader.Async.cs:line 246

@vonzshik This problem doesn't occur in 7.0

@NinoFloris I'll reconfirm the issue tomorrow, as we're all docker builds without a nuget package cache, so it's unlikely to be a problem with me not upgrading to version 8.0.1

I will make a working repo as soon as I can.

#5439

Was resolved for repro code.
But after update to 8.0.1 had new cases in queries that has more than 3 "skipped" columns while reading

with errors

"Internal Npgsql bug: unexpected value 0 of enum BackendMessageCode. Please file a bug."
"The read on this field has not consumed all of its bytes (pos: 4, len: 105)"

tried to repro it with simplest case and had reproducible error with code

using System;
using System.Threading.Tasks;
namespace pgTest;
public class Program {
	private const string ConnStr = "Server=pg;Port=5432;Database=temp;User id=admin;Password=admin";
	private static readonly Npgsql.NpgsqlDataSource ds = new Npgsql.NpgsqlDataSourceBuilder(ConnStr).Build();
	public static async Task Main() {
		AppContext.SetSwitch("Npgsql.EnableAssertions", true);
		try {
			Console.WriteLine($"Started");
			using var conn = await ds.OpenConnectionAsync();
			Console.WriteLine($"Connected");
			using var tx = await conn.BeginTransactionAsync();
			using var cmd = conn.CreateCommand();
			cmd.CommandTimeout = 1;
			cmd.Transaction = tx;
			cmd.CommandText = """select v.i, repeat('1', 10), repeat('2', 10), repeat('3', 10), repeat('4', 10), 1, 2 from generate_series(1, 1000) as v(i)""";
			var rdr = await cmd.ExecuteReaderAsync(System.Data.CommandBehavior.SingleResult | System.Data.CommandBehavior.SequentialAccess);
			while (await rdr.ReadAsync()) {
				_ = rdr[0];
				_ = rdr[1];
				//_ = rdr[2];
				//_ = rdr[3];
				//_ = rdr[4];
				//_ = rdr[5]; // uncomment lines for successful execution
				_ = rdr[6];
			await rdr.DisposeAsync();
			await cmd.DisposeAsync();
			await tx.CommitAsync();
			await conn.DisposeAsync();
		catch (Exception e) {
			Console.WriteLine(e);

But with error

Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
 ---> System.TimeoutException: Timeout during reading attempt
   at Npgsql.Internal.NpgsqlReadBuffer.<Ensure>g__EnsureLong|54_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at Npgsql.Internal.NpgsqlReadBuffer.Skip(Int32 len, Boolean async)
   at Npgsql.NpgsqlDataReader.<>c__DisplayClass128_0.<<SeekToColumnSequential>g__Core|0>d.MoveNext()

Not sure it's tightly linked, but maybe it has same reason.

@NinoFloris

@kae thanks for the repro, that's unfortunate... I've tested it against #5476 which does away with the complicated buffered sequential fast path entirely. It passes there but I'm not sure it's something we want to backport to 8.0.2. Because of that I've also created a targeted fix in #5486.

I'm sorry for the issue persisting into the 8.0.1 release.

I guess i have the same issue in package Npgsql.EntityFrameworkCore.PostgreSQL version 8.0.0
Sometimes it works fine

using (var multi = await connection.QueryMultipleAsync(query, parameters))
    result.TotalItems = multi.ReadSingle<int>();
    result.Items = multi.Read<UserForInternalAgentDto>().ToArray();

Stacktrace

System.InvalidOperationException: The reader is closed
   at Npgsql.ThrowHelper.ThrowInvalidOperationException(String message)
   at Npgsql.NpgsqlDataReader.<CheckClosedOrDisposed>g__Throw|138_0(ReaderState state)
   at Npgsql.NpgsqlDataReader.CheckClosedOrDisposed()
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Dapper.SqlMapper.GridReader.OnAfterGrid(Int32 index) in /_/Dapper/SqlMapper.GridReader.cs:line 450
   at Dapper.SqlMapper.GridReader.ReadDeferred[T](Int32 index, Func`2 deserializer, Type effectiveType)+<>m__Finally1() in /_/Dapper/SqlMapper.GridReader.cs:line 404
   at Dapper.SqlMapper.GridReader.ReadDeferred[T](Int32 index, Func`2 deserializer, Type effectiveType)+System.IDisposable.Dispose()
   at Dapper.SqlMapper.GridReader.ReadDeferred[T](Int32 index, Func`2 deserializer, Type effectiveType)+MoveNext() in /_/Dapper/SqlMapper.GridReader.cs:line 406
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Dapper.SqlMapper.GridReader.ReadImpl[T](Type type, Boolean buffered) in /_/Dapper/SqlMapper.GridReader.cs:line 205   at Dapper.SqlMapper.GridReader.Read[T](Boolean buffered) in /_/Dapper/SqlMapper.GridReader.cs:line 96
          

Heyho 👋
Thank you for providing this Libary: We have updated to the latest 8.0.1 release from 7.0.6 and we are experiencing the following exception when there is a high load of complex queries:

Npgsql.NpgsqlException (0x80004005): Exception while reading from stream
 ---> System.TimeoutException: Timeout during reading attempt
   at Npgsql.Internal.NpgsqlReadBuffer.<Ensure>g__EnsureLong|54_0(NpgsqlReadBuffer buffer, Int32 count, Boolean async, Boolean readingNotifications)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
   at Npgsql.Internal.NpgsqlConnector.ReadMessageLong(Boolean async, DataRowLoadingMode dataRowLoadingMode, Boolean readingNotifications, Boolean isReadingPrependedMessage)
   at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult(Boolean async, Boolean isConsuming, CancellationToken cancellationToken)
   at Npgsql.NpgsqlDataReader.NextResult()
   at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(Boolean async, CommandBehavior behavior, CancellationToken cancellationToken)
   at Npgsql.NpgsqlCommand.ExecuteReader(CommandBehavior behavior)
   at Npgsql.NpgsqlBatch.ExecuteReader(CommandBehavior behavior)
   at Npgsql.Internal.NpgsqlConnector.QueryDatabaseState(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlMultiHostDataSource.TryGetIdleOrNew(NpgsqlConnection conn, TimeSpan timeoutPerHost, Boolean async, TargetSessionAttributes preferredType, Func`3 stateValidator, Int32 poolIndex, IList`1 exceptions, CancellationToken cancellationToken)

The Stacktrace looks pretty simiular to this issue so i decided to post this here. Some information about our system:
We were using:

  • .net8
  • with docker (mcr.microsoft.com/dotnet/aspnet:8.0.1-bookworm-slim@sha256:3ff67792728179308c4bf06799d8b45d155c60fddc347acf69465a496d9a20b8)
  • npgsql with 8.0.1
  • Postgres 13
  • We use the "Multiple Hosts"-Feature with 3 Postgres nodes where one of them is primary and the other hosts are replicas. So we set Target Session Attributes=primary.
  • System.InvalidOperationException: The reader is closed - 8.0.0 Npgsql.NpgsqlException (0x80004005): Exception while reading from stream - 8.0.0 Jan 19, 2024

    I want to make sure we can put this issue to bed properly with 8.0.2.

    @kae would you mind running the latest ci build from myget to see if things are working correctly for you? (https://www.myget.org/feed/npgsql-vnext/package/nuget/Npgsql/9.0.0-preview.1-ci.20240131T215454+sha.882265627)

    Anybody else is free to try as well of course.

    Hello,

    To test this bug we have added integration test. The error is consistently reproduced under fairly high load (hundreds of parallel requests or more).

    We have now run this test for build with the specified package version (9.0.0-preview.1-ci.20240131T215454).

    Unfortunately, the error is being reproduced.

    Message: "Timeout during reading attempt".

    at Npgsql.Internal.NpgsqlReadBuffer.<<Ensure>g__EnsureLong|54_0>d.MoveNext()
       at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token)
       at Npgsql.Internal.NpgsqlConnector.<ReadMessageLong>d__233.MoveNext()
       at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
       at Npgsql.Internal.NpgsqlConnector.<ReadMessageLong>d__233.MoveNext()
       at System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder`1.StateMachineBox`1.System.Threading.Tasks.Sources.IValueTaskSource<TResult>.GetResult(Int16 token)
       at Npgsql.NpgsqlDataReader.<NextResult>d__52.MoveNext()
       at Npgsql.NpgsqlDataReader.<NextResult>d__52.MoveNext()
       at Npgsql.NpgsqlDataReader.NextResult()
       at Npgsql.NpgsqlCommand.<ExecuteReader>d__119.MoveNext()
       at Npgsql.NpgsqlCommand.<ExecuteReader>d__119.MoveNext()
       at System.Threading.Tasks.ValueTask`1.get_Result()
       at Npgsql.NpgsqlCommand.<ExecuteNonQuery>d__107.MoveNext()
       at Npgsql.NpgsqlCommand.ExecuteNonQuery()
       at Npgsql.NpgsqlBatch.ExecuteNonQuery()
       at Red.WorkPoint.Data.TmConnectionInterceptor.ConnectionOpened(DbConnection connection, ConnectionEndEventData eventData) in D:\repos\backend\Red.WorkPoint.Data\Data\TmConnectionInterceptor.cs:line 22
       at Microsoft.EntityFrameworkCore.Diagnostics.Internal.RelationalConnectionDiagnosticsLogger.ConnectionOpened(IRelationalConnection connection, DateTimeOffset startTime, TimeSpan duration)
       at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected)
       at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReader(RelationalCommandParameterObject parameterObject)
       at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.InitializeReader(Enumerator enumerator)
       at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.<>c.<MoveNext>b__21_0(DbContext _, Enumerator enumerator)
       at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)

    @zolotovvv that is not the same issue, please create a new issue with its own runnable repro.

    EF does not use CommandBehavior.Sequential, which Dapper does and where our fixes have been targeted.

    @kae would you mind running the latest ci build from myget to see if things are working correctly for you? (https://www.myget.org/feed/npgsql-vnext/package/nuget/Npgsql/9.0.0-preview.1-ci.20240131T215454+sha.882265627)

    Checked with repro
    there were no issues with "9.0.0-preview.1-ci.20240131T215454" and stable reproduction with "8.0.1"

    Hello, was this issue really solved for version 8.0.3. I was running performance test for 100 concurrent users. I used JMeter collection with 40 various steps/API calls. I had no issue when using Npqsql version 7.0.7 (of course using EntityFramework version 7). But when I used Npqsql version 8.0.3 (with EntityFramework version 8) I got a low of exceptions Npgsql.NpgsqlException (0x80004005): Exception while reading from stream --> System.TimeoutException: Timeout during reading attempt at Npgsql.Internal.NpgsqlReadBuffer. And therefore I am not able to complete performance test for 100 concurrent users with version 8. And as I wrote above version 7 works without any issue. And of course connection string and timeout settings was the same for both testing scenarios.

    Hi. I verified just one API step which was the most problematic. Generated queries was relative simple and exactly same for v7 and v8. The problem was especially with Insert operation into multiple tables (one API call generates insert to multiple tables). But because our system is robust the "Npgsql.NpgsqlException (0x80004005): Exception while reading from stream" started to appear on various places/methods. But it was usually one of the first 5 methods from prepared collection. But there was no chance to complete other steps because I tested real application journey and each step depends on result of previous step.

    Hello, I don't want to tell that our code/structure is optimal but I don't think pg_stat_statements and pg_stat_activity will help me. The goal of our application is to support 100 concurrent users. But after we switch to version 8 we are not able to reach this goal. We are able to sucessfully run test(s) for 50 concurrent users. As I wrote above we test complex insurance journey with more then 40 steps (API calls). We store data into Platoform and Document databases. And when we test 100 concurrent users we get a lot of Npgsql.NpgsqlException (0x80004005): Exception while reading from stream errors.
    I made also tests using infinity timeout (Command Timeout = 0) and than error above occured occasionally. But then we started to have another error: Npgsql.PostgresException (0x80004005): 53300: sorry, too many clients already
    So test result is exactly same. We are not able to support 100 concurrent users. It works for 50 concurrent users only.

    Another test I've made was that I changed/downgraded following nugets (just a note that I haven't updated framework version):

  • Npgsql version: 7.0.7
  • Npgsql.EntityFrameworkCore.PostgreSQL version: 7.0.18
  • Microsoft.EntityFrameworkCore version 7.0.20
    And in this case I don't get any error when running test(s) for 100 concurrent users! And code and tests are exactly same (except nugets mentioned above). So my experience is that performance is radically reduced when switching from Npgsql+EF Core version 7 to Npgsql+EF Core version 8. And all exceptions we get come from Npgsql nuget. And all I want is that update from version 7 to version 8 will not decrease performance of our application.
  • I also compared sql query/script generated for the most problematic operation in our test which was storing of documents. Scrips are exactly the same for both version 7 and version 8. I attached generated script to store one document generated with dynamic tags. As you can see insert queries are very simple.
    Of course we also get errors in other actions too but storing of document is probably the most time-consume action. Just FYI, document(s) can be generated in 2 different steps of our application journey test.

    Further technical details
    Framework: .Net 8
    Npgsql version: 8.0.3
    Npgsql.EntityFrameworkCore.PostgreSQL version: 8.0.4
    Microsoft.EntityFrameworkCore version 8.0.6
    PostgreSQL version: 14.5
    Operating system: Windows
    InsertDocument.zip

    Thanks for providing more context, though these problems will always be very difficult to diagnose from a distance. The library is under performance regression testing by multiple teams (the ASP.NET team and TechEmpower for instance) so it's unlikely we have actually regressed general performance.

    However there may be some lingering edge-case issue from our 8.x rewrite, and this could be what you are potentially hitting.

    InsertDocument.zip

    Could you provide the schema for these inserts? Essentially I want to see which database types are used, to quickly check whether there could be any suboptimal write implementations for these types.

    Hello, I don't want to tell that our code/structure is optimal but I don't think pg_stat_statements and pg_stat_activity will help me.

    I'm asking you to take a look at pg_stat_statements and pg_stat_activity just to confirm that the query in question is indeed fast so the issue is on our side and not on pg's.
    Looking at the query you provided there could be multiple other reasons why it could be slow:

  • If there are PK/FK, PG has to validate them on insert, which can result in full table scan if there is no index on referenced tables. And it becomes slower the more rows there are in the referenced table.
  • By default postgres writes query changes to WAL immediately after a COMMIT is requested and blocks until the write is successful. That means that the more inserts into the same table there are, the slower they'll be because they're going to block each other (it depends whether they're writing into the same page and a few other things, but more or less that's how it is).
  • Every time you insert a row pg has to update indices. In some cases pg has to rebalance them which will result in exclusive lock.
  • Hello, I don't want to tell that our code/structure is optimal but I don't think pg_stat_statements and pg_stat_activity will help me.

    I'm asking you to take a look at pg_stat_statements and pg_stat_activity just to confirm that the query in question is indeed fast so the issue is on our side and not on pg's. Looking at the query you provided there could be multiple other reasons why it could be slow:

  • If there are PK/FK, PG has to validate them on insert, which can result in full table scan if there is no index on referenced tables. And it becomes slower the more rows there are in the referenced table.
  • By default postgres writes query changes to WAL immediately after a COMMIT is requested and blocks until the write is successful. That means that the more inserts into the same table there are, the slower they'll be because they're going to block each other (it depends whether they're writing into the same page and a few other things, but more or less that's how it is).
  • Every time you insert a row pg has to update indices. In some cases pg has to rebalance them which will result in exclusive lock.
  • Hello, I understand what do your wrote and it could really help in some cases. But my test generates so many/various queries. And as I wrote that the same queries works on version 7 but does not work (or works in limited way) on version 8. Therefore I am not sure if pg_stat_statements and pg_stat_activity could help to solve the current issue.

    I made also tests using infinity timeout (Command Timeout = 0) and than error above occured occasionally. But then we started to have another error: Npgsql.PostgresException (0x80004005): 53300: sorry, too many clients already
    So test result is exactly same

    Btw this means that across your app you're not limiting your maximum connections properly. Maybe you're opening some management connection somewhere (e.g. health checks, background worker etc) while your main pool max size hasn't been reduced to take this into account.

    Hello Nino, thanks for your answer. I attached schema for related tables.
    Schema.zip

    I took a look and it seems the schema is using common types like: bool, uuid, integer, text, citext, timestamp with timezone, and bytea.

    Many other users would have opened issues if these types would have regressed significantly in v8.

    I think we're going to need a profile of the app under load to understand where a bottleneck may have appeared since v8.
    Could you collect a dotnet-trace? It won't contain a memory dump but you can send it to my github mail address if you don't want this to be public.

    @risulo One more thought, did you take a look at cpu stats and such to see whether v8 is using at least as much cpu as v7?

    Nino, I retested it today. CPU usage was up to 65% and memory usage was between 80% and 85% on my testing machine. These values was approximately the same for both v7 and v8. And they was also approximately same when I tested 10, 50 or 100 concurrent users.

    OK one more question, are you using sync ADO.NET apis by any chance?

    If the impacted features in your app are properly doing async EF calls I'll really have to see a profile to help you any further.

    Our solution is relative old and does not use async EF calls.

    @risulo take a look at this issue #5575 (comment)

    If at all possible I suggest you to try and increase your minimum threadpool threads (e.g. ThreadPool.SetMinThreads(100, 100)) to see if it brings the perf back to 7.x levels. Alternatively you can refactor your code to use async IO or decide to stay on 7.x for the coming years.

    We're aware it's not ideal from a backwards compatibility standpoint. Npgsql is an evolving driver and we have to re-evaluate trade-offs and workarounds over time to stay modern and maintainable. In 8.x we decided to remove one of our workarounds to handle synchronous batch queries at higher loads which had deep impact on all the async code we maintain. Keeping it any longer would have been a burden on new work we wanted to deliver; like the support for NativeAOT we landed in 8.0.0. Removing this workaround also solved some long standing issues like enabling Microsoft Orleans compatibility where before it was preventing users from using Npgsql asynchronously together with it at all (see #1130).

    Over time balances shift to favor one trade-off over another based on maintainability costs, popularity and impact. Async is really here to stay and is our recommended execution mode for anything beyond simple single statement queries.

    @risulo take a look at this issue #5575 (comment)

    If at all possible I suggest you to try and increase your minimum threadpool threads (e.g. ThreadPool.SetMinThreads(100, 100)) to see if it brings the perf back to 7.x levels. Alternatively you can refactor your code to use async IO or decide to stay on 7.x for the coming years.

    We're aware it's not ideal from a backwards compatibility standpoint. Npgsql is an evolving driver and we have to re-evaluate trade-offs and workarounds over time to stay modern and maintainable. In 8.x we decided to remove one of our workarounds to handle synchronous batch queries at higher loads which had deep impact on all the async code we maintain. Keeping it any longer would have been a burden on new work we wanted to deliver; like the support for NativeAOT we landed in 8.0.0. Removing this workaround also solved some long standing issues like enabling Microsoft Orleans compatibility where before it was preventing users from using Npgsql asynchronously together with it at all (see #1130).

    Over time balances shift to favor one trade-off over another based on maintainability costs, popularity and impact. Async is really here to stay and is our recommended execution mode for anything beyond simple single statement queries.

    Hello Nino. Thanks for your reply. At first "sync" solution using ThreadPool.SetMinThreads(100, 100) setting does not work. It is true that I don't get Timeout exception but I get another one: Npgsql.PostgresException (0x80004005): 53300: sorry, too many clients already

    But I tested "async" solution and it works fine. Of course I haven't updated whole solution yet. I just tested (and updated) 5 steps and had executed test with 100 concurent users. And it works fine for async solution. The same test fails for 100 concurent users using "sync" solution.

    It is true that I don't get Timeout exception

    That's great to hear, ThreadPool.SetMinThreads(100, 100) is precisely to prevent those timeout exceptions from happening.

    but I get another one: Npgsql.PostgresException (0x80004005): 53300: sorry, too many clients already

    This is always due to something in your app (or wider infra) holding onto more connections than your database will accept. Make sure you don't use multiple datasources, or have other places that may hold open a connection to the database. Also check whether your connection string MaxPoolSize (defaults to 100 connections) fits within what your db accepts. Many cloud databases have maximum connection counts that scales with instance size, so it may well accept less than 100 connections on small instances used for testing.

    But I tested "async" solution and it works fine. Of course I haven't updated whole solution yet. I just tested (and updated) 5 steps and had executed test with 100 concurent users.

    If you can, please do, async is very much recommended at this point.