Manage throttling policies¶
What happens
An admin creates or edits rate-limit policies in the Admin Portal. There are four levels, and each one has its own table. Advanced (API-level) policies can hold conditional limits, such as "IP 10.0.0.0/8 gets 100 req/min". Those are stored as a small tree of condition tables. Once saved, the policy is deployed to the Traffic Manager, which enforces it.
Who: Admin Portal · Tables written: AM_POLICY_SUBSCRIPTION, AM_POLICY_APPLICATION, AM_API_THROTTLE_POLICY, AM_CONDITION_GROUP, AM_IP_CONDITION, AM_HEADER_FIELD_CONDITION, AM_QUERY_PARAMETER_CONDITION, AM_JWT_CLAIM_CONDITION, AM_POLICY_GLOBAL, AM_BLOCK_CONDITIONS, AM_THROTTLE_TIER_PERMISSIONS · Tables read: none of note
The flow at a glance¶
This diagram shows which table each kind of policy lands in.
flowchart LR
Admin[Admin Portal] --> S[AM_POLICY_SUBSCRIPTION]
Admin --> A[AM_POLICY_APPLICATION]
Admin --> R[AM_API_THROTTLE_POLICY]
Admin --> G[AM_POLICY_GLOBAL]
Admin --> B[AM_BLOCK_CONDITIONS]
R --> C[AM_CONDITION_GROUP]
- From top to bottom: subscription policies, application policies, advanced (API/resource) policies with their condition groups, custom global policies, and deny policies.
- Every policy table has
IS_DEPLOYED. It flips to true once the Traffic Manager has accepted the policy.
Step by step¶
-
Subscription policy →
AM_POLICY_SUBSCRIPTION. This limits one app's calls to one API.AM_SUBSCRIPTION.TIER_IDuses it.NAMEQUOTA_TYPEQUOTAUNIT_TIMETIME_UNITRATE_LIMIT_COUNTSTOP_ON_QUOTA_REACHBILLING_PLANGoldrequestCount5000 1 min0 true FREEQUOTA_TYPEdecides howQUOTAis read:requestCount(a number of calls) orbandwidthVolume(withQUOTA_UNITin KB or MB).RATE_LIMIT_COUNT/RATE_LIMIT_TIME_UNITadd a short burst limit.- The monetization columns (
MONETIZATION_PLAN,FIXED_RATE,PRICE_PER_REQUEST,CURRENCY,BILLING_CYCLE) are only used for commercial tiers. MAX_COMPLEXITY/MAX_DEPTHlimit GraphQL queries.(NAME, TENANT_ID)is unique.
-
Application policy →
AM_POLICY_APPLICATION. This limits one app's calls across all APIs.AM_APPLICATION.APPLICATION_TIERuses it. It has the same quota columns, without the burst and billing columns. -
Advanced (API / resource) policy →
AM_API_THROTTLE_POLICY. This limits calls to an API or a single resource from all apps together.AM_API.API_TIERorAM_API_URL_MAPPING.THROTTLING_TIERuses it.- The
DEFAULT_*columns hold the limit that applies when no condition matches. APPLICABLE_LEVELisapiLevelorresourceLevel.
- The
-
Conditional limits →
AM_CONDITION_GROUPplus one table per condition type. This diagram shows the tree for one advanced policy.erDiagram AM_API_THROTTLE_POLICY ||--o{ AM_CONDITION_GROUP : "has" AM_CONDITION_GROUP ||--o{ AM_IP_CONDITION : "matches IP" AM_CONDITION_GROUP ||--o{ AM_HEADER_FIELD_CONDITION : "matches header" AM_CONDITION_GROUP ||--o{ AM_QUERY_PARAMETER_CONDITION : "matches query param" AM_CONDITION_GROUP ||--o{ AM_JWT_CLAIM_CONDITION : "matches JWT claim"- Each condition group has its own quota (
QUOTA_TYPE,QUOTA,UNIT_TIME,TIME_UNIT). It applies when all the conditions in that group match. AM_IP_CONDITION:SPECIFIC_IP, orSTARTING_IP+ENDING_IP, plus theWITHIN_IP_RANGEflag.AM_HEADER_FIELD_CONDITIONandAM_QUERY_PARAMETER_CONDITION: a name and value, plus anIS_*_MAPPINGflag.- Careful with the flags. Despite their names,
IS_HEADER_FIELD_MAPPINGandWITHIN_IP_RANGEare bothFALSEfor an ordinary, non-inverted condition. Don't readFALSEas "inverted" without checking against the Admin Portal. AM_JWT_CLAIM_CONDITION:CLAIM_URI+CLAIM_ATTRIB(a regex).- All links are real FKs with
ON DELETE CASCADE, so deleting the policy removes the whole tree.
Example: policy
PizzaAdvanced(POLICY_ID = 5, default 10/min) has condition group 1 (QUOTA = 2,TIME_UNIT = 'min',DESCRIPTION = 'mobile'). That group has oneAM_HEADER_FIELD_CONDITION(User-Agent=mobile) and oneAM_IP_CONDITION(SPECIFIC_IP = 10.0.0.1). Both conditions must match for the 2/min limit to apply. - Each condition group has its own quota (
-
Custom (global) policy →
AM_POLICY_GLOBAL. This is an advanced rule written as a Siddhi query (SIDDHI_QUERY), with aKEY_TEMPLATEsuch as$userId:$apiContext. It isn't linked to any API. It applies to all traffic that matches the key. -
Deny (block) policies →
AM_BLOCK_CONDITIONS. These block calls outright byTYPE:API(context),APPLICATION,USER,IPorIPRANGE.VALUEis what to match,ENABLEDturns the rule on or off, andDOMAINis the tenant domain.CONDITION_IDTYPEVALUEENABLEDDOMAINUUID1 IP{"invert":false,"fixedIp":"10.9.9.9"}'true'carbon.super466d…For IP types,
VALUEis a small JSON document, andENABLEDis the string'true'. -
Who may use a tier →
AM_THROTTLE_TIER_PERMISSIONS(TIER,PERMISSIONS_TYPE=allow/deny,ROLES,TENANT_ID). This limits which roles can subscribe with a tier. The olderAM_TIER_PERMISSIONShas the same shape and is kept for legacy tiers. -
Legacy hard limits →
AM_POLICY_HARD_THROTTLING. An older table for hard limits per tenant. Backend hard limits in 3.x are normally set on the API's endpoint configuration instead.
What gets cleaned up¶
Deleting an advanced policy cascades through its condition groups and conditions. Deleting a subscription or application policy that is still used by AM_SUBSCRIPTION.TIER_ID or AM_APPLICATION.APPLICATION_TIER is not blocked by the database, because those are name-based links. The Admin Portal checks for usage and refuses instead.
Try it¶
This query lists advanced policies with their conditional limits and IP conditions.
SELECT p.NAME, p.DEFAULT_QUOTA, p.DEFAULT_TIME_UNIT,
g.CONDITION_GROUP_ID, g.QUOTA, g.TIME_UNIT,
ip.SPECIFIC_IP, ip.STARTING_IP, ip.ENDING_IP, ip.WITHIN_IP_RANGE
FROM AM_API_THROTTLE_POLICY p
LEFT JOIN AM_CONDITION_GROUP g ON g.POLICY_ID = p.POLICY_ID
LEFT JOIN AM_IP_CONDITION ip ON ip.CONDITION_GROUP_ID = g.CONDITION_GROUP_ID
WHERE p.TENANT_ID = -1234;
Related domains: Throttling policies · Applications & subscriptions
Different in 4.x
4.x adds more columns, for example event-count quotas for streaming APIs and ORGANIZATION scoping on some tables. The four levels and the condition tree stay the same. See Manage throttling policies (4.x).