DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
World desk5 min

Racing Background Jobs: The Distributed Lock Gap in ASP.NET Core

Hosted services do not elect a single worker across replicas, and timers can overlap callbacks locally. Learn which coordination approach fits each problem.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

AddHostedService does not make a background worker run only once across an ASP.NET Core deployment. Every running application host can start its own hosted-service instance, so multiple replicas may execute the same recurring job. Separately, a timer can begin a new callback before the previous one finishes. Preventing local overlap and preventing overlap across replicas are different problems—and require different coordination.

Why can the same ASP.NET Core job run more than once?

A hosted service runs inside an application host; it is not a cluster-wide scheduler or leader election mechanism. Registering a service with AddHostedService means each running host can start its own copy. If a deployment has several replicas, each may run the same loop or scheduled work unless something coordinates them.

As an Amazon Associate I earn from qualifying purchases.

There is also a separate timer-reentrancy issue. Microsoft Learn warns that “The Timer doesn’t wait for previous executions of DoWork to finish, so the approach shown might not be suitable for every scenario.” A callback that takes longer than the timer interval can therefore overlap with another callback in that same process. Microsoft’s ASP.NET Core hosted-services documentation for .NET 10 describes this behavior.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Local overlap: One process starts a second execution while its first is still running.
  • Cross-replica overlap: Two or more application instances independently start work that is intended to have one active runner.

A process-local guard such as a SemaphoreSlim, lock, or static flag can address the first case if it is applied correctly. It cannot coordinate other processes or machines. To prevent cross-replica overlap, every potential runner needs to use a shared coordination mechanism or a scheduler/platform feature that provides the required concurrency behavior.

Choose a coordination model that fits the job

Microsoft’s Azure Architecture Center cautions that multiple instances of a background job can compete for shared resources such as databases and storage, affecting contention, availability, and data integrity. It discusses approaches including pessimistic locking, singleton execution, queues, and platform-specific concurrency controls; each involves tradeoffs. See Microsoft’s background-job guidance.

Approach Coordination scope What it suits Important tradeoff
Process-local guard One process only Preventing a timer callback from re-entering within a single host Does not stop another replica from running the same work.
Singleton worker or scheduled runner One designated runner, if deployment and platform configuration enforce it A job that must have one active runner and does not require parallel execution Reduces the redundancy and throughput available from multiple instances; verify how failover and restart are handled.
Shared lock or lease Processes that use the same coordination store Allowing multiple instances to compete while limiting active ownership Requires explicit rules for atomic acquisition, ownership, expiry, renewal, crashes, and paused or stale owners.
Queue with competing consumers Consumers draw discrete tasks from a shared queue Request-triggered or otherwise separable units of work that can be distributed and retried Persistence, retries, duplicate delivery, idempotency, queue capacity, and downstream limits all matter.
Scheduler or platform concurrency control As provided by the selected platform and its configuration Scheduled jobs where the platform’s documented behavior matches the deployment need Semantics are platform-specific; validate the actual configuration rather than assuming that scheduling itself guarantees exclusivity.

How to prevent overlapping executions

For overlap inside one host

Choose a local mechanism that makes the callback wait, skip, or otherwise handle an execution already in progress. The correct behavior depends on the job: waiting may create a backlog, while skipping may be acceptable for refresh work but not for required transactions. A local guard only protects callers that share that process and guard.

For one active scheduled runner across replicas

Use a scheduler or platform feature with documented cross-instance concurrency semantics. Microsoft cites Azure Functions timer triggers, which use a distributed lock, and Kubernetes CronJobs with concurrencyPolicy: Forbid as examples of concurrency controls. Confirm the relevant behavior and settings for the exact hosting environment; these examples do not mean that an ASP.NET Core hosted service automatically receives the same protection.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For request-triggered discrete work

Represent each unit of work as a queue message and let consumers claim tasks. This can distribute load and separate request handling from job execution, but it does not eliminate the need to design for retries and recovery. Make side effects idempotent where possible, and check that queue throughput and downstream services can sustain the consumer rate.

For a shared database lock or lease

A lock or lease is only as reliable as its ownership and failure rules. Before relying on one, specify how acquisition is atomic, how an owner proves it still holds the lock, how expiration and renewal work, what happens after a process crash, and how a paused worker is prevented from continuing after its lease has expired. The general guidance to use locking does not establish the correct implementation for a particular database or library; consult that system’s primary documentation before choosing code or configuration.

For a background-job framework

Hangfire documents distributed locks as part of coordination when running multiple servers. Its documentation describes multiple server instances, and its feature overview also identifies distributed locking. Evaluate its storage and operational model against the system you already run; the existence of distributed locks is not a guarantee of exactly-once completion for every job or external side effect.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Design for retries, crashes, and duplicate effects

Exclusivity and successful completion are separate guarantees. A lock can reduce simultaneous execution, but it cannot by itself ensure exactly-once behavior if a process crashes after making an external change and before recording completion. Likewise, queues and schedulers can involve retries or recovery paths that make repeat execution part of the failure model.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 2
SaleBestseller No. 5
Programming ASP.NET Core (Developer Reference)
Programming ASP.NET Core (Developer Reference)
Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap; ASP.NET Core code for implementing business logic and data transformations
$24.99
Best Value
Sale
Programming ASP.NET Core (Developer Reference)
  • Applying all key ASP.NET Core components, including MVC for HTML generation, .NET Core, EF Core, ASP.NET Identity, dependency injection, and more
  • Integrating ASP.NET Core with leading client-side frameworks, including Bootstrap
  • ASP.NET Core code for implementing business logic and data transformations
  • Handling configuration, routing, controllers, views, and common tasks (including posting forms and presenting data)
  • Performing complementary tasks: error handling, logging, application design, authentication, localization, and more
  • Make operations idempotent where possible, so a retry does not apply the same effect twice.
  • Define which failures should trigger a retry and how repeated failures are surfaced or recovered.
  • For leases, address expiration and stale ownership rather than treating acquisition as permanent proof that a worker remains active.
  • Account for shared-store limits and downstream bottlenecks; adding consumers or replicas can increase competition rather than useful throughput.
  • Choose persistence and restart behavior that match the cost of losing or repeating a task.

A practical decision path

  1. Determine the scope. If only callbacks in one process can overlap, use a local guard and select whether overlapping work should wait or be skipped. If replicas must coordinate, a local lock is insufficient.
  2. Classify the work. For discrete tasks triggered by requests, consider a persistent queue with competing consumers. For a scheduled task requiring one active runner, look for a scheduler or platform concurrency feature documented for your deployment.
  3. Specify failure behavior. Decide how the system handles crashes, retries, duplicate side effects, lease expiration, and recovery before selecting a lock, queue, or singleton deployment.
  4. Check the bottleneck and operational cost. Consider the limits of the shared database, queue, and downstream services, as well as the work required to operate the chosen coordination mechanism.
  5. Validate the guarantee at the right boundary. Confirm that the selected scheduler, framework, store, or deployment setting coordinates all relevant instances—not just threads in one process—and test the failure cases that matter to the job.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.