diff --git a/Inngest.Tests/FunctionRegistryTests.cs b/Inngest.Tests/FunctionRegistryTests.cs
index 10620ad..a88f349 100644
--- a/Inngest.Tests/FunctionRegistryTests.cs
+++ b/Inngest.Tests/FunctionRegistryTests.cs
@@ -194,10 +194,11 @@ public void RegisterFunction_CapturesFunctionOptions()
Assert.NotNull(registration.Options.Retry);
Assert.Equal(5, registration.Options.Retry.Attempts);
- // Concurrency
- Assert.NotNull(registration.Options.ConcurrencyOptions);
- Assert.Equal(10, registration.Options.ConcurrencyOptions.Limit);
- Assert.Equal("event.data.userId", registration.Options.ConcurrencyOptions.Key);
+ // Concurrency - now uses ConcurrencyConstraints list
+ Assert.NotNull(registration.Options.ConcurrencyConstraints);
+ Assert.Single(registration.Options.ConcurrencyConstraints);
+ Assert.Equal(10, registration.Options.ConcurrencyConstraints[0].Limit);
+ Assert.Equal("event.data.userId", registration.Options.ConcurrencyConstraints[0].Key);
// Rate limit
Assert.NotNull(registration.Options.RateLimit);
diff --git a/Inngest.Tests/SdkParityTests.cs b/Inngest.Tests/SdkParityTests.cs
new file mode 100644
index 0000000..a605fed
--- /dev/null
+++ b/Inngest.Tests/SdkParityTests.cs
@@ -0,0 +1,647 @@
+using System.Text.Json;
+using Inngest.Attributes;
+using Inngest.Configuration;
+using Inngest.Internal;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging.Abstractions;
+using System.Text;
+
+namespace Inngest.Tests;
+
+///
+/// Tests for SDK parity features: multi-concurrency, idempotency period,
+/// retry helpers, structured logging, and onFailure handlers.
+///
+public class SdkParityTests
+{
+ private readonly JsonSerializerOptions _jsonOptions = new()
+ {
+ PropertyNamingPolicy = JsonNamingPolicy.CamelCase
+ };
+
+ #region Test Function Definitions
+
+ // Multi-concurrency constraint test function
+ [InngestFunction("multi-concurrency-function", Name = "Multi Concurrency Function")]
+ [EventTrigger("test/multi-concurrency")]
+ [Concurrency(1, Key = "event.data.paymentId")] // Per-key serialization
+ [Concurrency(5)] // Global cap
+ public class MultiConcurrencyFunction : IInngestFunction
+ {
+ public Task