DEV Community

Cover image for Benchmarking WJb: Measuring Raw Background Job Throughput in .NET
Oleksandr Viktor
Oleksandr Viktor

Posted on

Benchmarking WJb: Measuring Raw Background Job Throughput in .NET

Benchmarking WJb: Measuring Raw Background Job Throughput in .NET

When building a background job system, performance questions appear almost immediately:

  • How fast can I enqueue jobs?
  • Does it scale with concurrent producers?
  • What happens when payloads are not trivial?
  • Are delayed and timer jobs expensive?

To answer these questions early, WJb ships with a dedicated benchmark project:

WJb.Benchmarks [github.com]

This article explains what exactly is measured, how the benchmarks are structured, and what the numbers really mean.


Why Benchmark Enqueue Speed First?

WJb is designed as a lightweight, explicit background job engine.

Unlike full orchestration systems, WJb deliberately avoids:

  • Persistent storage by default
  • Distributed locks
  • Retries, dashboards, or schedulers baked into the core

That makes enqueue throughput a critical foundational metric.

If placing jobs into the system is slow or unpredictable, everything else scales poorly — regardless of how fast job execution later becomes.


What Is WJb.Benchmarks?

WJb.Benchmarks is a standalone console benchmark application designed to answer one simple question:

How fast can WJb prepare and enqueue jobs under different conditions?

The benchmark project lives under the test folder and is intentionally isolated from production code to keep results clean and reproducible. [github.com]


Benchmark Scenarios

The benchmark suite focuses on enqueue-only performance and includes four core scenarios:

1. Single-threaded enqueue

Measures raw throughput when jobs are enqueued sequentially from a single producer.

This represents:

  • Simple applications
  • Low-contention background usage
  • Baseline overhead of job creation + JSON compaction

Why it matters:
Single-thread speed reflects framework overhead, not threading tricks.


2. Multi-threaded enqueue (concurrent producers)

Uses multiple threads enqueueing jobs simultaneously.

This simulates:

  • Web APIs enqueueing background work
  • Message-driven systems
  • Burst workloads under pressure

The goal here is scalability, not just raw numbers.


3. Heavy JSON payload enqueue

Jobs rarely carry empty payloads in real systems.

This benchmark measures:

  • JSON serialization overhead
  • JsonObject compaction cost
  • Memory pressure from larger payloads

The payload is intentionally heavy to reveal realistic performance drops instead of optimistic results.


4. Delayed / timer job enqueue

Delayed jobs often involve:

  • Extra metadata
  • Timer coordination
  • Scheduling logic

This benchmark isolates enqueue cost only, without waiting for execution.


Benchmark Setup

The benchmarks are intentionally boring — and that’s a feature.

  • Action implementation: minimal IAction returning Task.CompletedTask
  • Execution: enqueue only (no worker execution measured)
  • Configuration: Release build
  • Runtime: modern .NET
  • Environment: standard developer machine

No database.

No persistence.

No background threads executing jobs.

This keeps results focused and repeatable.


Sample Results

A representative benchmark run looks like this:

WJb Performance Benchmark Suite
==================================
[Multi-threaded Enqueue]
200,000 jobs from 8 threads → ~320 ms
≈ 600k+ jobs/sec

[Single-thread Enqueue]
100,000 jobs → ~180 ms
≈ 500k+ jobs/sec

[Heavy JSON Payload]
20,000 jobs → ~400 ms
≈ 50k jobs/sec

[Delayed / Timer Jobs]
10,000 jobs → ~30 ms
≈ 330k jobs/sec
Enter fullscreen mode Exit fullscreen mode

⚠️ Exact numbers will vary per machine. The trend and scaling behavior are what matter.


How to Read These Numbers (Correctly)

These benchmarks do not measure job execution.

They measure:

  • Job compaction
  • JSON serialization
  • Internal queueing
  • Thread contention behavior

Real-world throughput will depend on:

  • The work your jobs perform
  • Worker concurrency
  • Machine resources
  • Whether persistence is added later

But high enqueue performance is still valuable because it ensures:

✅ predictable latency under load

✅ minimal overhead per job

✅ headroom for future features


Why This Approach Works

Many job systems optimize dashboards, retries, or storage first.

WJb does the opposite:

Build a fast, explicit, predictable core — then layer complexity consciously.

WJb.Benchmarks exists to validate that core continually, not once.


Run It Yourself

Clone the repository and run the benchmark project directly:

dotnet run -c Release
Enter fullscreen mode Exit fullscreen mode

Because it’s a plain console app, no infrastructure setup is required.

Repository:
https://github.com/UkrGuru/WJb/tree/main/test/WJb.Benchmarks [github.com]


Final Thoughts

Benchmarks don’t make software good — discipline does.

But a lightweight job engine that can enqueue hundreds of thousands of jobs per second provides a solid foundation for:

  • APIs
  • Workers
  • Schedulers
  • Workflow engines

WJb.Benchmarks is not about bragging rights — it’s about knowing the cost of every abstraction you add.

If that philosophy resonates with you, WJb is worth exploring further.


Tags

.NET CSharp Performance BackgroundJobs OpenSource


Top comments (0)