@@ -45,6 +45,7 @@ class EndpointCategory(str, Enum):
4545 GRAPH_SYNC = "graph_sync"
4646 GRAPH_MCP = "graph_mcp"
4747 GRAPH_AGENT = "graph_agent"
48+ GRAPH_SEARCH = "graph_search" # OpenSearch full-text search (shared resource)
4849
4950 # High-cost operations
5051 GRAPH_QUERY = "graph_query" # Direct Cypher queries
@@ -87,150 +88,119 @@ class RateLimitConfig:
8788 SUBSCRIPTION_RATE_LIMITS : dict [
8889 str , dict [EndpointCategory , tuple [int , RateLimitPeriod ]]
8990 ] = {
90- "free" : {
91- # Non-graph endpoints - keep some restrictions for free tier
91+ # -----------------------------------------------------------------------
92+ # MANAGED SERVICE RATE LIMITS
93+ # All tiers share managed infrastructure. Limits are conservative to
94+ # protect shared resources (OpenSearch t3.medium, LadybugDB on m7g/r7g).
95+ # For self-hosted scale, customers deploy their own infrastructure.
96+ # Loosen these as infra scales up.
97+ # -----------------------------------------------------------------------
98+ "base" : {
99+ # Anonymous / unrecognized tier — tightest limits
92100 EndpointCategory .AUTH : (10 , RateLimitPeriod .MINUTE ),
93- EndpointCategory .USER_MANAGEMENT : (60 , RateLimitPeriod .MINUTE ),
94- EndpointCategory .TASKS : (60 , RateLimitPeriod .MINUTE ),
95- EndpointCategory .STATUS : (120 , RateLimitPeriod .MINUTE ),
96- EndpointCategory .SSE : (
97- 5 ,
98- RateLimitPeriod .MINUTE ,
99- ), # Limited SSE connections for free
101+ EndpointCategory .USER_MANAGEMENT : (30 , RateLimitPeriod .MINUTE ),
102+ EndpointCategory .TASKS : (30 , RateLimitPeriod .MINUTE ),
103+ EndpointCategory .STATUS : (60 , RateLimitPeriod .MINUTE ),
104+ EndpointCategory .SSE : (3 , RateLimitPeriod .MINUTE ),
100105 EndpointCategory .BILLING : (60 , RateLimitPeriod .MINUTE ), # Never block payments
101- # Graph-scoped endpoints - burst protection only
102- EndpointCategory .GRAPH_READ : (100 , RateLimitPeriod .MINUTE ),
103- EndpointCategory .GRAPH_WRITE : (20 , RateLimitPeriod .MINUTE ),
104- EndpointCategory .GRAPH_ANALYTICS : (10 , RateLimitPeriod .MINUTE ),
106+ # Graph-scoped
107+ EndpointCategory .GRAPH_READ : (30 , RateLimitPeriod .MINUTE ),
108+ EndpointCategory .GRAPH_WRITE : (10 , RateLimitPeriod .MINUTE ),
109+ EndpointCategory .GRAPH_ANALYTICS : (5 , RateLimitPeriod .MINUTE ),
105110 EndpointCategory .GRAPH_BACKUP : (2 , RateLimitPeriod .MINUTE ),
106- EndpointCategory .GRAPH_SYNC : (5 , RateLimitPeriod .MINUTE ),
107- EndpointCategory .GRAPH_MCP : (10 , RateLimitPeriod .MINUTE ),
108- EndpointCategory .GRAPH_AGENT : (5 , RateLimitPeriod .MINUTE ),
109- EndpointCategory .GRAPH_QUERY : (50 , RateLimitPeriod .MINUTE ),
111+ EndpointCategory .GRAPH_SYNC : (3 , RateLimitPeriod .MINUTE ),
112+ EndpointCategory .GRAPH_MCP : (5 , RateLimitPeriod .MINUTE ),
113+ EndpointCategory .GRAPH_AGENT : (3 , RateLimitPeriod .MINUTE ),
114+ EndpointCategory .GRAPH_SEARCH : (5 , RateLimitPeriod .MINUTE ),
115+ EndpointCategory .GRAPH_QUERY : (20 , RateLimitPeriod .MINUTE ),
110116 EndpointCategory .GRAPH_IMPORT : (2 , RateLimitPeriod .MINUTE ),
111- # Table operations - free tier
112- EndpointCategory .TABLE_QUERY : (30 , RateLimitPeriod .MINUTE ),
113- EndpointCategory .TABLE_UPLOAD : (10 , RateLimitPeriod .MINUTE ),
114- EndpointCategory .TABLE_MANAGEMENT : (10 , RateLimitPeriod .MINUTE ),
117+ # Table operations
118+ EndpointCategory .TABLE_QUERY : (15 , RateLimitPeriod .MINUTE ),
119+ EndpointCategory .TABLE_UPLOAD : (5 , RateLimitPeriod .MINUTE ),
120+ EndpointCategory .TABLE_MANAGEMENT : (5 , RateLimitPeriod .MINUTE ),
115121 },
116- # Technical tier names (primary)
122+ # ladybug-standard: m7g.large (8GB, 2 vCPU) — anchor tier
117123 "ladybug-standard" : {
118- # Non-graph endpoints - generous burst limits
119124 EndpointCategory .AUTH : (20 , RateLimitPeriod .MINUTE ),
120- EndpointCategory .USER_MANAGEMENT : (600 , RateLimitPeriod .MINUTE ),
121- EndpointCategory .TASKS : (200 , RateLimitPeriod .MINUTE ),
122- EndpointCategory .STATUS : (600 , RateLimitPeriod .MINUTE ),
123- EndpointCategory .SSE : (
124- 10 ,
125- RateLimitPeriod .MINUTE ,
126- ), # Standard SSE connection rate
125+ EndpointCategory .USER_MANAGEMENT : (60 , RateLimitPeriod .MINUTE ),
126+ EndpointCategory .TASKS : (60 , RateLimitPeriod .MINUTE ),
127+ EndpointCategory .STATUS : (120 , RateLimitPeriod .MINUTE ),
128+ EndpointCategory .SSE : (5 , RateLimitPeriod .MINUTE ),
127129 EndpointCategory .BILLING : (60 , RateLimitPeriod .MINUTE ), # Never block payments
128- # Graph-scoped endpoints - HIGH BURST LIMITS
129- EndpointCategory .GRAPH_READ : (500 , RateLimitPeriod .MINUTE ), # 30k/hour possible
130- EndpointCategory .GRAPH_WRITE : (100 , RateLimitPeriod .MINUTE ), # 6k/hour possible
131- EndpointCategory .GRAPH_ANALYTICS : (
132- 50 ,
133- RateLimitPeriod .MINUTE ,
134- ), # 3k/hour possible
135- EndpointCategory .GRAPH_BACKUP : (10 , RateLimitPeriod .MINUTE ), # 600/hour possible
136- EndpointCategory .GRAPH_SYNC : (100 , RateLimitPeriod .MINUTE ), # 6k/hour possible
137- EndpointCategory .GRAPH_MCP : (100 , RateLimitPeriod .MINUTE ), # 6k/hour possible
138- EndpointCategory .GRAPH_AGENT : (50 , RateLimitPeriod .MINUTE ), # 3k/hour possible
139- EndpointCategory .GRAPH_QUERY : (200 , RateLimitPeriod .MINUTE ), # 12k/hour possible
140- EndpointCategory .GRAPH_IMPORT : (50 , RateLimitPeriod .MINUTE ), # 3k/hour possible
141- # Table operations (generous burst limits)
142- EndpointCategory .TABLE_QUERY : (60 , RateLimitPeriod .MINUTE ), # 3.6k/hour possible
143- EndpointCategory .TABLE_UPLOAD : (20 , RateLimitPeriod .MINUTE ), # 1.2k/hour possible
144- EndpointCategory .TABLE_MANAGEMENT : (
145- 30 ,
130+ # Graph-scoped — sized for m7g.large
131+ EndpointCategory .GRAPH_READ : (120 , RateLimitPeriod .MINUTE ),
132+ EndpointCategory .GRAPH_WRITE : (30 , RateLimitPeriod .MINUTE ),
133+ EndpointCategory .GRAPH_ANALYTICS : (15 , RateLimitPeriod .MINUTE ),
134+ EndpointCategory .GRAPH_BACKUP : (5 , RateLimitPeriod .MINUTE ),
135+ EndpointCategory .GRAPH_SYNC : (10 , RateLimitPeriod .MINUTE ),
136+ EndpointCategory .GRAPH_MCP : (30 , RateLimitPeriod .MINUTE ),
137+ EndpointCategory .GRAPH_AGENT : (15 , RateLimitPeriod .MINUTE ),
138+ EndpointCategory .GRAPH_SEARCH : (
139+ 10 ,
146140 RateLimitPeriod .MINUTE ,
147- ), # 1.8k/hour possible
141+ ), # Shared OpenSearch t3.medium
142+ EndpointCategory .GRAPH_QUERY : (60 , RateLimitPeriod .MINUTE ),
143+ EndpointCategory .GRAPH_IMPORT : (10 , RateLimitPeriod .MINUTE ),
144+ # Table operations
145+ EndpointCategory .TABLE_QUERY : (30 , RateLimitPeriod .MINUTE ),
146+ EndpointCategory .TABLE_UPLOAD : (10 , RateLimitPeriod .MINUTE ),
147+ EndpointCategory .TABLE_MANAGEMENT : (15 , RateLimitPeriod .MINUTE ),
148148 },
149+ # ladybug-large: r7g.large (16GB, 2 vCPU)
150+ # Same base values as standard — graph.yml api_rate_multiplier (1.5x) handles scaling
149151 "ladybug-large" : {
150- # Non-graph endpoints - very high burst limits
151- EndpointCategory .AUTH : (50 , RateLimitPeriod .MINUTE ),
152- EndpointCategory .USER_MANAGEMENT : (1000 , RateLimitPeriod .MINUTE ),
153- EndpointCategory .TASKS : (1000 , RateLimitPeriod .MINUTE ),
154- EndpointCategory .STATUS : (3000 , RateLimitPeriod .MINUTE ),
155- EndpointCategory .SSE : (
156- 30 ,
157- RateLimitPeriod .MINUTE ,
158- ), # More SSE connections for large tier
152+ EndpointCategory .AUTH : (20 , RateLimitPeriod .MINUTE ),
153+ EndpointCategory .USER_MANAGEMENT : (60 , RateLimitPeriod .MINUTE ),
154+ EndpointCategory .TASKS : (60 , RateLimitPeriod .MINUTE ),
155+ EndpointCategory .STATUS : (120 , RateLimitPeriod .MINUTE ),
156+ EndpointCategory .SSE : (5 , RateLimitPeriod .MINUTE ),
159157 EndpointCategory .BILLING : (60 , RateLimitPeriod .MINUTE ), # Never block payments
160- # Graph-scoped endpoints - VERY HIGH BURST LIMITS
161- EndpointCategory .GRAPH_READ : (2000 , RateLimitPeriod .MINUTE ), # 120k/hour possible
162- EndpointCategory .GRAPH_WRITE : (500 , RateLimitPeriod .MINUTE ), # 30k/hour possible
163- EndpointCategory .GRAPH_ANALYTICS : (
164- 200 ,
165- RateLimitPeriod .MINUTE ,
166- ), # 12k/hour possible
167- EndpointCategory .GRAPH_BACKUP : (50 , RateLimitPeriod .MINUTE ), # 3k/hour possible
168- EndpointCategory .GRAPH_SYNC : (500 , RateLimitPeriod .MINUTE ), # 30k/hour possible
169- EndpointCategory .GRAPH_MCP : (500 , RateLimitPeriod .MINUTE ), # 30k/hour possible
170- EndpointCategory .GRAPH_AGENT : (200 , RateLimitPeriod .MINUTE ), # 12k/hour possible
171- EndpointCategory .GRAPH_QUERY : (1000 , RateLimitPeriod .MINUTE ), # 60k/hour possible
172- EndpointCategory .GRAPH_IMPORT : (200 , RateLimitPeriod .MINUTE ), # 12k/hour possible
173- # Table operations - large tier (very high burst limits)
174- EndpointCategory .TABLE_QUERY : (300 , RateLimitPeriod .MINUTE ), # 18k/hour possible
175- EndpointCategory .TABLE_UPLOAD : (100 , RateLimitPeriod .MINUTE ), # 6k/hour possible
176- EndpointCategory .TABLE_MANAGEMENT : (
177- 150 ,
158+ # Graph-scoped — same base, multiplied by 1.5x from graph.yml
159+ EndpointCategory .GRAPH_READ : (120 , RateLimitPeriod .MINUTE ),
160+ EndpointCategory .GRAPH_WRITE : (30 , RateLimitPeriod .MINUTE ),
161+ EndpointCategory .GRAPH_ANALYTICS : (15 , RateLimitPeriod .MINUTE ),
162+ EndpointCategory .GRAPH_BACKUP : (5 , RateLimitPeriod .MINUTE ),
163+ EndpointCategory .GRAPH_SYNC : (10 , RateLimitPeriod .MINUTE ),
164+ EndpointCategory .GRAPH_MCP : (30 , RateLimitPeriod .MINUTE ),
165+ EndpointCategory .GRAPH_AGENT : (15 , RateLimitPeriod .MINUTE ),
166+ EndpointCategory .GRAPH_SEARCH : (
167+ 10 ,
178168 RateLimitPeriod .MINUTE ,
179- ), # 9k/hour possible
169+ ), # Shared OpenSearch t3.medium
170+ EndpointCategory .GRAPH_QUERY : (60 , RateLimitPeriod .MINUTE ),
171+ EndpointCategory .GRAPH_IMPORT : (10 , RateLimitPeriod .MINUTE ),
172+ # Table operations
173+ EndpointCategory .TABLE_QUERY : (30 , RateLimitPeriod .MINUTE ),
174+ EndpointCategory .TABLE_UPLOAD : (10 , RateLimitPeriod .MINUTE ),
175+ EndpointCategory .TABLE_MANAGEMENT : (15 , RateLimitPeriod .MINUTE ),
180176 },
177+ # ladybug-xlarge: r7g.xlarge (32GB, 4 vCPU)
178+ # Same base values as standard — graph.yml api_rate_multiplier (2.5x) handles scaling
181179 "ladybug-xlarge" : {
182- # XLarge tier gets extreme burst limits - essentially unlimited
183- # Only safety limits to prevent complete system abuse
184- EndpointCategory .AUTH : (100 , RateLimitPeriod .MINUTE ),
185- EndpointCategory .USER_MANAGEMENT : (3000 , RateLimitPeriod .MINUTE ),
186- EndpointCategory .TASKS : (5000 , RateLimitPeriod .MINUTE ),
187- EndpointCategory .STATUS : (10000 , RateLimitPeriod .MINUTE ),
188- EndpointCategory .SSE : (
189- 100 ,
190- RateLimitPeriod .MINUTE ,
191- ), # Generous SSE connections for xlarge tier
180+ EndpointCategory .AUTH : (20 , RateLimitPeriod .MINUTE ),
181+ EndpointCategory .USER_MANAGEMENT : (60 , RateLimitPeriod .MINUTE ),
182+ EndpointCategory .TASKS : (60 , RateLimitPeriod .MINUTE ),
183+ EndpointCategory .STATUS : (120 , RateLimitPeriod .MINUTE ),
184+ EndpointCategory .SSE : (5 , RateLimitPeriod .MINUTE ),
192185 EndpointCategory .BILLING : (60 , RateLimitPeriod .MINUTE ), # Never block payments
193- # Graph-scoped endpoints - EXTREME BURST LIMITS
194- EndpointCategory .GRAPH_READ : (
195- 10000 ,
196- RateLimitPeriod .MINUTE ,
197- ), # 600k/hour possible
198- EndpointCategory .GRAPH_WRITE : (
199- 5000 ,
200- RateLimitPeriod .MINUTE ,
201- ), # 300k/hour possible
202- EndpointCategory .GRAPH_ANALYTICS : (
203- 2000 ,
204- RateLimitPeriod .MINUTE ,
205- ), # 120k/hour possible
206- EndpointCategory .GRAPH_BACKUP : (200 , RateLimitPeriod .MINUTE ), # 12k/hour possible
207- EndpointCategory .GRAPH_SYNC : (2000 , RateLimitPeriod .MINUTE ), # 120k/hour possible
208- EndpointCategory .GRAPH_MCP : (5000 , RateLimitPeriod .MINUTE ), # 300k/hour possible
209- EndpointCategory .GRAPH_AGENT : (
210- 2000 ,
211- RateLimitPeriod .MINUTE ,
212- ), # 120k/hour possible
213- EndpointCategory .GRAPH_QUERY : (
214- 10000 ,
215- RateLimitPeriod .MINUTE ,
216- ), # 600k/hour possible
217- EndpointCategory .GRAPH_IMPORT : (
218- 1000 ,
219- RateLimitPeriod .MINUTE ,
220- ), # 60k/hour possible
221- # Table operations - xlarge tier (extreme burst limits)
222- EndpointCategory .TABLE_QUERY : (
223- 1000 ,
224- RateLimitPeriod .MINUTE ,
225- ), # 60k/hour possible
226- EndpointCategory .TABLE_UPLOAD : (
227- 500 ,
228- RateLimitPeriod .MINUTE ,
229- ), # 30k/hour possible
230- EndpointCategory .TABLE_MANAGEMENT : (
231- 500 ,
186+ # Graph-scoped — same base, multiplied by 2.5x from graph.yml
187+ EndpointCategory .GRAPH_READ : (120 , RateLimitPeriod .MINUTE ),
188+ EndpointCategory .GRAPH_WRITE : (30 , RateLimitPeriod .MINUTE ),
189+ EndpointCategory .GRAPH_ANALYTICS : (15 , RateLimitPeriod .MINUTE ),
190+ EndpointCategory .GRAPH_BACKUP : (5 , RateLimitPeriod .MINUTE ),
191+ EndpointCategory .GRAPH_SYNC : (10 , RateLimitPeriod .MINUTE ),
192+ EndpointCategory .GRAPH_MCP : (30 , RateLimitPeriod .MINUTE ),
193+ EndpointCategory .GRAPH_AGENT : (15 , RateLimitPeriod .MINUTE ),
194+ EndpointCategory .GRAPH_SEARCH : (
195+ 10 ,
232196 RateLimitPeriod .MINUTE ,
233- ), # 30k/hour possible
197+ ), # Shared OpenSearch t3.medium
198+ EndpointCategory .GRAPH_QUERY : (60 , RateLimitPeriod .MINUTE ),
199+ EndpointCategory .GRAPH_IMPORT : (10 , RateLimitPeriod .MINUTE ),
200+ # Table operations
201+ EndpointCategory .TABLE_QUERY : (30 , RateLimitPeriod .MINUTE ),
202+ EndpointCategory .TABLE_UPLOAD : (10 , RateLimitPeriod .MINUTE ),
203+ EndpointCategory .TABLE_MANAGEMENT : (15 , RateLimitPeriod .MINUTE ),
234204 },
235205 }
236206
@@ -246,8 +216,8 @@ def get_rate_limit(
246216 """
247217 tier_limits = cls .SUBSCRIPTION_RATE_LIMITS .get (tier )
248218 if not tier_limits :
249- # Default to free tier if unknown
250- tier_limits = cls .SUBSCRIPTION_RATE_LIMITS ["free " ]
219+ # Default to base tier if unknown
220+ tier_limits = cls .SUBSCRIPTION_RATE_LIMITS ["base " ]
251221
252222 limit_config = tier_limits .get (category )
253223 if not limit_config :
@@ -353,6 +323,10 @@ def get_endpoint_category(
353323 elif endpoint_type == "agent" :
354324 return EndpointCategory .GRAPH_AGENT
355325
326+ # Search operations (OpenSearch - shared resource)
327+ elif endpoint_type == "search" :
328+ return EndpointCategory .GRAPH_SEARCH
329+
356330 # Backup operations
357331 elif endpoint_type == "graph" and "backup" in path :
358332 return EndpointCategory .GRAPH_BACKUP
0 commit comments