Live
Black Hat USAAI BusinessBlack Hat AsiaAI Businessciflow/trunk/178793PyTorch Releases[R] deadlines for main conferencesReddit r/MachineLearningThe truth about AI in media - radioinfoGNews AI AustraliaAgentic AI Is Acting on Your Behalf. Is Your Data Ready? - Tech CritterGNews AI agentictrunk/43172938c77ce95e706aad37dd15fda0a909c66cPyTorch ReleasesI Rewrote Our Payment Gateway in Rust. Revenue Impact Surprised MeDEV Community🚀 Gudu SQL Omni Lineage Analysis — Directly Inside VS CodeDEV Communityb8672llama.cpp ReleasesThe $200 Billion Wait: How Outdated Banking Rails Are Strangling the Global WorkforceDEV CommunityBuilding AI Visibility Infrastructure: The Technical Architecture Behind JonomorDEV CommunityAlma and Rocky Linux ISOs: DVD vs Boot vs MinimalDEV Community[D] How to break free from LLM's chains as a PhD student?Reddit r/MachineLearningBlack Hat USAAI BusinessBlack Hat AsiaAI Businessciflow/trunk/178793PyTorch Releases[R] deadlines for main conferencesReddit r/MachineLearningThe truth about AI in media - radioinfoGNews AI AustraliaAgentic AI Is Acting on Your Behalf. Is Your Data Ready? - Tech CritterGNews AI agentictrunk/43172938c77ce95e706aad37dd15fda0a909c66cPyTorch ReleasesI Rewrote Our Payment Gateway in Rust. Revenue Impact Surprised MeDEV Community🚀 Gudu SQL Omni Lineage Analysis — Directly Inside VS CodeDEV Communityb8672llama.cpp ReleasesThe $200 Billion Wait: How Outdated Banking Rails Are Strangling the Global WorkforceDEV CommunityBuilding AI Visibility Infrastructure: The Technical Architecture Behind JonomorDEV CommunityAlma and Rocky Linux ISOs: DVD vs Boot vs MinimalDEV Community[D] How to break free from LLM's chains as a PhD student?Reddit r/MachineLearning
AI NEWS HUBbyEIGENVECTOREigenvector

NPoco vs UkrGuru.Sql: When Streaming Beats Buffering

DEV Communityby Oleksandr ViktorApril 2, 20264 min read0 views
Source Quiz

When we talk about database performance in .NET, we often compare ORMs as if they were interchangeable. In practice, the API shape matters just as much as the implementation . In this post, I benchmark NPoco and UkrGuru.Sql using BenchmarkDotNet, focusing on a very common task: reading a large table from SQL Server. The interesting part is not which library wins , but why the numbers differ so much. TL;DR : Streaming rows with IAsyncEnumerable is faster, allocates less, and scales better than loading everything into a list. Test Scenario The setup is intentionally simple and realistic. Database: SQL Server Table: Customers Dataset: SampleStoreLarge (large enough to stress allocations) Columns: CustomerId FullName Email CreatedAt All benchmarks execute the same SQL: SELECT CustomerId , Full

When we talk about database performance in .NET, we often compare ORMs as if they were interchangeable. In practice, the API shape matters just as much as the implementation.

In this post, I benchmark NPoco and UkrGuru.Sql using BenchmarkDotNet, focusing on a very common task: reading a large table from SQL Server. The interesting part is not which library wins, but why the numbers differ so much.

TL;DR: Streaming rows with IAsyncEnumerable is faster, allocates less, and scales better than loading everything into a list.

Test Scenario

The setup is intentionally simple and realistic.

  • Database: SQL Server

  • Table: Customers

  • Dataset: SampleStoreLarge (large enough to stress allocations)

  • Columns:

CustomerId FullName Email CreatedAt

All benchmarks execute the same SQL:

SELECT CustomerId, FullName, Email, CreatedAt FROM Customers

Enter fullscreen mode

Exit fullscreen mode

No filters, no projections — just raw read performance.

Benchmark Code

using BenchmarkDotNet.Attributes; using Microsoft.Data.SqlClient; using NPoco; using UkrGuru.Sql;

public class SqlBenchmark { private const string ConnectionString = "Server=(local);Database=SampleStoreLarge;Trusted_Connection=True;TrustServerCertificate=True;";

private const string CommandText = "SELECT CustomerId, FullName, Email, CreatedAt FROM Customers";

[Benchmark] public async Task NPoco_LoadList() { using var connection = new SqlConnection(ConnectionString); await connection.OpenAsync();

using var db = new Database(connection);

var list = await db.FetchAsync(CommandText); return list.Count; }

[Benchmark] public async Task UkrGuru_LoadList() { await using var connection = await DbHelper.CreateConnectionAsync(ConnectionString);

var list = await connection.ReadAsync(CommandText); return list.Count(); }

[Benchmark] public async Task UkrGuru_StreamRows() { int count = 0;

await using var command = await DbHelper.CreateCommandAsync( CommandText, connectionString: ConnectionString);

await foreach (var _ in command.ReadAsync()) count++;_

return count; } }`

Enter fullscreen mode

Exit fullscreen mode

All benchmarks were run in Release mode with BenchmarkDotNet.

Results (Execution Time)

Method Mean StdDev Median

NPoco_LoadList 8.23 ms 0.33 ms 8.22 ms

UkrGuru_LoadList 5.30 ms 0.57 ms 5.34 ms

UkrGuru_StreamRows 3.29 ms 0.14 ms 3.22 ms

At first glance, streaming is already ~2.5× faster than NPoco. But the real story starts when we look at memory.

Results (Memory & GC)

Method Gen0 Gen1 Gen2 Allocated

NPoco_LoadList 367 258 109 4.39 MB

UkrGuru_LoadList 203 188 70 2.33 MB

UkrGuru_StreamRows 164 – – 2.08 MB

This table explains almost everything.

What’s Actually Being Measured?

NPoco_LoadList

  • Uses FetchAsync()

  • Fully materializes a List

  • Allocates buffers and intermediate objects

✅ Idiomatic NPoco usage

❌ No streaming support

NPoco optimizes for developer productivity, not minimal allocations. That’s a valid trade‑off, but it shows up clearly in GC pressure.

UkrGuru_LoadList

  • Also builds a full list

  • Uses a leaner mapping pipeline

  • Roughly half the allocations of NPoco

✅ Same algorithm as NPoco

✅ Less overhead

This is a fair apple‑to‑apple comparison with NPoco’s approach.

UkrGuru_StreamRows

  • Uses IAsyncEnumerable

  • Processes rows one at a time

  • No list allocation

  • No Gen2 collections

✅ True async streaming

✅ Lowest latency

✅ Most stable GC behavior

This is not a micro‑optimization — it’s a different execution model.

Why Streaming Wins

The biggest improvement is not raw speed — it’s memory behavior.

  • Fewer allocations

  • Almost no object promotion

  • No Gen2 collections

That matters a lot under real load: ASP.NET requests, background workers, message consumers, etc.

Streaming doesn’t just run faster — it scales better.

About Fairness

This benchmark is not trying to prove that one ORM is “better” than another.

It compares three distinct patterns:

  • Buffered list materialization (NPoco)

  • Buffered list materialization with fewer abstractions

  • True async streaming

Comparing streaming to buffering is not “ORM vs ORM” — it’s algorithm vs algorithm.

When Should You Use Each?

Use NPoco when:

  • You want simple, expressive data access

  • Loading lists is acceptable

  • Developer time matters more than raw throughput

Use streaming (e.g. UkrGuru.Sql) when:

  • Result sets are large

  • Latency and GC pressure matter

  • You want full control over execution

Final Thoughts

Benchmarks don’t just measure libraries — they measure abstractions and APIs.

If your workload is dominated by large reads, switching from buffered lists to async streaming can cut both execution time and memory pressure dramatically.

Choose the tool that matches your data access pattern, not just the one you’re used to.

Was this article helpful?

Sign in to highlight and annotate this article

AI
Ask AI about this article
Powered by Eigenvector · full article context loaded
Ready

Conversation starters

Ask anything about this article…

Daily AI Digest

Get the top 5 AI stories delivered to your inbox every morning.

Knowledge Map

Knowledge Map
TopicsEntitiesSource
NPoco vs Uk…modelbenchmarkreleaseproductDEV Communi…

Connected Articles — Knowledge Graph

This article is connected to other articles through shared AI topics and tags.

Knowledge Graph100 articles · 157 connections
Scroll to zoom · drag to pan · click to open

Discussion

Sign in to join the discussion

No comments yet — be the first to share your thoughts!

More in Products