@exulu/backend 1.48.2 → 1.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/dist/index.cjs +351 -42
  2. package/dist/index.d.cts +96 -1
  3. package/dist/index.d.ts +96 -1
  4. package/dist/index.js +340 -38
  5. package/ee/{markdown.ts → chunking/markdown.ts} +2 -2
  6. package/ee/python/README.md +295 -0
  7. package/ee/python/documents/processing/README.md +155 -0
  8. package/ee/{documents → python/documents}/processing/doc_processor.ts +25 -17
  9. package/ee/{documents/processing/pdf_to_markdown.py → python/documents/processing/document_to_markdown.py} +3 -10
  10. package/ee/python/setup.sh +180 -0
  11. package/package.json +14 -3
  12. package/scripts/postinstall.cjs +149 -0
  13. package/.agents/skills/mintlify/SKILL.md +0 -347
  14. package/.editorconfig +0 -15
  15. package/.eslintrc.json +0 -52
  16. package/.github/workflows/release-backend.yml +0 -38
  17. package/.husky/commit-msg +0 -1
  18. package/.jscpd.json +0 -18
  19. package/.mcp.json +0 -25
  20. package/.nvmrc +0 -1
  21. package/.prettierignore +0 -5
  22. package/.prettierrc.json +0 -12
  23. package/CHANGELOG.md +0 -8
  24. package/SECURITY.md +0 -5
  25. package/commitlint.config.js +0 -4
  26. package/devops/documentation/patch-older-releases.md +0 -42
  27. package/ee/documents/processing/build_pdf_processor.sh +0 -35
  28. package/ee/documents/processing/chunk_markdown.py +0 -263
  29. package/ee/documents/processing/pdf_processor.spec +0 -115
  30. package/eslint.config.js +0 -88
  31. package/jest.config.ts +0 -25
  32. package/mintlify-docs/.mintignore +0 -7
  33. package/mintlify-docs/AGENTS.md +0 -33
  34. package/mintlify-docs/CLAUDE.MD +0 -50
  35. package/mintlify-docs/CONTRIBUTING.md +0 -32
  36. package/mintlify-docs/LICENSE +0 -21
  37. package/mintlify-docs/README.md +0 -55
  38. package/mintlify-docs/ai-tools/claude-code.mdx +0 -43
  39. package/mintlify-docs/ai-tools/cursor.mdx +0 -39
  40. package/mintlify-docs/ai-tools/windsurf.mdx +0 -39
  41. package/mintlify-docs/api-reference/core-types/agent-types.mdx +0 -110
  42. package/mintlify-docs/api-reference/core-types/analytics-types.mdx +0 -95
  43. package/mintlify-docs/api-reference/core-types/configuration-types.mdx +0 -83
  44. package/mintlify-docs/api-reference/core-types/evaluation-types.mdx +0 -106
  45. package/mintlify-docs/api-reference/core-types/job-types.mdx +0 -135
  46. package/mintlify-docs/api-reference/core-types/overview.mdx +0 -73
  47. package/mintlify-docs/api-reference/core-types/prompt-types.mdx +0 -102
  48. package/mintlify-docs/api-reference/core-types/rbac-types.mdx +0 -163
  49. package/mintlify-docs/api-reference/core-types/session-types.mdx +0 -77
  50. package/mintlify-docs/api-reference/core-types/user-management.mdx +0 -112
  51. package/mintlify-docs/api-reference/core-types/workflow-types.mdx +0 -88
  52. package/mintlify-docs/api-reference/core-types.mdx +0 -585
  53. package/mintlify-docs/api-reference/dynamic-types.mdx +0 -851
  54. package/mintlify-docs/api-reference/endpoint/create.mdx +0 -4
  55. package/mintlify-docs/api-reference/endpoint/delete.mdx +0 -4
  56. package/mintlify-docs/api-reference/endpoint/get.mdx +0 -4
  57. package/mintlify-docs/api-reference/endpoint/webhook.mdx +0 -4
  58. package/mintlify-docs/api-reference/introduction.mdx +0 -661
  59. package/mintlify-docs/api-reference/mutations.mdx +0 -1012
  60. package/mintlify-docs/api-reference/openapi.json +0 -217
  61. package/mintlify-docs/api-reference/queries.mdx +0 -1154
  62. package/mintlify-docs/backend/introduction.mdx +0 -218
  63. package/mintlify-docs/changelog.mdx +0 -387
  64. package/mintlify-docs/community-edition.mdx +0 -304
  65. package/mintlify-docs/core/exulu-agent/api-reference.mdx +0 -894
  66. package/mintlify-docs/core/exulu-agent/configuration.mdx +0 -690
  67. package/mintlify-docs/core/exulu-agent/introduction.mdx +0 -552
  68. package/mintlify-docs/core/exulu-app/api-reference.mdx +0 -481
  69. package/mintlify-docs/core/exulu-app/configuration.mdx +0 -319
  70. package/mintlify-docs/core/exulu-app/introduction.mdx +0 -117
  71. package/mintlify-docs/core/exulu-authentication.mdx +0 -810
  72. package/mintlify-docs/core/exulu-chunkers/api-reference.mdx +0 -1011
  73. package/mintlify-docs/core/exulu-chunkers/configuration.mdx +0 -596
  74. package/mintlify-docs/core/exulu-chunkers/introduction.mdx +0 -403
  75. package/mintlify-docs/core/exulu-context/api-reference.mdx +0 -911
  76. package/mintlify-docs/core/exulu-context/configuration.mdx +0 -648
  77. package/mintlify-docs/core/exulu-context/introduction.mdx +0 -394
  78. package/mintlify-docs/core/exulu-database.mdx +0 -811
  79. package/mintlify-docs/core/exulu-default-agents.mdx +0 -545
  80. package/mintlify-docs/core/exulu-eval/api-reference.mdx +0 -772
  81. package/mintlify-docs/core/exulu-eval/configuration.mdx +0 -680
  82. package/mintlify-docs/core/exulu-eval/introduction.mdx +0 -459
  83. package/mintlify-docs/core/exulu-logging.mdx +0 -464
  84. package/mintlify-docs/core/exulu-otel.mdx +0 -670
  85. package/mintlify-docs/core/exulu-queues/api-reference.mdx +0 -648
  86. package/mintlify-docs/core/exulu-queues/configuration.mdx +0 -650
  87. package/mintlify-docs/core/exulu-queues/introduction.mdx +0 -474
  88. package/mintlify-docs/core/exulu-reranker/api-reference.mdx +0 -630
  89. package/mintlify-docs/core/exulu-reranker/configuration.mdx +0 -663
  90. package/mintlify-docs/core/exulu-reranker/introduction.mdx +0 -516
  91. package/mintlify-docs/core/exulu-tool/api-reference.mdx +0 -723
  92. package/mintlify-docs/core/exulu-tool/configuration.mdx +0 -805
  93. package/mintlify-docs/core/exulu-tool/introduction.mdx +0 -539
  94. package/mintlify-docs/core/exulu-variables/api-reference.mdx +0 -699
  95. package/mintlify-docs/core/exulu-variables/configuration.mdx +0 -736
  96. package/mintlify-docs/core/exulu-variables/introduction.mdx +0 -511
  97. package/mintlify-docs/development.mdx +0 -94
  98. package/mintlify-docs/docs.json +0 -248
  99. package/mintlify-docs/enterprise-edition.mdx +0 -538
  100. package/mintlify-docs/essentials/code.mdx +0 -35
  101. package/mintlify-docs/essentials/images.mdx +0 -59
  102. package/mintlify-docs/essentials/markdown.mdx +0 -88
  103. package/mintlify-docs/essentials/navigation.mdx +0 -87
  104. package/mintlify-docs/essentials/reusable-snippets.mdx +0 -110
  105. package/mintlify-docs/essentials/settings.mdx +0 -318
  106. package/mintlify-docs/favicon.svg +0 -3
  107. package/mintlify-docs/frontend/introduction.mdx +0 -39
  108. package/mintlify-docs/getting-started.mdx +0 -267
  109. package/mintlify-docs/guides/custom-agent.mdx +0 -608
  110. package/mintlify-docs/guides/first-agent.mdx +0 -315
  111. package/mintlify-docs/images/admin_ui.png +0 -0
  112. package/mintlify-docs/images/contexts.png +0 -0
  113. package/mintlify-docs/images/create_agents.png +0 -0
  114. package/mintlify-docs/images/evals.png +0 -0
  115. package/mintlify-docs/images/graphql.png +0 -0
  116. package/mintlify-docs/images/graphql_api.png +0 -0
  117. package/mintlify-docs/images/hero-dark.png +0 -0
  118. package/mintlify-docs/images/hero-light.png +0 -0
  119. package/mintlify-docs/images/hero.png +0 -0
  120. package/mintlify-docs/images/knowledge_sources.png +0 -0
  121. package/mintlify-docs/images/mcp.png +0 -0
  122. package/mintlify-docs/images/scaling.png +0 -0
  123. package/mintlify-docs/index.mdx +0 -411
  124. package/mintlify-docs/logo/dark.svg +0 -9
  125. package/mintlify-docs/logo/light.svg +0 -9
  126. package/mintlify-docs/partners.mdx +0 -558
  127. package/mintlify-docs/products.mdx +0 -77
  128. package/mintlify-docs/snippets/snippet-intro.mdx +0 -4
  129. package/mintlify-docs/styles.css +0 -207
  130. package/ngrok.bash +0 -1
  131. package/ngrok.md +0 -6
  132. package/ngrok.yml +0 -10
  133. package/release.config.cjs +0 -15
  134. package/skills-lock.json +0 -10
  135. package/types/context-processor.ts +0 -45
  136. package/types/enums/eval-types.ts +0 -5
  137. package/types/enums/field-types.ts +0 -1
  138. package/types/enums/jobs.ts +0 -11
  139. package/types/enums/statistics.ts +0 -13
  140. package/types/exulu-table-definition.ts +0 -79
  141. package/types/file-types.ts +0 -18
  142. package/types/models/agent-session.ts +0 -27
  143. package/types/models/agent.ts +0 -68
  144. package/types/models/context.ts +0 -53
  145. package/types/models/embedding.ts +0 -17
  146. package/types/models/eval-run.ts +0 -40
  147. package/types/models/exulu-agent-tool-config.ts +0 -11
  148. package/types/models/item.ts +0 -21
  149. package/types/models/job.ts +0 -8
  150. package/types/models/project.ts +0 -16
  151. package/types/models/rate-limiter-rules.ts +0 -7
  152. package/types/models/test-case.ts +0 -25
  153. package/types/models/tool.ts +0 -9
  154. package/types/models/user-role.ts +0 -12
  155. package/types/models/user.ts +0 -20
  156. package/types/models/variable.ts +0 -8
  157. package/types/models/vector-methods.ts +0 -7
  158. package/types/provider-config.ts +0 -21
  159. package/types/queue-config.ts +0 -16
  160. package/types/rbac-rights-modes.ts +0 -1
  161. package/types/statistics.ts +0 -20
  162. package/types/workflow.ts +0 -31
  163. /package/ee/{documents → python/documents}/THIRD_PARTY_LICENSES/docling.txt +0 -0
  164. /package/ee/{documents/processing → python}/requirements.txt +0 -0
@@ -1,650 +0,0 @@
1
- ---
2
- title: "Configuration"
3
- description: "Complete guide to configuring ExuluQueues for background job processing"
4
- ---
5
-
6
- ## Queue registration
7
-
8
- Register queues using the `ExuluQueues.register()` method:
9
-
10
- ```typescript
11
- ExuluQueues.register(
12
- name: string,
13
- concurrency: { worker: number; queue: number },
14
- ratelimit?: number,
15
- timeoutInSeconds?: number
16
- )
17
- ```
18
-
19
- ## Parameters
20
-
21
- ### name
22
-
23
- <ParamField path="name" type="string" required>
24
- Unique queue name. Used to identify the queue and its workers.
25
- </ParamField>
26
-
27
- ```typescript
28
- ExuluQueues.register("embeddings", ...)
29
- ```
30
-
31
- <Note>
32
- Queue names should be descriptive and unique across your application. Common patterns: `embeddings`, `document-processing`, `data-sync`, `agent-workflows`.
33
- </Note>
34
-
35
- ### concurrency
36
-
37
- <ParamField path="concurrency" type="object" required>
38
- Concurrency configuration with worker and queue levels
39
- </ParamField>
40
-
41
- ```typescript
42
- concurrency: {
43
- worker: number, // Jobs per worker process
44
- queue: number // Global max jobs across all workers
45
- }
46
- ```
47
-
48
- #### concurrency.worker
49
-
50
- <ParamField path="concurrency.worker" type="number" required>
51
- Number of jobs a single worker process can handle simultaneously
52
- </ParamField>
53
-
54
- ```typescript
55
- concurrency: {
56
- worker: 5 // Each worker handles 5 jobs at once
57
- }
58
- ```
59
-
60
- **Guidelines:**
61
- - CPU-bound tasks: 1-2 per CPU core
62
- - I/O-bound tasks: 5-20 per worker
63
- - Memory-intensive tasks: 1-5 per worker
64
-
65
- #### concurrency.queue
66
-
67
- <ParamField path="concurrency.queue" type="number" required>
68
- Maximum jobs processing globally across all workers
69
- </ParamField>
70
-
71
- ```typescript
72
- concurrency: {
73
- queue: 10 // Max 10 jobs across all workers
74
- }
75
- ```
76
-
77
- **Guidelines:**
78
- - API rate limits: Match your API's concurrency limit
79
- - Database load: 5-50 depending on DB capacity
80
- - External service: Check service documentation
81
-
82
- ### ratelimit
83
-
84
- <ParamField path="ratelimit" type="number" default={1}>
85
- Maximum jobs processed per second (default: 1)
86
- </ParamField>
87
-
88
- ```typescript
89
- ExuluQueues.register(
90
- "api-calls",
91
- { worker: 5, queue: 10 },
92
- 10 // Process 10 jobs per second
93
- )
94
- ```
95
-
96
- **Use cases:**
97
- - API rate limits (e.g., OpenAI: 10 req/sec)
98
- - Cost control (limit LLM calls per second)
99
- - Database protection (prevent overload)
100
-
101
- ### timeoutInSeconds
102
-
103
- <ParamField path="timeoutInSeconds" type="number" default={180}>
104
- Maximum execution time for a job in seconds (default: 180 = 3 minutes)
105
- </ParamField>
106
-
107
- ```typescript
108
- ExuluQueues.register(
109
- "long-running-tasks",
110
- { worker: 2, queue: 5 },
111
- 1,
112
- 600 // 10 minute timeout
113
- )
114
- ```
115
-
116
- **Guidelines:**
117
- - Quick tasks: 30-60 seconds
118
- - Document processing: 120-300 seconds
119
- - Data sync: 300-1800 seconds
120
- - Large embeddings: 600-3600 seconds
121
-
122
- ## Configuration examples
123
-
124
- ### Embeddings generation queue
125
-
126
- ```typescript
127
- import { ExuluQueues } from "@exulu/backend";
128
-
129
- const embeddingsQueue = ExuluQueues.register(
130
- "embeddings",
131
- {
132
- worker: 5, // 5 concurrent embeddings per worker
133
- queue: 10 // Max 10 embeddings globally
134
- },
135
- 10, // 10 jobs/second (OpenAI rate limit)
136
- 300 // 5 minute timeout
137
- );
138
-
139
- // Use with ExuluEmbedder
140
- const embedder = new ExuluEmbedder({
141
- id: "openai_embedder",
142
- name: "OpenAI Embeddings",
143
- provider: "openai",
144
- model: "text-embedding-3-small",
145
- vectorDimensions: 1536,
146
- queue: await embeddingsQueue.use()
147
- });
148
- ```
149
-
150
- ### Document processing queue
151
-
152
- ```typescript
153
- const processingQueue = ExuluQueues.register(
154
- "document-processing",
155
- {
156
- worker: 3, // 3 documents per worker
157
- queue: 5 // Max 5 documents globally
158
- },
159
- 5, // 5 jobs/second
160
- 600 // 10 minute timeout for large docs
161
- );
162
-
163
- // Use with ExuluContext processor
164
- const context = new ExuluContext({
165
- id: "documents",
166
- processor: {
167
- name: "PDF Text Extractor",
168
- config: {
169
- queue: await processingQueue.use(),
170
- trigger: "onInsert",
171
- generateEmbeddings: true
172
- },
173
- execute: async ({ item, utils }) => {
174
- const text = await utils.storage.extractText(item.document_s3key);
175
- return { ...item, content: text };
176
- }
177
- }
178
- });
179
- ```
180
-
181
- ### Data sync queue
182
-
183
- ```typescript
184
- const syncQueue = ExuluQueues.register(
185
- "github-sync",
186
- {
187
- worker: 1, // Sequential processing
188
- queue: 1 // One sync at a time
189
- },
190
- 1, // 1 job/second (no rush)
191
- 1800 // 30 minute timeout
192
- );
193
-
194
- // Use with ExuluContext source
195
- const context = new ExuluContext({
196
- id: "github_issues",
197
- sources: [{
198
- id: "github",
199
- name: "GitHub Issues Sync",
200
- description: "Syncs issues from GitHub",
201
- config: {
202
- schedule: "0 */6 * * *", // Every 6 hours
203
- queue: await syncQueue.use(),
204
- retries: 3,
205
- backoff: {
206
- type: "exponential",
207
- delay: 2000
208
- }
209
- },
210
- execute: async ({ exuluConfig }) => {
211
- const issues = await fetchGitHubIssues();
212
- return issues.map(issue => ({
213
- external_id: issue.id,
214
- name: issue.title,
215
- content: issue.body
216
- }));
217
- }
218
- }]
219
- });
220
- ```
221
-
222
- ### Agent workflow queue
223
-
224
- ```typescript
225
- const workflowQueue = ExuluQueues.register(
226
- "agent-workflows",
227
- {
228
- worker: 10, // 10 concurrent agent tasks per worker
229
- queue: 20 // Max 20 agent tasks globally
230
- },
231
- 20, // 20 jobs/second
232
- 300 // 5 minute timeout
233
- );
234
-
235
- // Use with ExuluAgent
236
- const agent = new ExuluAgent({
237
- id: "assistant",
238
- name: "Assistant",
239
- type: "agent",
240
- description: "AI assistant",
241
- provider: "openai",
242
- config: { /* ... */ },
243
- workflows: {
244
- enabled: true,
245
- queue: await workflowQueue.use()
246
- },
247
- capabilities: { text: true, images: [], files: [], audio: [], video: [] }
248
- });
249
- ```
250
-
251
- ### High-throughput queue
252
-
253
- ```typescript
254
- const highThroughputQueue = ExuluQueues.register(
255
- "bulk-operations",
256
- {
257
- worker: 20, // 20 concurrent jobs per worker
258
- queue: 100 // Max 100 jobs globally
259
- },
260
- 50, // 50 jobs/second
261
- 60 // 1 minute timeout
262
- );
263
-
264
- // For fast, lightweight operations
265
- await queueConfig.queue.add("process-item", {
266
- itemId: "item-123"
267
- });
268
- ```
269
-
270
- ### Low-throughput, long-running queue
271
-
272
- ```typescript
273
- const batchQueue = ExuluQueues.register(
274
- "nightly-batch",
275
- {
276
- worker: 1, // Sequential processing
277
- queue: 1 // One at a time
278
- },
279
- 0.1, // 1 job every 10 seconds
280
- 7200 // 2 hour timeout
281
- );
282
-
283
- // For expensive, long-running batch jobs
284
- await queueConfig.queue.add("nightly-report", {
285
- date: new Date()
286
- });
287
- ```
288
-
289
- ### API-constrained queue
290
-
291
- ```typescript
292
- // OpenAI has rate limits: 10 req/sec for most tiers
293
- const openaiQueue = ExuluQueues.register(
294
- "openai-api",
295
- {
296
- worker: 3, // 3 concurrent requests per worker
297
- queue: 10 // Max 10 requests globally
298
- },
299
- 9, // 9 req/sec (under the limit)
300
- 120 // 2 minute timeout
301
- );
302
-
303
- // Anthropic has different limits: 5 req/sec
304
- const anthropicQueue = ExuluQueues.register(
305
- "anthropic-api",
306
- {
307
- worker: 2,
308
- queue: 5
309
- },
310
- 4, // 4 req/sec (under the limit)
311
- 120
312
- );
313
- ```
314
-
315
- ## Queue configuration object
316
-
317
- After registration, call `.use()` to get the queue configuration:
318
-
319
- ```typescript
320
- const myQueue = ExuluQueues.register("my-queue", ...);
321
-
322
- const config = await myQueue.use();
323
-
324
- // config has this structure:
325
- type ExuluQueueConfig = {
326
- queue: Queue; // BullMQ Queue instance
327
- ratelimit: number; // Jobs per second
328
- timeoutInSeconds: number; // Job timeout
329
- concurrency: {
330
- worker: number; // Per-worker concurrency
331
- queue: number; // Global concurrency
332
- };
333
- retries?: number; // Retry count (optional)
334
- backoff?: { // Backoff strategy (optional)
335
- type: "exponential" | "linear";
336
- delay: number; // Delay in milliseconds
337
- };
338
- };
339
- ```
340
-
341
- ## Retry and backoff configuration
342
-
343
- Configure retries and backoff in ExuluContext sources:
344
-
345
- ```typescript
346
- const context = new ExuluContext({
347
- id: "data",
348
- sources: [{
349
- id: "api-source",
350
- name: "API Data Source",
351
- description: "Fetches data from external API",
352
- config: {
353
- queue: await myQueue.use(),
354
- retries: 5, // Retry up to 5 times
355
- backoff: {
356
- type: "exponential", // exponential or linear
357
- delay: 1000 // Start with 1 second delay
358
- }
359
- },
360
- execute: async () => {
361
- const data = await fetchFromAPI();
362
- return data;
363
- }
364
- }]
365
- });
366
- ```
367
-
368
- ### Exponential backoff
369
-
370
- Delay doubles after each retry:
371
-
372
- ```typescript
373
- backoff: {
374
- type: "exponential",
375
- delay: 1000 // 1s, 2s, 4s, 8s, 16s, ...
376
- }
377
- ```
378
-
379
- **Use for:** Temporary failures, API rate limits, transient network issues
380
-
381
- ### Linear backoff
382
-
383
- Fixed delay between retries:
384
-
385
- ```typescript
386
- backoff: {
387
- type: "linear",
388
- delay: 5000 // 5s, 5s, 5s, 5s, ...
389
- }
390
- ```
391
-
392
- **Use for:** Predictable delays, scheduled retry windows
393
-
394
- ## Concurrency tuning
395
-
396
- ### Start conservative
397
-
398
- Begin with low concurrency and increase gradually:
399
-
400
- ```typescript
401
- // Starting point
402
- ExuluQueues.register(
403
- "new-queue",
404
- { worker: 1, queue: 1 }, // Start with 1
405
- 1,
406
- 180
407
- );
408
-
409
- // After testing, increase
410
- ExuluQueues.register(
411
- "new-queue",
412
- { worker: 5, queue: 10 }, // Scale up
413
- 10,
414
- 180
415
- );
416
- ```
417
-
418
- ### Monitor and adjust
419
-
420
- Watch these metrics:
421
- - **CPU usage**: High CPU? Reduce worker concurrency
422
- - **Memory usage**: High memory? Reduce worker concurrency
423
- - **Queue depth**: Jobs piling up? Increase concurrency
424
- - **Error rate**: Many failures? Reduce concurrency or rate limit
425
-
426
- ### Concurrency patterns
427
-
428
- <Tabs>
429
- <Tab title="Balanced">
430
- ```typescript
431
- // Good for general-purpose queues
432
- concurrency: {
433
- worker: 5, // Moderate per-worker
434
- queue: 20 // Higher global limit
435
- }
436
- ```
437
-
438
- Multiple workers can run without hitting global limit.
439
- </Tab>
440
-
441
- <Tab title="Worker-heavy">
442
- ```typescript
443
- // Good for I/O-bound tasks with no global constraints
444
- concurrency: {
445
- worker: 20, // High per-worker
446
- queue: 1000 // Very high global limit
447
- }
448
- ```
449
-
450
- Workers max out before hitting global limit.
451
- </Tab>
452
-
453
- <Tab title="Queue-constrained">
454
- ```typescript
455
- // Good for external API rate limits
456
- concurrency: {
457
- worker: 2, // Low per-worker
458
- queue: 10 // Strict global limit
459
- }
460
- ```
461
-
462
- Global limit enforced across all workers.
463
- </Tab>
464
-
465
- <Tab title="Sequential">
466
- ```typescript
467
- // Good for ordered processing or single-threaded tasks
468
- concurrency: {
469
- worker: 1,
470
- queue: 1
471
- }
472
- ```
473
-
474
- One job at a time, guaranteed order.
475
- </Tab>
476
- </Tabs>
477
-
478
- ## Rate limit strategies
479
-
480
- ### API-based
481
-
482
- Match your API provider's limits:
483
-
484
- ```typescript
485
- // OpenAI Tier 4: 10,000 req/min = 166 req/sec
486
- ExuluQueues.register("openai", { worker: 10, queue: 100 }, 150);
487
-
488
- // Anthropic Pro: 5 req/sec
489
- ExuluQueues.register("anthropic", { worker: 2, queue: 5 }, 4);
490
-
491
- // Google Gemini: 60 req/min = 1 req/sec
492
- ExuluQueues.register("gemini", { worker: 1, queue: 1 }, 0.9);
493
- ```
494
-
495
- ### Cost-based
496
-
497
- Control spending by limiting throughput:
498
-
499
- ```typescript
500
- // Limit expensive LLM calls
501
- ExuluQueues.register(
502
- "gpt4-calls",
503
- { worker: 1, queue: 2 },
504
- 0.5 // 0.5 jobs/sec = 1800 calls/hour
505
- );
506
-
507
- // Track costs:
508
- // 1800 calls/hr × $0.03/call = $54/hr max
509
- ```
510
-
511
- ### Database-based
512
-
513
- Prevent database overload:
514
-
515
- ```typescript
516
- // PostgreSQL can handle ~100-200 concurrent connections
517
- ExuluQueues.register(
518
- "db-queries",
519
- { worker: 10, queue: 50 },
520
- 100 // 100 queries/sec
521
- );
522
- ```
523
-
524
- ## Timeout configuration
525
-
526
- Set timeouts based on expected duration + buffer:
527
-
528
- ```typescript
529
- // Quick operations (embeddings)
530
- ExuluQueues.register("embeddings", { ... }, 10, 60); // 1 min
531
-
532
- // Medium operations (document parsing)
533
- ExuluQueues.register("parsing", { ... }, 5, 300); // 5 min
534
-
535
- // Long operations (data sync)
536
- ExuluQueues.register("sync", { ... }, 1, 1800); // 30 min
537
-
538
- // Very long operations (large batch jobs)
539
- ExuluQueues.register("batch", { ... }, 1, 7200); // 2 hours
540
- ```
541
-
542
- <Warning>
543
- Jobs that exceed the timeout are terminated and marked as failed. Ensure timeouts are realistic for your workload.
544
- </Warning>
545
-
546
- ## Redis configuration
547
-
548
- ExuluQueues requires Redis connection information:
549
-
550
- ```bash
551
- # .env file
552
- REDIS_HOST=localhost
553
- REDIS_PORT=6379
554
- REDIS_PASSWORD=your-password # Optional
555
- ```
556
-
557
- Or configure programmatically:
558
-
559
- ```typescript
560
- import { redisServer } from "@exulu/backend";
561
-
562
- redisServer.host = "localhost";
563
- redisServer.port = "6379";
564
- redisServer.password = "your-password"; // Optional
565
- ```
566
-
567
- ### Redis for production
568
-
569
- For production environments:
570
-
571
- ```bash
572
- # Managed Redis service
573
- REDIS_HOST=redis-12345.cloud.redislabs.com
574
- REDIS_PORT=12345
575
- REDIS_PASSWORD=your-secure-password
576
- ```
577
-
578
- Recommended providers:
579
- - Redis Cloud
580
- - AWS ElastiCache
581
- - Google Cloud Memorystore
582
- - Azure Cache for Redis
583
-
584
- ## Best practices
585
-
586
- <AccordionGroup>
587
- <Accordion title="One queue per purpose">
588
- Create separate queues for different workload types:
589
-
590
- ```typescript
591
- ExuluQueues.register("embeddings", ...);
592
- ExuluQueues.register("processing", ...);
593
- ExuluQueues.register("sync", ...);
594
- ```
595
-
596
- Benefits: Independent scaling, better monitoring, isolated failures
597
- </Accordion>
598
-
599
- <Accordion title="Match concurrency to resources">
600
- Consider available CPU, memory, and external service limits:
601
-
602
- ```typescript
603
- // 4 CPU cores → worker concurrency 4-8
604
- // 8 GB RAM → adjust based on job memory
605
- // API limit 10 req/sec → rate limit 9
606
- ```
607
- </Accordion>
608
-
609
- <Accordion title="Set realistic timeouts">
610
- Add buffer to expected duration:
611
-
612
- ```typescript
613
- // Expected: 30 seconds → Timeout: 60 seconds
614
- // Expected: 2 minutes → Timeout: 5 minutes
615
- ```
616
- </Accordion>
617
-
618
- <Accordion title="Use exponential backoff">
619
- For transient failures, exponential backoff is more effective:
620
-
621
- ```typescript
622
- backoff: {
623
- type: "exponential",
624
- delay: 1000 // 1s, 2s, 4s, 8s, 16s
625
- }
626
- ```
627
- </Accordion>
628
-
629
- <Accordion title="Monitor queue depth">
630
- If jobs pile up (high waiting count), increase concurrency or rate limit:
631
-
632
- ```typescript
633
- const counts = await config.queue.getJobCounts();
634
- if (counts.waiting > 1000) {
635
- // Consider increasing concurrency
636
- }
637
- ```
638
- </Accordion>
639
- </AccordionGroup>
640
-
641
- ## Next steps
642
-
643
- <CardGroup cols={2}>
644
- <Card title="API reference" icon="code" href="/core/exulu-queues/api-reference">
645
- Explore methods and properties
646
- </Card>
647
- <Card title="ExuluContext" icon="database" href="/core/exulu-context/introduction">
648
- Learn how contexts use queues
649
- </Card>
650
- </CardGroup>