Skip to content

Bump the nuget-minor-patch group with 8 updates - #207

Closed
dependabot[bot] wants to merge 2 commits into
mainfrom
dependabot/nuget/nuget-minor-patch-70fa6db961
Closed

dependabot[bot] wants to merge 2 commits into
mainfrom
dependabot/nuget/nuget-minor-patch-70fa6db961

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Updated Aspire.Hosting.AppHost from 13.5.4 to 13.6.0.

Release notes

Sourced from Aspire.Hosting.AppHost's releases.

13.6.0

Aspire 13.6.0

Aspire 13.6 brings persistent application history, a refreshed and more interactive dashboard, first-party Java and Rust hosting, and new Azure deployment options. Coordinated .NET builds, portable volume paths, sharper CLI workflows, and more capable editor tooling make it easier to build, debug, and deploy applications across languages.

Highlights

  • 🗃️ Persistent, refreshed dashboard — SQLite-backed telemetry and resource snapshots let you revisit up to ten application runs, with read-only access to completed runs and default retention limits of 100,000 console log messages, structured logs, and traces each. The dashboard now ships as Native AOT and adopts Fluent UI v5 with a collapsible navigation rail.
  • 🖥️ AppHost-owned terminals and database REPLs — Experimental terminal APIs let AppHosts create interactive sessions in a dashboard dock, dialog, or separate window. Opt-in WithRepl() commands open bundled clients for PostgreSQL, MySQL, MongoDB, SQL Server, Redis, and Valkey, while aspire terminal ps and aspire terminal tape play support discovery and repeatable terminal interactions.
  • 🌐 First-party Java and Rust hosting — New Aspire.Hosting.Java and Aspire.Hosting.Rust packages bring Maven, Gradle, Spring Boot, Quarkus, and Cargo applications into the app model, with generated container builds and VS Code debugging. These integrations build on work that originated in the Aspire Community Toolkit.
  • 🛠️ More flexible AppHosts — The prerelease Aspire.Hosting.Dotnet integration coordinates compatible projects into shared restore and build groups and supports .NET SDK container publishing. Portable volume-path environment variables work across local execution and deployment, while TypeScript AppHosts gain standard appsettings.json configuration and Deno runtime support.
  • ⌨️ Sharper CLI workflows — Select launch profiles with aspire run and aspire start, update repository-local CLI manifests with aspire update, create file-based C# AppHosts with aspire init --language csharp --file-based, and export TypeScript API data with aspire sdk export. Terminal commands no longer need a feature flag, Linux certificate trust includes Firefox NSS databases, and aspire stop --force --volumes adds explicit cleanup of Aspire-owned volumes.
  • 💻 More capable VS Code tooling — Coding agents can start and stop AppHosts through the extension, and the Aspire pane exposes deploy, publish, and pipeline actions. Multi-root discovery, worktree-scoped lifecycle operations, preserved launch arguments, clearer debug logs, and missing-debugger guidance make complex workspaces more predictable.
  • ☁️ New Azure options in preview — Azure Connector Namespace models external-service connections and managed MCP server configurations. Azure Container Apps Sandboxes adds isolated sandbox deployments with configurable resource tiers and lifecycle policies, while Azure Container Apps Express offers a simplified environment option for rapid provisioning.
  • ☸️ More expressive, reliable deployments — Experimental Azure Provisioning SDK proxies let polyglot AppHosts customize infrastructure. Deployment state is isolated under ASPIRE_HOME, Kubernetes preserves inherited hostnames and embedded parameter values, and AKS gains persistent-volume provisioning and more reliable cleanup.
  • 🔌 Expanded integrations — Experimental Deno hosting and MongoDB replica sets join Foundry Toolboxes, remote Foundry Local endpoints, Blazor WebAssembly debugging, and configurable Dev Tunnel expiration. Azure Cosmos DB and AI Inference client integrations gain health checks, and the vNext Cosmos DB emulator sends its own telemetry to the dashboard.

⚠️ Breaking changes

Notable changes include automatic TLS for local MongoDB servers when a certificate is available, the Linux-based vNext Cosmos DB emulator becoming the default, new Azure Front Door origin names that can require cleanup of existing origins, portable connection-string environment-variable aliases on stricter deployment targets, and experimental terminal types moving from Aspire.Hosting.Terminals to Aspire.Hosting.ApplicationModel.

See the full list and migration guidance in the Aspire 13.6 breaking changes.

📖 Learn more

For complete details, examples, migration guidance, and everything new in this release, read What's new in Aspire 13.6.

Thank you to all the community contributors who helped make Aspire 13.6 possible! 💜


Full Changelog: v13.5.4...v13.6.0

Full commit: 56f3e9c0d216c0c7069dabb49dd0464e4827744f

Commits viewable in compare view.

Updated Aspire.Hosting.PostgreSQL from 13.5.4 to 13.6.0.

Release notes

Sourced from Aspire.Hosting.PostgreSQL's releases.

13.6.0

Aspire 13.6.0

Aspire 13.6 brings persistent application history, a refreshed and more interactive dashboard, first-party Java and Rust hosting, and new Azure deployment options. Coordinated .NET builds, portable volume paths, sharper CLI workflows, and more capable editor tooling make it easier to build, debug, and deploy applications across languages.

Highlights

  • 🗃️ Persistent, refreshed dashboard — SQLite-backed telemetry and resource snapshots let you revisit up to ten application runs, with read-only access to completed runs and default retention limits of 100,000 console log messages, structured logs, and traces each. The dashboard now ships as Native AOT and adopts Fluent UI v5 with a collapsible navigation rail.
  • 🖥️ AppHost-owned terminals and database REPLs — Experimental terminal APIs let AppHosts create interactive sessions in a dashboard dock, dialog, or separate window. Opt-in WithRepl() commands open bundled clients for PostgreSQL, MySQL, MongoDB, SQL Server, Redis, and Valkey, while aspire terminal ps and aspire terminal tape play support discovery and repeatable terminal interactions.
  • 🌐 First-party Java and Rust hosting — New Aspire.Hosting.Java and Aspire.Hosting.Rust packages bring Maven, Gradle, Spring Boot, Quarkus, and Cargo applications into the app model, with generated container builds and VS Code debugging. These integrations build on work that originated in the Aspire Community Toolkit.
  • 🛠️ More flexible AppHosts — The prerelease Aspire.Hosting.Dotnet integration coordinates compatible projects into shared restore and build groups and supports .NET SDK container publishing. Portable volume-path environment variables work across local execution and deployment, while TypeScript AppHosts gain standard appsettings.json configuration and Deno runtime support.
  • ⌨️ Sharper CLI workflows — Select launch profiles with aspire run and aspire start, update repository-local CLI manifests with aspire update, create file-based C# AppHosts with aspire init --language csharp --file-based, and export TypeScript API data with aspire sdk export. Terminal commands no longer need a feature flag, Linux certificate trust includes Firefox NSS databases, and aspire stop --force --volumes adds explicit cleanup of Aspire-owned volumes.
  • 💻 More capable VS Code tooling — Coding agents can start and stop AppHosts through the extension, and the Aspire pane exposes deploy, publish, and pipeline actions. Multi-root discovery, worktree-scoped lifecycle operations, preserved launch arguments, clearer debug logs, and missing-debugger guidance make complex workspaces more predictable.
  • ☁️ New Azure options in preview — Azure Connector Namespace models external-service connections and managed MCP server configurations. Azure Container Apps Sandboxes adds isolated sandbox deployments with configurable resource tiers and lifecycle policies, while Azure Container Apps Express offers a simplified environment option for rapid provisioning.
  • ☸️ More expressive, reliable deployments — Experimental Azure Provisioning SDK proxies let polyglot AppHosts customize infrastructure. Deployment state is isolated under ASPIRE_HOME, Kubernetes preserves inherited hostnames and embedded parameter values, and AKS gains persistent-volume provisioning and more reliable cleanup.
  • 🔌 Expanded integrations — Experimental Deno hosting and MongoDB replica sets join Foundry Toolboxes, remote Foundry Local endpoints, Blazor WebAssembly debugging, and configurable Dev Tunnel expiration. Azure Cosmos DB and AI Inference client integrations gain health checks, and the vNext Cosmos DB emulator sends its own telemetry to the dashboard.

⚠️ Breaking changes

Notable changes include automatic TLS for local MongoDB servers when a certificate is available, the Linux-based vNext Cosmos DB emulator becoming the default, new Azure Front Door origin names that can require cleanup of existing origins, portable connection-string environment-variable aliases on stricter deployment targets, and experimental terminal types moving from Aspire.Hosting.Terminals to Aspire.Hosting.ApplicationModel.

See the full list and migration guidance in the Aspire 13.6 breaking changes.

📖 Learn more

For complete details, examples, migration guidance, and everything new in this release, read What's new in Aspire 13.6.

Thank you to all the community contributors who helped make Aspire 13.6 possible! 💜


Full Changelog: v13.5.4...v13.6.0

Full commit: 56f3e9c0d216c0c7069dabb49dd0464e4827744f

Commits viewable in compare view.

Updated Aspire.Hosting.Testing from 13.5.4 to 13.6.0.

Release notes

Sourced from Aspire.Hosting.Testing's releases.

13.6.0

Aspire 13.6.0

Aspire 13.6 brings persistent application history, a refreshed and more interactive dashboard, first-party Java and Rust hosting, and new Azure deployment options. Coordinated .NET builds, portable volume paths, sharper CLI workflows, and more capable editor tooling make it easier to build, debug, and deploy applications across languages.

Highlights

  • 🗃️ Persistent, refreshed dashboard — SQLite-backed telemetry and resource snapshots let you revisit up to ten application runs, with read-only access to completed runs and default retention limits of 100,000 console log messages, structured logs, and traces each. The dashboard now ships as Native AOT and adopts Fluent UI v5 with a collapsible navigation rail.
  • 🖥️ AppHost-owned terminals and database REPLs — Experimental terminal APIs let AppHosts create interactive sessions in a dashboard dock, dialog, or separate window. Opt-in WithRepl() commands open bundled clients for PostgreSQL, MySQL, MongoDB, SQL Server, Redis, and Valkey, while aspire terminal ps and aspire terminal tape play support discovery and repeatable terminal interactions.
  • 🌐 First-party Java and Rust hosting — New Aspire.Hosting.Java and Aspire.Hosting.Rust packages bring Maven, Gradle, Spring Boot, Quarkus, and Cargo applications into the app model, with generated container builds and VS Code debugging. These integrations build on work that originated in the Aspire Community Toolkit.
  • 🛠️ More flexible AppHosts — The prerelease Aspire.Hosting.Dotnet integration coordinates compatible projects into shared restore and build groups and supports .NET SDK container publishing. Portable volume-path environment variables work across local execution and deployment, while TypeScript AppHosts gain standard appsettings.json configuration and Deno runtime support.
  • ⌨️ Sharper CLI workflows — Select launch profiles with aspire run and aspire start, update repository-local CLI manifests with aspire update, create file-based C# AppHosts with aspire init --language csharp --file-based, and export TypeScript API data with aspire sdk export. Terminal commands no longer need a feature flag, Linux certificate trust includes Firefox NSS databases, and aspire stop --force --volumes adds explicit cleanup of Aspire-owned volumes.
  • 💻 More capable VS Code tooling — Coding agents can start and stop AppHosts through the extension, and the Aspire pane exposes deploy, publish, and pipeline actions. Multi-root discovery, worktree-scoped lifecycle operations, preserved launch arguments, clearer debug logs, and missing-debugger guidance make complex workspaces more predictable.
  • ☁️ New Azure options in preview — Azure Connector Namespace models external-service connections and managed MCP server configurations. Azure Container Apps Sandboxes adds isolated sandbox deployments with configurable resource tiers and lifecycle policies, while Azure Container Apps Express offers a simplified environment option for rapid provisioning.
  • ☸️ More expressive, reliable deployments — Experimental Azure Provisioning SDK proxies let polyglot AppHosts customize infrastructure. Deployment state is isolated under ASPIRE_HOME, Kubernetes preserves inherited hostnames and embedded parameter values, and AKS gains persistent-volume provisioning and more reliable cleanup.
  • 🔌 Expanded integrations — Experimental Deno hosting and MongoDB replica sets join Foundry Toolboxes, remote Foundry Local endpoints, Blazor WebAssembly debugging, and configurable Dev Tunnel expiration. Azure Cosmos DB and AI Inference client integrations gain health checks, and the vNext Cosmos DB emulator sends its own telemetry to the dashboard.

⚠️ Breaking changes

Notable changes include automatic TLS for local MongoDB servers when a certificate is available, the Linux-based vNext Cosmos DB emulator becoming the default, new Azure Front Door origin names that can require cleanup of existing origins, portable connection-string environment-variable aliases on stricter deployment targets, and experimental terminal types moving from Aspire.Hosting.Terminals to Aspire.Hosting.ApplicationModel.

See the full list and migration guidance in the Aspire 13.6 breaking changes.

📖 Learn more

For complete details, examples, migration guidance, and everything new in this release, read What's new in Aspire 13.6.

Thank you to all the community contributors who helped make Aspire 13.6 possible! 💜


Full Changelog: v13.5.4...v13.6.0

Full commit: 56f3e9c0d216c0c7069dabb49dd0464e4827744f

Commits viewable in compare view.

Updated coverlet.collector from 10.0.1 to 10.1.0.

Release notes

Sourced from coverlet.collector's releases.

10.1.0

Improvements

  • Publish Microsoft.Testing.Platform coverage messages from coverlet.MTP #​2019
  • Implement dynamic exclusion filters for assemblies (Coverlet.MTP) #​1946
  • Replace legacy .sln files with modern .slnx format #​1966
  • coverlet.console: add trace diagnostics and actionable warnings for instrumentation/hit/empty-result failures #​2005
  • Relax auto-property skip logic and improve coverage for records #​1941

Fixed

  • Fix coverlet.MTP does not collect coverage on the .NET Framework portion of a large project #​1980 #​1967
  • Fix Regression in branch coverage for lambda expressions #​1938
  • Fix When using "is" with "or" in pattern matching, branch coverage is lower than normal #​1979
  • Fix silent zero coverage on .NET Framework since 8.0.0 #​1985 by @​tobiwae
  • Fix Race condition between ProcessExit hit-file write and out-of-proc coverage read causes EndOfStreamException #​1987 #​1988 by @​bkoelman
  • Fix Regression TypeInitializationException when targeting .NET Framework - Could not load type 'System.Collections.Concurrent.ConcurrentBag #​2010
  • Fix use --config-file CLI arg in coverlet.MTP #​2030 by alexthornton1
  • Fix silently empty coverage for shared-framework assemblies missing from compileLibraries #​2032 by @​Eljees

Diff between 10.0.1 and 10.1.0

Commits viewable in compare view.

Updated Marten from 9.39.0 to 9.43.0.

Release notes

Sourced from Marten's releases.

9.43.0

Bumps the JasperFx family to 2.78.0 and lands four issues, one of them a data-corruption fix worth reading even if you skip the rest.

Fixes

#​5539 — a zero-event quick append could permanently wedge a stream. mt_quick_append_events called with zero events read mt_streams.version without a lock and ended with a blind write-back, so under READ COMMITTED it could overwrite a concurrent appender's version and leave the stream row below its own events. Every later append then computed a version that already existed and failed on pk_mt_events_stream_and_version — permanently, with no recovery short of repairing the row by hand. A non-empty append could never do this: its first insert collides on that same primary key and rolls back, which is why only the empty call was exposed. The write-back is now skipped when nothing was appended, and uses greatest() so it can never lower a version whoever calls it.

Field context: a production console on 9.32.0 sat at mt_streams.version 608676 against max(mt_events.version) 608678 for 42 days, roughly 28 failed appends a minute. If you have a stream failing every append on that constraint, this is likely why.

#​5541 — ShardState.LastUpdated, liveness rather than progress. Sequence cannot distinguish caught up with nothing new from no longer maintained: both hold the same number forever. The progression row's last_updated now reaches ShardState and ProjectionProgressRow, and — the part that needed a product change — an idle high-water cycle now restamps the HighWaterMark row. Previously an idle cycle issued no SQL at all, so that stamp froze at the last real mark advance and read as "abandoned weeks ago" on a perfectly healthy store. The restamp never touches last_seq_id, so it cannot nudge the mark.

Diagnostics surface (monitoring consoles)

#​5543 — IDocumentStoreDiagnostics adopts the defined contract (jasperfx#​870). Five behaviours were previously "whatever the store happened to do", and Marten was on the wrong side of all five:

Before Now
Soft deletes returned as live excluded unless asked; a load by id returns the row flagged
Hierarchies every sub-class in the table filtered to the requested type; each row reports its own
Missing tenant all tenants the default tenant
"" tenant a tenant literally named "" the default tenant
Ids id::text = @​id converted to the stored identity type — uses the PK index, matches an upper-case Guid

Also: LoadDocumentAsync returning StoredDocument with metadata, populated DocumentQueryResult.Documents, a new IDocumentStoreDiagnosticsWriter (save-from-JSON and delete through a normal session, with an expected-version guard), DocumentStoreUsage.SerializerCasing, and structured index / duplicated-field descriptors. Query criteria Marten cannot yet translate are refused rather than silently ignored.

#​5544 — DocumentQueryOptions.AllTenants. The explicit replacement for the all-tenants read that #​5543 removed. Conjoined tenancy reads every tenant, ordered by tenant then id so paging cannot repeat a row. A store spreading tenants across databases refuses rather than quietly returning only the default tenant's rows.

⚠️ Behaviour change for diagnostics consumers: a null or blank TenantId now means the default tenant, not every tenant. If you relied on the old behaviour, set AllTenants = true.

Also

#​5542 — asynchronous aggregate events are ordered by stream sequence.

Internals: a diagnostic document read now resolves a tenant's database through TryFindDatabase rather than FindOrCreateDatabase, so asking a read-only question about an unknown tenant can no longer provision that tenant.

9.42.0

Mostly fixes, and two of them only became visible once the one underneath them was gone. Nothing here requires action on upgrade unless you use IsolationLevel.RepeatableRead or above, or batch a FetchForWriting for an Async-snapshot aggregate.

Migrations settle again on a long schema name

#​5536. ApplyAllDatabaseChangesOnStartup() against an already-migrated schema could fail with:

42710: constraint "fkey_mt_events_stream_id" for relation "mt_events" already exists

The foreign key was not the problem. PostgreSQL truncates identifiers at 63 characters, so a longer DatabaseSchemaName was stored truncated while Marten went on querying for the name it had asked for — found none of its objects, concluded they were all missing, and re-issued DDL the server resolved against the truncated schema, where they already existed. The first apply passed and the second failed, with an error pointing nowhere near the schema name.

DatabaseSchemaName is now truncated to 63 characters so the two sides agree. This does not move anyone's data: the server was already truncating it, and Marten now simply uses the name the server actually stored. Two distinct long names sharing their first 63 characters still collide, exactly as they already do in PostgreSQL.

The apply-changes lock waits long enough to be useful

#​5529. The advisory lock guarding startup migrations retried on a fixed 50 / 100 / 250ms ladder — about 400ms to win it. That is ample for the multi-replica rolling deploy it was designed for, where the loser only has to outlast a peer's finished migration. It is not enough when more than one store shares a database inside one host, where the loser has to outlast a migration that is still running: it failed startup, and the message's own advice (ResourceMigrationFailureMode.ContinueOnFailures) would have started the application against a half-migrated schema.

New knob, defaulting to 10 seconds:

opts.ApplyChangesLockTimeout = 30.Seconds();   // many stores on one database, or a large schema

This was held back until it could be measured. While weasel#​659 was unfixed the lock was stranded by any migration that threw, and a longer wait provably changed nothing. Weasel 9.37.0 releases it on the failure path, and only then did the residue show up as a genuine race worth budgeting for.

⚠️ No write retry from RepeatableRead upwards

#​5528, completing what 9.41.0 started. Marten's retry replays the operations it has already computed, not the application code that computed them — and from RepeatableRead up, the session's transaction is pinned to one snapshot. So any successful replay commits decisions derived from a snapshot that no longer exists. That is exactly the silent lost update 9.41.0 fixed for 40001, and 40P01 (deadlock) had the same flaw for the same structural reason.

The write-retry pipeline is now skipped entirely for RepeatableRead, Serializable and Snapshot. This is deliberately broader than refusing those two SQLSTATEs: class 53, 55, 57P03 and 58 all abort a snapshot-holding transaction too, so singling out class 40 would have left the identical hole open one error code over.

If you use those isolation levels, expect to see failures surface that were previously retried away. Handle them by re-reading and recomputing — the only place a snapshot conflict can be resolved. ReadCommitted is the default and is unchanged: it takes a fresh snapshot per statement, so replaying precomputed SQL still means what it meant, and every existing application keeps full retry behaviour.

A batched Async-snapshot FetchForWriting says what it needs

#​5535. For an aggregate projected with ProjectionLifecycle.Async, the non-exclusive FetchForWriting wraps its reads in begin transaction isolation level repeatable read read only … end so they share one snapshot — and PostgreSQL accepts that only as the first statement in a transaction. Enlisted after anything else in a batch, it failed at Execute() with 25001: SET TRANSACTION ISOLATION LEVEL must be called before any query, naming an isolation level the caller never mentioned and saying nothing about ordering. Nothing about CreateBatchQuery() hints that one of its members has to go first.

It is now refused at the enlisting call, with a message that names the aggregate and the constraint. The position that worked still works.

Dependencies

Weasel 9.37.0, whose weasel#​659 is the reason most of #​5529 went away: ApplyAllConfiguredChangesToDatabaseAsync released the global migration lock only on its success paths, so a migration that threw left it held and locked every other replica out of migrating — while the node that stranded it reported nothing. Disposing the connection was not enough, because Npgsql resets a pooled connection when it is next used rather than when it is returned, so the lock outlived the apply for as long as that connection sat idle.

Also in 9.37.0, and worth reading if you use them: SQL Server 2025 JSON indexes are no longer emitted as DROP INDEX on every apply (weasel#​661), Oracle descending indexes and co-migrated views settle (weasel#​660), TableDelta.HasChanges() answers instead of throwing for a table that does not exist yet (weasel#​658), and the reconnection loop no longer abandons a connection per attempt (weasel#​664).

Housekeeping

DISABLE_TEST_PARALLELIZATION is gone from the CI workflow and the contributor docs. Nothing ever read it, so it looked like a control and was not one — including to us, while diagnosing #​5529. Test parallelisation is disabled by CollectionBehavior in AssemblyInfo.cs, and both files now say where to change it.

9.41.0

Upgrade if you use IsolationLevel.Serializable. The first item below is a silent lost update, and it has been present since the write-retry pipeline shipped. The two items after it change behaviour you may be relying on.

🛑 Data integrity: Serializable sessions could silently lose an update

#​5528. A session opened with IsolationLevel.Serializable (or RepeatableRead) did not reliably protect against a lost update. PostgreSQL detected the write conflict correctly and Marten discarded the detection by retrying.

Two serializable sessions each load the same document at Amount = 100. One commits 100 - 500. The other should be refused with ConcurrentUpdateException; instead it committed 100 - 350 on top, and the first session's write was gone with no error raised anywhere. From the server's own log:

[14197] ERROR:  could not serialize access due to concurrent update
[14197] ROLLBACK
[14196] BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE    -- the replay
[14196] insert ... on conflict (id) do update ...         -- same values, same mt_version
[14196] COMMIT

WriteRetryClassifier (#​5262) listed 40001 serialization_failure as safe to replay, on the reasoning that the server had rolled the transaction back and said so — which is true, and turned out to be necessary but not sufficient. A replay re-issues the operations already computed, rather than re-running the application code that produced them, and a serialization failure means precisely that the snapshot those operations were derived from is no longer a valid basis for them. The replay opens a new transaction with a fresh snapshot, so the conflict is gone and the write lands.

40001 is now never replayed and surfaces as ConcurrentUpdateException, which is what Marten already translated it to. If you opted into Serializable you should expect to start seeing that exception — handle it by re-reading and recomputing, which is the only place the conflict can be resolved. Nothing inside Marten requests these isolation levels, so the async daemon and every default ReadCommitted session are unaffected.

40P01 deadlock_detected stays retryable deliberately: a deadlock aborts over lock ordering rather than a rejected snapshot, and replaying it is the textbook remedy at ReadCommitted. A deadlock retry under Serializable replays stale-snapshot work for the same structural reason, and the honest fix needs the isolation level plumbed into the classifier — recorded as a known gap rather than guessed at.

This went unnoticed because the test that catches it lives in StressTests, which has had no CI job since 2026-08-08.

⚠️ Behaviour change: the HotCold leadership lock is session-scoped again

#​5526. Events.UseAdvisoryLockTransaction now defaults to false, so HotCold leader election uses a session-scoped pg_try_advisory_lock rather than a transaction-scoped pg_try_advisory_xact_lock. The transaction-scoped lock had been the default since 8.37.3 (April 2026).

The reason is what the transaction-scoped lock costs while it works: the leader holds an open transaction for as long as it holds leadership, which on a long-lived daemon is an indefinitely long-running transaction sitting on the connection — with everything that implies for vacuum and for anything watching transaction age.

The transaction-scoped lock is still the better fit behind PgBouncer in transaction pooling mode, which can hand a session-scoped lock's server connection to another client. If that is your deployment, opt back in explicitly:

builder.Services.AddMarten(opts =>
{
    opts.Connection(connectionString);
    opts.Events.UseAdvisoryLockTransaction = true;
})
.AddAsyncDaemon(DaemonMode.HotCold);

⚠️ Breaking: DefaultTenantUsageDisabledException is no longer a MartenException

#​5514. Marten.Exceptions.DefaultTenantUsageDisabledException now derives from JasperFx.Events.DefaultTenantUsageDisabledException.

JasperFx.Events carries this exception so that code can handle the refusal once across Critter Stack stores, and its own contract is that stores subclass it. Polecat did; Marten did not. The consequence was not an error anywhere — a store-agnostic catch (JasperFx.Events.DefaultTenantUsageDisabledException) compiled, read as if it handled the refusal, and let it through unhandled on Marten only. That is the failure mode this fixes.

Multiple inheritance is not available, so it is one base or the other, and the cross-store catch was judged worth more than the marker base. If you rely on a broad catch (MartenException) to handle this refusal, it will no longer be caught — catch the exception itself, or the JasperFx base. The message is unchanged, including the single-argument overload's behaviour of appending to the standard prefix.

Also gone with the reparenting: the protected (SerializationInfo, StreamingContext) constructor, because the JasperFx base declares none to chain to. Binary serialization of exceptions has been obsolete since .NET 8.
... (truncated)

9.40.0

Minor rather than patch for one reason: the source-generated DetermineAction now decides one action per batch rather than per event. See the behaviour change below before upgrading if you archive streams from a projection.

⚠️ Behaviour changes

Archiving projections: one action per batch, not per event (JasperFx/jasperfx#​889, via the JasperFx 2.75.2 bump). The source-generated DetermineAction used to decide per event; it now decides once per batch. This changes what an archiving projection does when a single batch mixes an archive with later events for the same stream. StreamArchivingCompliance gained facts for it and Marten passes them, but if you depend on the old per-event evaluation, test before upgrading.

TenantIdStyle is now applied where the tenant id is stamped and keyed, not only where a tenant is resolved (#​5516). Under ForceLowerCase, these three previously wrote or matched the raw id:

  • BulkInsertEventsAsync / BulkInsertEventStreamAsync resolved the right database or partition and then stamped the raw id on every mt_streams / mt_events row — rows invisible to any normalised read under conjoined tenancy, and the wrong key inside the right partition under UseTenantPartitionedEvents.
  • TenantIsOneOf(...) filtered on the raw values, so a mixed-case id matched nothing.
  • DeleteAllTenantDataAsync used the raw id as its DELETE ... WHERE tenant_id = :p parameter, so it matched no rows and reported success — the one to look at hardest, since callers are usually honouring an erasure request.

If you have been calling these with mixed-case tenant ids, data already written under the raw casing stays where it is; it will not be found by a normalised read. ForTenant(string) also now normalises its nested-session cache key, which makes ForTenant("RED") and ForTenant("red") one session rather than two.

Event store

  • IEventStore.OpenReadOnlyEventStore(tenantId) is implemented (#​5513). With Advanced.DefaultTenantUsageEnabled = false — the automatic state once database-per-tenant tenancy is configured — the entire IReadOnlyEventStore surface was unreachable, because the tenant-less overload opens the store's default session and is refused before any tenant scope applies. That is why QueryStreamStates(tenantId)'s own parameter could not work around it. A null tenant keeps the previous store-global behaviour.
  • Diagnostic event-store reads answer "no results" instead of throwing (#​5511, #​5512), decided from the database rather than from configuration.
  • Progression and dead-letter reads answer nothing for an event store nothing provisions (#​5509, #​5510).

Diagnosing a missing source-generated dispatcher

The JasperFx 2.75.2 bump (#​5518) carries three changes that came out of #​5495, where a user's aggregates compiled with no dispatcher and the runtime message could not tell them why:

  • The generator now leaves [assembly: JasperFxSourceGeneratorApplied] in every assembly it processes, so "the generator never ran in that assembly" — a csproj problem — is distinguishable at runtime from "the generator ran and declined your type" — a code-shape problem. The exception says which.
  • Two copies of the generator in one compilation no longer collide with CS0433. This happens when a project references the standalone JasperFx.Events.SourceGenerator package as well as Marten, which bundles it: both copies emit identical file paths and the file-scoped evolvers mangle to the same name. If you hit that error — recognisable because it names the same assembly on both sides — remove the standalone package reference; Marten already carries the analyzer.
  • Opt in to a build-time check with <JasperFxEventsRequireSourceGenerator>true</JasperFxEventsRequireSourceGenerator> on projects that declare aggregates, and a missing analyzer becomes build error JFXEVT900 rather than a failure at the first FetchForWriting.

Compliance coverage

Marten is now enrolled in DocumentConjoinedTenancyCompliance (#​5517) — the first shared document coverage of conjoined tenancy on any store — with all 10 facts running. ConjoinedEventTenancyCompliance goes from 16 passing with 2 skipped to 18 passing with none, the two skips having been waiting on the read-only overload above.

Two of these enrollments exposed that Marten's own commit-listener compliance facts had been passing vacuously — the harness never installed the listener the suites register, so "no phantom deletion was reported" was trivially true of a store reporting nothing at all. Fixed in the #​5518 bump; no product change was needed, and both halves of that fact now pass for real.

Dependencies

JasperFx 2.75.2 and Weasel 9.35.2.

Weasel 9.35.x is mostly EF Core and SQL Server work, plus weasel#​634: an exhausted DropSchema retry is now reported instead of returning success.

Docs

The bundled analyzer does flow transitively across a ProjectReference (#​5508) — the composite-configuration page claimed the opposite. The claim was true of the standalone analyzer package, which Marten sets PrivateAssets="all" on, but #​4557 bundles the analyzer DLL into Marten's own package and that copy flows.

9.39.1

What's Changed

Full Changelog: JasperFx/marten@V9.39.0...v9.39.1

Commits viewable in compare view.

Updated Marten.AspNetCore from 9.39.0 to 9.43.0.

Release notes

Sourced from Marten.AspNetCore's releases.

9.43.0

Bumps the JasperFx family to 2.78.0 and lands four issues, one of them a data-corruption fix worth reading even if you skip the rest.

Fixes

#​5539 — a zero-event quick append could permanently wedge a stream. mt_quick_append_events called with zero events read mt_streams.version without a lock and ended with a blind write-back, so under READ COMMITTED it could overwrite a concurrent appender's version and leave the stream row below its own events. Every later append then computed a version that already existed and failed on pk_mt_events_stream_and_version — permanently, with no recovery short of repairing the row by hand. A non-empty append could never do this: its first insert collides on that same primary key and rolls back, which is why only the empty call was exposed. The write-back is now skipped when nothing was appended, and uses greatest() so it can never lower a version whoever calls it.

Field context: a production console on 9.32.0 sat at mt_streams.version 608676 against max(mt_events.version) 608678 for 42 days, roughly 28 failed appends a minute. If you have a stream failing every append on that constraint, this is likely why.

#​5541 — ShardState.LastUpdated, liveness rather than progress. Sequence cannot distinguish caught up with nothing new from no longer maintained: both hold the same number forever. The progression row's last_updated now reaches ShardState and ProjectionProgressRow, and — the part that needed a product change — an idle high-water cycle now restamps the HighWaterMark row. Previously an idle cycle issued no SQL at all, so that stamp froze at the last real mark advance and read as "abandoned weeks ago" on a perfectly healthy store. The restamp never touches last_seq_id, so it cannot nudge the mark.

Diagnostics surface (monitoring consoles)

#​5543 — IDocumentStoreDiagnostics adopts the defined contract (jasperfx#​870). Five behaviours were previously "whatever the store happened to do", and Marten was on the wrong side of all five:

Before Now
Soft deletes returned as live excluded unless asked; a load by id returns the row flagged
Hierarchies every sub-class in the table filtered to the requested type; each row reports its own
Missing tenant all tenants the default tenant
"" tenant a tenant literally named "" the default tenant
Ids id::text = @​id converted to the stored identity type — uses the PK index, matches an upper-case Guid

Also: LoadDocumentAsync returning StoredDocument with metadata, populated DocumentQueryResult.Documents, a new IDocumentStoreDiagnosticsWriter (save-from-JSON and delete through a normal session, with an expected-version guard), DocumentStoreUsage.SerializerCasing, and structured index / duplicated-field descriptors. Query criteria Marten cannot yet translate are refused rather than silently ignored.

#​5544 — DocumentQueryOptions.AllTenants. The explicit replacement for the all-tenants read that #​5543 removed. Conjoined tenancy reads every tenant, ordered by tenant then id so paging cannot repeat a row. A store spreading tenants across databases refuses rather than quietly returning only the default tenant's rows.

⚠️ Behaviour change for diagnostics consumers: a null or blank TenantId now means the default tenant, not every tenant. If you relied on the old behaviour, set AllTenants = true.

Also

#​5542 — asynchronous aggregate events are ordered by stream sequence.

Internals: a diagnostic document read now resolves a tenant's database through TryFindDatabase rather than FindOrCreateDatabase, so asking a read-only question about an unknown tenant can no longer provision that tenant.

9.42.0

Mostly fixes, and two of them only became visible once the one underneath them was gone. Nothing here requires action on upgrade unless you use IsolationLevel.RepeatableRead or above, or batch a FetchForWriting for an Async-snapshot aggregate.

Migrations settle again on a long schema name

#​5536. ApplyAllDatabaseChangesOnStartup() against an already-migrated schema could fail with:

42710: constraint "fkey_mt_events_stream_id" for relation "mt_events" already exists

The foreign key was not the problem. PostgreSQL truncates identifiers at 63 characters, so a longer DatabaseSchemaName was stored truncated while Marten went on querying for the name it had asked for — found none of its objects, concluded they were all missing, and re-issued DDL the server resolved against the truncated schema, where they already existed. The first apply passed and the second failed, with an error pointing nowhere near the schema name.

DatabaseSchemaName is now truncated to 63 characters so the two sides agree. This does not move anyone's data: the server was already truncating it, and Marten now simply uses the name the server actually stored. Two distinct long names sharing their first 63 characters still collide, exactly as they already do in PostgreSQL.

The apply-changes lock waits long enough to be useful

#​5529. The advisory lock guarding startup migrations retried on a fixed 50 / 100 / 250ms ladder — about 400ms to win it. That is ample for the multi-replica rolling deploy it was designed for, where the loser only has to outlast a peer's finished migration. It is not enough when more than one store shares a database inside one host, where the loser has to outlast a migration that is still running: it failed startup, and the message's own advice (ResourceMigrationFailureMode.ContinueOnFailures) would have started the application against a half-migrated schema.

New knob, defaulting to 10 seconds:

opts.ApplyChangesLockTimeout = 30.Seconds();   // many stores on one database, or a large schema

This was held back until it could be measured. While weasel#​659 was unfixed the lock was stranded by any migration that threw, and a longer wait provably changed nothing. Weasel 9.37.0 releases it on the failure path, and only then did the residue show up as a genuine race worth budgeting for.

⚠️ No write retry from RepeatableRead upwards

#​5528, completing what 9.41.0 started. Marten's retry replays the operations it has already computed, not the application code that computed them — and from RepeatableRead up, the session's transaction is pinned to one snapshot. So any successful replay commits decisions derived from a snapshot that no longer exists. That is exactly the silent lost update 9.41.0 fixed for 40001, and 40P01 (deadlock) had the same flaw for the same structural reason.

The write-retry pipeline is now skipped entirely for RepeatableRead, Serializable and Snapshot. This is deliberately broader than refusing those two SQLSTATEs: class 53, 55, 57P03 and 58 all abort a snapshot-holding transaction too, so singling out class 40 would have left the identical hole open one error code over.

If you use those isolation levels, expect to see failures surface that were previously retried away. Handle them by re-reading and recomputing — the only place a snapshot conflict can be resolved. ReadCommitted is the default and is unchanged: it takes a fresh snapshot per statement, so replaying precomputed SQL still means what it meant, and every existing application keeps full retry behaviour.

A batched Async-snapshot FetchForWriting says what it needs

#​5535. For an aggregate projected with ProjectionLifecycle.Async, the non-exclusive FetchForWriting wraps its reads in begin transaction isolation level repeatable read read only … end so they share one snapshot — and PostgreSQL accepts that only as the first statement in a transaction. Enlisted after anything else in a batch, it failed at Execute() with 25001: SET TRANSACTION ISOLATION LEVEL must be called before any query, naming an isolation level the caller never mentioned and saying nothing about ordering. Nothing about CreateBatchQuery() hints that one of its members has to go first.

It is now refused at the enlisting call, with a message that names the aggregate and the constraint. The position that worked still works.

Dependencies

Weasel 9.37.0, whose weasel#​659 is the reason most of #​5529 went away: ApplyAllConfiguredChangesToDatabaseAsync released the global migration lock only on its success paths, so a migration that threw left it held and locked every other replica out of migrating — while the node that stranded it reported nothing. Disposing the connection was not enough, because Npgsql resets a pooled connection when it is next used rather than when it is returned, so the lock outlived the apply for as long as that connection sat idle.

Also in 9.37.0, and worth reading if you use them: SQL Server 2025 JSON indexes are no longer emitted as DROP INDEX on every apply (weasel#​661), Oracle descending indexes and co-migrated views settle (weasel#​660), TableDelta.HasChanges() answers instead of throwing for a table that does not exist yet (weasel#​658), and the reconnection loop no longer abandons a connection per attempt (weasel#​664).

Housekeeping

DISABLE_TEST_PARALLELIZATION is gone from the CI workflow and the contributor docs. Nothing ever read it, so it looked like a control and was not one — including to us, while diagnosing #​5529. Test parallelisation is disabled by CollectionBehavior in AssemblyInfo.cs, and both files now say where to change it.

9.41.0

Upgrade if you use IsolationLevel.Serializable. The first item below is a silent lost update, and it has been present since the write-retry pipeline shipped. The two items after it change behaviour you may be relying on.

🛑 Data integrity: Serializable sessions could silently lose an update

#​5528. A session opened with IsolationLevel.Serializable (or RepeatableRead) did not reliably protect against a lost update. PostgreSQL detected the write conflict correctly and Marten discarded the detection by retrying.

Two serializable sessions each load the same document at Amount = 100. One commits 100 - 500. The other should be refused with ConcurrentUpdateException; instead it committed 100 - 350 on top, and the first session's write was gone with no error raised anywhere. From the server's own log:

[14197] ERROR:  could not serialize access due to concurrent update
[14197] ROLLBACK
[14196] BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE    -- the replay
[14196] insert ... on conflict (id) do update ...         -- same values, same mt_version
[14196] COMMIT

WriteRetryClassifier (#​5262) listed 40001 serialization_failure as safe to replay, on the reasoning that the server had rolled the transaction back and said so — which is true, and turned out to be necessary but not sufficient. A replay re-issues the operations already computed, rather than re-running the application code that produced them, and a serialization failure means precisely that the snapshot those operations were derived from is no longer a valid basis for them. The replay opens a new transaction with a fresh snapshot, so the conflict is gone and the write lands.

40001 is now never replayed and surfaces as ConcurrentUpdateException, which is what Marten already translated it to. If you opted into Serializable you should expect to start seeing that exception — handle it by re-reading and recomputing, which is the only place the conflict can be resolved. Nothing inside Marten requests these isolation levels, so the async daemon and every default ReadCommitted session are unaffected.

40P01 deadlock_detected stays retryable deliberately: a deadlock aborts over lock ordering rather than a rejected snapshot, and replaying it is the textbook remedy at ReadCommitted. A deadlock retry under Serializable replays stale-snapshot work for the same structural reason, and the honest fix needs the isolation level plumbed into the classifier — recorded as a known gap rather than guessed at.

This went unnoticed because the test that catches it lives in StressTests, which has had no CI job since 2026-08-08.

⚠️ Behaviour change: the HotCold leadership lock is session-scoped again

#​5526. Events.UseAdvisoryLockTransaction now defaults to false, so HotCold leader election uses a session-scoped pg_try_advisory_lock rather than a transaction-scoped pg_try_advisory_xact_lock. The transaction-scoped lock had been the default since 8.37.3 (April 2026).

The reason is what the transaction-scoped lock costs while it works: the leader holds an open transaction for as long as it holds leadership, which on a long-lived daemon is an indefinitely long-running transaction sitting on the connection — with everything that implies for vacuum and for anything watching transaction age.

The transaction-scoped lock is still the better fit behind PgBouncer in transaction pooling mode, which can hand a session-scoped lock's server connection to another client. If that is your deployment, opt back in explicitly:

builder.Services.AddMarten(opts =>
{
    opts.Connection(connectionString);
    opts.Events.UseAdvisoryLockTransaction = true;
})
.AddAsyncDaemon(DaemonMode.HotCold);

⚠️ Breaking: DefaultTenantUsageDisabledException is no longer a MartenException

#​5514. Marten.Exceptions.DefaultTenantUsageDisabledException now derives from JasperFx.Events.DefaultTenantUsageDisabledException.

JasperFx.Events carries this exception so that code can handle the refusal once across Critter Stack stores, and its own contract is that stores subclass it. Polecat did; Marten did not. The consequence was not an error anywhere — a store-agnostic catch (JasperFx.Events.DefaultTenantUsageDisabledException) compiled, read as if it handled the refusal, and let it through unhandled on Marten only. That is the failure mode this fixes.

Multiple inheritance is not available, so it is one base or the other, and the cross-store catch was judged worth more than the marker base. If you rely on a broad catch (MartenException) to handle this refusal, it will no longer be caught — catch the exception itself, or the JasperFx base. The message is unchanged, including the single-argument overload's behaviour of appending to the standard prefix.

Also gone with the reparenting: the protected (SerializationInfo, StreamingContext) constructor, because the JasperFx base declares none to chain to. Binary serialization of exceptions has been obsolete since .NET 8.
... (truncated)

9.40.0

Minor rather than patch for one reason: the source-generated DetermineAction now decides one action per batch rather than per event. See the behaviour change below before upgrading if you archive streams from a projection.

⚠️ Behaviour changes

Archiving projections: one action per batch, not per event (JasperFx/jasperfx#​889, via the JasperFx 2.75.2 bump). The source-generated DetermineAction used to decide per event; it now decides once per batch. This changes what an archiving projection does when a single batch mixes an archive with later events for the same stream. StreamArchivingCompliance gained facts for it and Marten passes them, but if you depend on the old per-event evaluation, test before upgrading.

TenantIdStyle is now applied where the tenant id is stamped and keyed, not only where a tenant is resolved (#​5516). Under ForceLowerCase, these three previously wrote or matched the raw id:

  • BulkInsertEventsAsync / BulkInsertEventStreamAsync resolved the right database or partition and then stamped the raw id on every mt_streams / mt_events row — rows invisible to any normalised read under conjoined tenancy, and the wrong key inside the right partition under UseTenantPartitionedEvents.
  • TenantIsOneOf(...) filtered on the raw values, so a mixed-case id matched nothing.
  • DeleteAllTenantDataAsync used the raw id as its DELETE ... WHERE tenant_id = :p parameter, so it matched no rows and reported success — the one to look at hardest, since callers are usually honouring an erasure request.

If you have been calling these with mixed-case tenant ids, data already written under the raw casing stays where it is; it will not be found by a normalised read. ForTenant(string) also now normalises its nested-session cache key, which makes ForTenant("RED") and ForTenant("red") one session rather than two.

Event store

  • IEventStore.OpenReadOnlyEventStore(tenantId) is implemented (#​5513). With Advanced.DefaultTenantUsageEnabled = false — the automatic state once database-per-tenant tenancy is configured — the entire IReadOnlyEventStore surface was unreachable, because the tenant-less overload opens the store's default session and is refused before any tenant scope applies. That is why QueryStreamStates(tenantId)'s own parameter could not work around it. A null tenant keeps the previous store-global behaviour.
  • Diagnostic event-store reads answer "no results" instead of throwing (#​5511, #​5512), decided from the database rather than from configuration.
  • Progression and dead-letter reads answer nothing for an event store nothing provisions (#​5509, #​5510).

Diagnosing a missing source-generated dispatcher

The JasperFx 2.75.2 bump (#​5518) carries three changes that came out of #​5495, where a user's aggregates compiled with no dispatcher and the runtime message could not tell them why:

  • The generator now leaves [assembly: JasperFxSourceGeneratorApplied] in every assembly it processes, so "the generator never ran in that assembly" — a csproj problem — is distinguishable at runtime from "the generator ran and declined your type" — a code-shape problem. The exception says which.
  • Two copies of the generator in one compilation no longer collide with CS0433. This happens when a project references the standalone JasperFx.Events.SourceGenerator package as well as Marten, which bundles it: both copies emit identical file paths and the file-scoped evolvers mangle to the same name. If you hit that error — recognisable because it names the same assembly on both sides — remove the standalone package reference; Marten already carries the analyzer.
  • Opt in to a build-time check with <JasperFxEventsRequireSourceGenerator>true</JasperFxEventsRequireSourceGenerator> on projects that declare aggregates, and a missing analyzer becomes build error JFXEVT900 rather than a failure at the first FetchForWriting.

Compliance coverage

Marten is now enrolled in DocumentConjoinedTenancyCompliance (#​5517) — the first shared document coverage of conjoined tenancy on any store — with all 10 facts running. ConjoinedEventTenancyCompliance goes from 16 passing with 2 skipped to 18 passing with none, the two skips having been waiting on the read-only overload above.

Two of these enrollments exposed that Marten's own commit-listener compliance facts had been passing vacuously — the harness never installed the listener the suites register, so "no phantom deletion was reported" was trivially true of a store reporting nothing at all. Fixed in the #​5518 bump; no product change was needed, and both halves of that fact now pass for real.

Dependencies

JasperFx 2.75.2 and Weasel 9.35.2.

Weasel 9.35.x is mostly EF Core and SQL Server work, plus weasel#​634: an exhausted DropSchema retry is now reported instead of returning success.

Docs

The bundled analyzer does flow transitively across a ProjectReference (#​5508) — the composite-configuration page claimed the opposite. The claim was true of the standalone analyzer package, which Marten sets PrivateAssets="all" on, but #​4557 bundles the analyzer DLL into Marten's own package and that copy flows.

9.39.1

What's Changed

Full Changelog: JasperFx/marten@V9.39.0...v9.39.1

Commits viewable in compare view.

Updated Quartz.Extensions.Hosting from 4.1.1 to 4.3.0.

Release notes

Sourced from Quartz.Extensions.Hosting's releases.

4.3.0

Quartz.NET 4.3 is an additive minor. Every public change is a new type, a new member on a type we own, or a default
interface member, and its schema change is one generated folder, database/migrations/4.3/, that only adds
nullable columns. A released 4.2 node and a 4.3 node share one PostgreSQL database in CI to prove a mixed cluster
runs safely. A 4.2 application upgrades by changing the version and, on a persistent store, running the 4.3 scripts
before the first 4.3 node starts. The headlines: a scheduler on a database fires one-off jobs 2.8× faster than 4.2
at its shipped defaults; a job can be a lambda; and a schedule can be steered while it runs, with an overlap policy,
a pause that says why, backfill, progress and captured logs, and a dashboard that edits. Four new packages put the job store's tables under Weasel, for applications on Marten or Wolverine.

dotnet add package Quartz --version 4.3.0

Highlights

Faster where it runs

  • A job that takes nothing from the container — no constructor parameters, not registered, no ConfigureScope —
    is built without a DI scope: 1.84 → 1.68 KB a firing on RAMJobStore, a little faster too. Every other job keeps
    its scope exactly as before. (#​3866)

  • RAMJobStore computes a cron trigger's next fire time once per firing, not twice, inside its lock. (#​3866)

  • A scheduler on a database batches what is already due, out of the box. MaxBatchSize now defaults to
    automatic: the thread pool's size on a persistent store, clustered or not, and 1 in memory.
    Nothing fires early (the fire-ahead window is still zero). On PostgreSQL a backlog of one-off jobs goes from
    about 80–91 to 125 firings a second, and from 6.0 to 2.8 commits a firing. MaxBatchSize = 1 restores 4.2.
    On a cluster, the flip was gated on a 2- and 4-node drain against a durable PostgreSQL: 1.7–2.1× faster on
    two nodes and 1.6–2.0× on four, at a lock-wait p99 of about 60 ms. One of four sittings read 0.78× on four nodes
    while every lock wait on that shared VM was slower. (#​3862, #​3900)

  • Scheduling a job costs less. ScheduleJob with a simple trigger allocates 2.76 KB, down from 3.83 KB,
    and a cron one 3.3 KB, down from 4.6 KB. Scheduling a trigger later than the one the scheduler is already
    waiting for no longer wakes it, and listener lists are built when they change, not on every call. (#​3865)

  • A firing that may run beside itself completes without the store's lock. Completions of
    concurrent-allowed jobs no longer queue behind each other on TRIGGER_ACCESS. With the batching default above,
    one-off jobs on PostgreSQL go from 4.2's 91 to 237 firings a second on the same database: 2.6×. Repeating
    triggers fire 1.5–1.9× faster. A 2- and 4-node cluster drains 1.5–1.8× faster at a fifth of the lock wait. A
    [DisallowConcurrentExecution] job, a retry, a trigger with continuations, a buffered overlap policy and a
    non-durable job's last trigger keep the lock. The misfire pass also settles a continuation whose parent no
    longer exists. (#​3863)

  • Measured on the release candidate against 4.2.0, alternating sittings on one box and one durable PostgreSQL:

    4.2.0 4.3.0
    One-off jobs on PostgreSQL, shipped defaults 90–91 a second 251–255 a second (2.8×)
    Repeating triggers on PostgreSQL at 20 a second, within ±50 ms 22 % 52 % (all within ±250 ms; worst 84–96 ms, was 205 ms)
    In-memory throughput, bytes per execution 2.81 KB 2.07 KB, and not slower
    Scheduling one simple trigger 3.4–3.6 KB 2.6–2.7 KB

    In memory every firing still lands within ±...

_Description has been...

Description has been truncated

Bumps Aspire.Hosting.AppHost from 13.5.4 to 13.6.0
Bumps Aspire.Hosting.PostgreSQL from 13.5.4 to 13.6.0
Bumps Aspire.Hosting.Testing from 13.5.4 to 13.6.0
Bumps coverlet.collector from 10.0.1 to 10.1.0
Bumps Marten from 9.39.0 to 9.43.0
Bumps Marten.AspNetCore from 9.39.0 to 9.43.0
Bumps Quartz.Extensions.Hosting from 4.1.1 to 4.3.0
Bumps Radzen.Blazor from 11.4.2 to 11.5.1

---
updated-dependencies:
- dependency-name: Aspire.Hosting.AppHost
  dependency-version: 13.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Aspire.Hosting.PostgreSQL
  dependency-version: 13.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Aspire.Hosting.Testing
  dependency-version: 13.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: coverlet.collector
  dependency-version: 10.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Marten
  dependency-version: 9.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Marten.AspNetCore
  dependency-version: 9.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Quartz.Extensions.Hosting
  dependency-version: 4.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Radzen.Blazor
  dependency-version: 11.5.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added .NET Pull requests that update .NET code dependencies Pull requests that update a dependency file labels Oct 1, 2026
@dependabot @github

dependabot Bot commented on behalf of github Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Looks like these dependencies are updatable in another way, so this is no longer needed.

@dependabot dependabot Bot closed this Oct 2, 2026
@dependabot
dependabot Bot deleted the dependabot/nuget/nuget-minor-patch-70fa6db961 branch October 2, 2026 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants