+ Test various rate limiting policies. Each card shows a different partition strategy and window configuration.
+ When a limit is triggered, observe the localized error message and countdown timer.
+
+
+ Public = no login required
+ Auth = login required
+
+
+
+
+
+
+
+
+
+
+ 1. Send SMS Code
+ Public
+
+
+
+ Partition:PartitionByParameter
+ Rule: 3 requests per phone number within 20 seconds
+ Note: Each phone number has an independent counter. The parameter is passed explicitly by the caller.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2. Login Attempt
+ Public
+
+
+
+ Partition:PartitionByClientIp
+ Rule: 5 requests per IP within 20 seconds
+ Note: Client IP is resolved automatically. All requests from the same IP share one counter; no parameter needed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 3. Generate API Key
+ Auth
+
+
+
+ Partition:PartitionByCurrentUser
+ Rule: 3 requests per user within 20 seconds
+ Note: Requires login. Current user ID is used as the partition key automatically; each user has an independent counter.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 4. Send Email Code
+ Auth
+
+
+
+ Partition:PartitionByEmail
+ Rule: 2 requests per email within 20 seconds
+ Note: Requires login. Email is resolved from the current user's email claim automatically; no manual parameter needed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5a. Composite: User + IP
+ Auth
+
+
+
+ Partition:ByCurrentUser + ByClientIp
+ Rule 1: 5 requests per user within 2 minutes
+ Rule 2: 3 requests per IP within 20 seconds
+ Note: IP window (20s) triggers first; user window (2min) does not expire during the wait. Two-phase check prevents wasted quota on blocked requests.
+ How to test: Click 3 times quickly → IP blocked (3/3); wait 20s then click 2 more → user rule triggers (5/5).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5b. Composite: Param + User
+ Auth
+
+
+
+ Partition:ByParameter + ByCurrentUser
+ Rule 1: 5 requests per key within 2 minutes
+ Rule 2: 2 requests per user within 20 seconds
+ Note: User limit (2/20s) triggers first; parameter rule (5/2min) only counts successful requests. Parameter counter persists after user window resets.
+ How to test: Click 2 times → user blocked (2/2); wait 20s, click 2 more → user blocked again; wait 20s, click 1 more → parameter rule triggers (5/5).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5c. Composite: Triple
+ Auth
+
+
+
+ Partition:ByParameter + ByCurrentUser + ByClientIp
+ Rule 1: 5 requests per key within 2 minutes
+ Rule 2: 4 requests per user within 2 minutes
+ Rule 3: 3 requests per IP within 20 seconds
+ Note: All three rules apply (AND logic). IP (3/20s) triggers first; after 20s reset, user (4/2min) becomes the bottleneck.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 6. Submit Feedback (Custom Error Code)
+ Public
+
+
+
+ Partition:PartitionByParameter
+ Rule: 2 requests per email within 20 seconds
+ Custom error code:App:Feedback:RateLimited
+ Note: Default error code is Volo.Abp.OperationRateLimit:010001. This policy uses WithErrorCode() to set a custom code so the frontend can handle it differently.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 7. Long Window - Hours
+ Public
+
+
+
+ Partition:PartitionByParameter
+ Rule: 2 requests per key within 3 hours
+ Note: Tests RetryAfter formatting for long windows. When triggered, the message should display something like "X hours Y minutes".
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 8. Long Window - Days
+ Public
+
+
+
+ Partition:PartitionByClientIp
+ Rule: 1 request per IP within 3 days
+ Note: Tests RetryAfter formatting for very long windows. When triggered, the message should display something like "X days Y hours". Only 1 request is needed to trigger it.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 9. Custom Multi-Key Resolver
+ Auth
+
+
+
+ Partition:PartitionBy(ctx => $"{resourceId}:{userId}")
+ Rule: 2 requests per user per resource within 20 seconds
+ Note: A custom resolver combines multiple values into one partition key. Each user has an independent quota per resource — different users on the same resource don't affect each other, and the same user on different resources doesn't either.
+ How to test: Click 2 times with the same Resource ID → limit triggered; change the Resource ID → quota resets.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 10. Multi-Tenancy Isolation
+ Public
+
+
+
+ Partition:PartitionByParameter + .WithMultiTenancy()
+ Rule: 3 requests per parameter per tenant within 20 seconds
+ Note: The same parameter value has independent counters in different tenants. Without .WithMultiTenancy(), all tenants share the same counter.
+