zilmate 1.8.0 → 1.8.5

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 (315) hide show
  1. package/.agents/skills/copywriting/SKILL.md +252 -0
  2. package/.agents/skills/copywriting/evals/evals.json +111 -0
  3. package/.agents/skills/copywriting/references/copy-frameworks.md +344 -0
  4. package/.agents/skills/copywriting/references/natural-transitions.md +272 -0
  5. package/.agents/skills/firecrawl-deep-research/SKILL.md +108 -0
  6. package/.agents/skills/shadcn/SKILL.md +267 -0
  7. package/.agents/skills/shadcn/agents/openai.yml +5 -0
  8. package/.agents/skills/shadcn/assets/shadcn-small.png +0 -0
  9. package/.agents/skills/shadcn/assets/shadcn.png +0 -0
  10. package/.agents/skills/shadcn/cli.md +290 -0
  11. package/.agents/skills/shadcn/customization.md +209 -0
  12. package/.agents/skills/shadcn/evals/evals.json +47 -0
  13. package/.agents/skills/shadcn/mcp.md +105 -0
  14. package/.agents/skills/shadcn/registry.md +277 -0
  15. package/.agents/skills/shadcn/rules/base-vs-radix.md +306 -0
  16. package/.agents/skills/shadcn/rules/composition.md +195 -0
  17. package/.agents/skills/shadcn/rules/forms.md +192 -0
  18. package/.agents/skills/shadcn/rules/icons.md +101 -0
  19. package/.agents/skills/shadcn/rules/styling.md +162 -0
  20. package/.agents/skills/tavily-research/SKILL.md +100 -0
  21. package/.agents/skills/upstash/SKILL.md +48 -0
  22. package/.agents/skills/upstash/upstash-box-js/overview.md +243 -0
  23. package/.agents/skills/upstash/upstash-box-py/overview.md +275 -0
  24. package/.agents/skills/upstash/upstash-cli/overview.md +138 -0
  25. package/.agents/skills/upstash/upstash-qstash-js/advanced/callbacks.md +147 -0
  26. package/.agents/skills/upstash/upstash-qstash-js/advanced/deduplication.md +86 -0
  27. package/.agents/skills/upstash/upstash-qstash-js/advanced/dlq.md +164 -0
  28. package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
  29. package/.agents/skills/upstash/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
  30. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/local-development.md +106 -0
  31. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
  32. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
  33. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/schedules.md +177 -0
  34. package/.agents/skills/upstash/upstash-qstash-js/fundamentals/url-groups.md +127 -0
  35. package/.agents/skills/upstash/upstash-qstash-js/overview.md +81 -0
  36. package/.agents/skills/upstash/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
  37. package/.agents/skills/upstash/upstash-qstash-js/verification/receiver.md +213 -0
  38. package/.agents/skills/upstash/upstash-ratelimit-js/algorithms.md +84 -0
  39. package/.agents/skills/upstash/upstash-ratelimit-js/features.md +117 -0
  40. package/.agents/skills/upstash/upstash-ratelimit-js/methods-getting-started.md +77 -0
  41. package/.agents/skills/upstash/upstash-ratelimit-js/overview.md +26 -0
  42. package/.agents/skills/upstash/upstash-ratelimit-js/pricing-cost.md +146 -0
  43. package/.agents/skills/upstash/upstash-ratelimit-js/traffic-protection.md +77 -0
  44. package/.agents/skills/upstash/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
  45. package/.agents/skills/upstash/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
  46. package/.agents/skills/upstash/upstash-redis-js/advanced-features/scripting.md +124 -0
  47. package/.agents/skills/upstash/upstash-redis-js/data-structures/hashes.md +71 -0
  48. package/.agents/skills/upstash/upstash-redis-js/data-structures/json.md +133 -0
  49. package/.agents/skills/upstash/upstash-redis-js/data-structures/lists.md +72 -0
  50. package/.agents/skills/upstash/upstash-redis-js/data-structures/sets.md +90 -0
  51. package/.agents/skills/upstash/upstash-redis-js/data-structures/sorted-sets.md +126 -0
  52. package/.agents/skills/upstash/upstash-redis-js/data-structures/streams.md +196 -0
  53. package/.agents/skills/upstash/upstash-redis-js/data-structures/strings.md +73 -0
  54. package/.agents/skills/upstash/upstash-redis-js/migrations/from-ioredis.md +163 -0
  55. package/.agents/skills/upstash/upstash-redis-js/migrations/from-redis-node.md +205 -0
  56. package/.agents/skills/upstash/upstash-redis-js/overview.md +183 -0
  57. package/.agents/skills/upstash/upstash-redis-js/patterns/caching.md +58 -0
  58. package/.agents/skills/upstash/upstash-redis-js/patterns/distributed-locks.md +130 -0
  59. package/.agents/skills/upstash/upstash-redis-js/patterns/leaderboard.md +134 -0
  60. package/.agents/skills/upstash/upstash-redis-js/patterns/rate-limiting.md +187 -0
  61. package/.agents/skills/upstash/upstash-redis-js/patterns/session-management.md +217 -0
  62. package/.agents/skills/upstash/upstash-redis-js/performance/batching-operations.md +76 -0
  63. package/.agents/skills/upstash/upstash-redis-js/performance/data-serialization.md +134 -0
  64. package/.agents/skills/upstash/upstash-redis-js/performance/error-handling.md +118 -0
  65. package/.agents/skills/upstash/upstash-redis-js/performance/pipeline-optimization.md +105 -0
  66. package/.agents/skills/upstash/upstash-redis-js/performance/redis-replicas.md +14 -0
  67. package/.agents/skills/upstash/upstash-redis-js/performance/ttl-expiration.md +32 -0
  68. package/.agents/skills/upstash/upstash-redis-js/search/adapters.md +99 -0
  69. package/.agents/skills/upstash/upstash-redis-js/search/commands/aggregating.md +234 -0
  70. package/.agents/skills/upstash/upstash-redis-js/search/commands/aliases.md +76 -0
  71. package/.agents/skills/upstash/upstash-redis-js/search/commands/index-management.md +124 -0
  72. package/.agents/skills/upstash/upstash-redis-js/search/commands/querying.md +315 -0
  73. package/.agents/skills/upstash/upstash-redis-js/search/overview.md +155 -0
  74. package/.agents/skills/upstash/upstash-redis-start/overview.md +71 -0
  75. package/.agents/skills/upstash/upstash-search-js/overview.md +48 -0
  76. package/.agents/skills/upstash/upstash-search-js/quick-start.md +158 -0
  77. package/.agents/skills/upstash/upstash-search-js/sdk-overview.md +158 -0
  78. package/.agents/skills/upstash/upstash-vector-js/features/filtering-and-metadata.md +82 -0
  79. package/.agents/skills/upstash/upstash-vector-js/features/index-structure.md +193 -0
  80. package/.agents/skills/upstash/upstash-vector-js/features/namespaces.md +32 -0
  81. package/.agents/skills/upstash/upstash-vector-js/overview.md +44 -0
  82. package/.agents/skills/upstash/upstash-vector-js/sdk-methods.md +210 -0
  83. package/.agents/skills/upstash/upstash-workflow-js/agents.md +248 -0
  84. package/.agents/skills/upstash/upstash-workflow-js/basics/client.md +180 -0
  85. package/.agents/skills/upstash/upstash-workflow-js/basics/context.md +230 -0
  86. package/.agents/skills/upstash/upstash-workflow-js/basics/serve.md +70 -0
  87. package/.agents/skills/upstash/upstash-workflow-js/features/flow-control.md +145 -0
  88. package/.agents/skills/upstash/upstash-workflow-js/features/invoke.md +97 -0
  89. package/.agents/skills/upstash/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
  90. package/.agents/skills/upstash/upstash-workflow-js/features/wait-for-event.md +97 -0
  91. package/.agents/skills/upstash/upstash-workflow-js/features/webhooks.md +79 -0
  92. package/.agents/skills/upstash/upstash-workflow-js/how-to/local-dev.md +177 -0
  93. package/.agents/skills/upstash/upstash-workflow-js/how-to/middleware.md +166 -0
  94. package/.agents/skills/upstash/upstash-workflow-js/how-to/migrations.md +201 -0
  95. package/.agents/skills/upstash/upstash-workflow-js/how-to/realtime.md +186 -0
  96. package/.agents/skills/upstash/upstash-workflow-js/overview.md +55 -0
  97. package/.agents/skills/upstash/upstash-workflow-js/rest-api.md +156 -0
  98. package/.agents/skills/upstash/upstash-workflow-js/troubleshooting.md +201 -0
  99. package/.agents/skills/upstash-box-js/SKILL.md +248 -0
  100. package/.agents/skills/upstash-box-py/SKILL.md +280 -0
  101. package/.agents/skills/upstash-cli/SKILL.md +143 -0
  102. package/.agents/skills/upstash-qstash-js/SKILL.md +86 -0
  103. package/.agents/skills/upstash-qstash-js/advanced/callbacks.md +147 -0
  104. package/.agents/skills/upstash-qstash-js/advanced/deduplication.md +86 -0
  105. package/.agents/skills/upstash-qstash-js/advanced/dlq.md +164 -0
  106. package/.agents/skills/upstash-qstash-js/advanced/multi-region/summary.md +388 -0
  107. package/.agents/skills/upstash-qstash-js/advanced/multi-region/verify-multi-region-setup.ts +388 -0
  108. package/.agents/skills/upstash-qstash-js/fundamentals/local-development.md +106 -0
  109. package/.agents/skills/upstash-qstash-js/fundamentals/publishing-messages.md +144 -0
  110. package/.agents/skills/upstash-qstash-js/fundamentals/queues-and-flow-control.md +148 -0
  111. package/.agents/skills/upstash-qstash-js/fundamentals/schedules.md +177 -0
  112. package/.agents/skills/upstash-qstash-js/fundamentals/url-groups.md +127 -0
  113. package/.agents/skills/upstash-qstash-js/verification/platform-specific/nextjs.md +171 -0
  114. package/.agents/skills/upstash-qstash-js/verification/receiver.md +213 -0
  115. package/.agents/skills/upstash-ratelimit-js/SKILL.md +31 -0
  116. package/.agents/skills/upstash-ratelimit-js/algorithms.md +84 -0
  117. package/.agents/skills/upstash-ratelimit-js/features.md +117 -0
  118. package/.agents/skills/upstash-ratelimit-js/methods-getting-started.md +77 -0
  119. package/.agents/skills/upstash-ratelimit-js/pricing-cost.md +146 -0
  120. package/.agents/skills/upstash-ratelimit-js/traffic-protection.md +77 -0
  121. package/.agents/skills/upstash-redis-js/SKILL.md +188 -0
  122. package/.agents/skills/upstash-redis-js/advanced-features/auto-pipeline.md +49 -0
  123. package/.agents/skills/upstash-redis-js/advanced-features/pipeline-and-transactions.md +42 -0
  124. package/.agents/skills/upstash-redis-js/advanced-features/scripting.md +124 -0
  125. package/.agents/skills/upstash-redis-js/data-structures/hashes.md +71 -0
  126. package/.agents/skills/upstash-redis-js/data-structures/json.md +133 -0
  127. package/.agents/skills/upstash-redis-js/data-structures/lists.md +72 -0
  128. package/.agents/skills/upstash-redis-js/data-structures/sets.md +90 -0
  129. package/.agents/skills/upstash-redis-js/data-structures/sorted-sets.md +126 -0
  130. package/.agents/skills/upstash-redis-js/data-structures/streams.md +196 -0
  131. package/.agents/skills/upstash-redis-js/data-structures/strings.md +73 -0
  132. package/.agents/skills/upstash-redis-js/migrations/from-ioredis.md +163 -0
  133. package/.agents/skills/upstash-redis-js/migrations/from-redis-node.md +205 -0
  134. package/.agents/skills/upstash-redis-js/patterns/caching.md +58 -0
  135. package/.agents/skills/upstash-redis-js/patterns/distributed-locks.md +130 -0
  136. package/.agents/skills/upstash-redis-js/patterns/leaderboard.md +134 -0
  137. package/.agents/skills/upstash-redis-js/patterns/rate-limiting.md +187 -0
  138. package/.agents/skills/upstash-redis-js/patterns/session-management.md +217 -0
  139. package/.agents/skills/upstash-redis-js/performance/batching-operations.md +76 -0
  140. package/.agents/skills/upstash-redis-js/performance/data-serialization.md +134 -0
  141. package/.agents/skills/upstash-redis-js/performance/error-handling.md +118 -0
  142. package/.agents/skills/upstash-redis-js/performance/pipeline-optimization.md +105 -0
  143. package/.agents/skills/upstash-redis-js/performance/redis-replicas.md +14 -0
  144. package/.agents/skills/upstash-redis-js/performance/ttl-expiration.md +32 -0
  145. package/.agents/skills/upstash-redis-js/search/adapters.md +99 -0
  146. package/.agents/skills/upstash-redis-js/search/commands/aggregating.md +234 -0
  147. package/.agents/skills/upstash-redis-js/search/commands/aliases.md +76 -0
  148. package/.agents/skills/upstash-redis-js/search/commands/index-management.md +124 -0
  149. package/.agents/skills/upstash-redis-js/search/commands/querying.md +315 -0
  150. package/.agents/skills/upstash-redis-js/search/overview.md +155 -0
  151. package/.agents/skills/upstash-redis-start/SKILL.md +76 -0
  152. package/.agents/skills/upstash-search-js/SKILL.md +53 -0
  153. package/.agents/skills/upstash-search-js/quick-start.md +158 -0
  154. package/.agents/skills/upstash-search-js/sdk-overview.md +158 -0
  155. package/.agents/skills/upstash-vector-js/SKILL.md +49 -0
  156. package/.agents/skills/upstash-vector-js/features/filtering-and-metadata.md +82 -0
  157. package/.agents/skills/upstash-vector-js/features/index-structure.md +193 -0
  158. package/.agents/skills/upstash-vector-js/features/namespaces.md +32 -0
  159. package/.agents/skills/upstash-vector-js/sdk-methods.md +210 -0
  160. package/.agents/skills/upstash-workflow-js/SKILL.md +60 -0
  161. package/.agents/skills/upstash-workflow-js/agents.md +248 -0
  162. package/.agents/skills/upstash-workflow-js/basics/client.md +180 -0
  163. package/.agents/skills/upstash-workflow-js/basics/context.md +230 -0
  164. package/.agents/skills/upstash-workflow-js/basics/serve.md +70 -0
  165. package/.agents/skills/upstash-workflow-js/features/flow-control.md +145 -0
  166. package/.agents/skills/upstash-workflow-js/features/invoke.md +97 -0
  167. package/.agents/skills/upstash-workflow-js/features/retries-failures-reliability.md +239 -0
  168. package/.agents/skills/upstash-workflow-js/features/wait-for-event.md +97 -0
  169. package/.agents/skills/upstash-workflow-js/features/webhooks.md +79 -0
  170. package/.agents/skills/upstash-workflow-js/how-to/local-dev.md +177 -0
  171. package/.agents/skills/upstash-workflow-js/how-to/middleware.md +166 -0
  172. package/.agents/skills/upstash-workflow-js/how-to/migrations.md +201 -0
  173. package/.agents/skills/upstash-workflow-js/how-to/realtime.md +186 -0
  174. package/.agents/skills/upstash-workflow-js/rest-api.md +156 -0
  175. package/.agents/skills/upstash-workflow-js/troubleshooting.md +201 -0
  176. package/dist/agents/coding.agent.d.ts +185 -42
  177. package/dist/agents/coding.agent.d.ts.map +1 -1
  178. package/dist/agents/coding.agent.js +42 -5
  179. package/dist/agents/coding.agent.js.map +1 -1
  180. package/dist/agents/manager.d.ts +216 -41
  181. package/dist/agents/manager.d.ts.map +1 -1
  182. package/dist/agents/manager.js +103 -140
  183. package/dist/agents/manager.js.map +1 -1
  184. package/dist/agents/security.agent.d.ts +3 -3
  185. package/dist/agents/swarm/development/lead.d.ts +3 -0
  186. package/dist/agents/swarm/development/lead.d.ts.map +1 -0
  187. package/dist/agents/swarm/development/lead.js +24 -0
  188. package/dist/agents/swarm/development/lead.js.map +1 -0
  189. package/dist/agents/swarm/main.d.ts +69 -0
  190. package/dist/agents/swarm/main.d.ts.map +1 -1
  191. package/dist/agents/swarm/main.js +65 -11
  192. package/dist/agents/swarm/main.js.map +1 -1
  193. package/dist/agents/swarm/registry.d.ts +2 -1
  194. package/dist/agents/swarm/registry.d.ts.map +1 -1
  195. package/dist/agents/swarm/registry.js +225 -95
  196. package/dist/agents/swarm/registry.js.map +1 -1
  197. package/dist/cli/composer.d.ts.map +1 -1
  198. package/dist/cli/composer.js +85 -30
  199. package/dist/cli/composer.js.map +1 -1
  200. package/dist/cli/confirm.d.ts +2 -2
  201. package/dist/cli/confirm.d.ts.map +1 -1
  202. package/dist/cli/confirm.js +373 -4
  203. package/dist/cli/confirm.js.map +1 -1
  204. package/dist/cli/doctor.d.ts +1 -0
  205. package/dist/cli/doctor.d.ts.map +1 -1
  206. package/dist/cli/doctor.js +47 -2
  207. package/dist/cli/doctor.js.map +1 -1
  208. package/dist/cli/format.d.ts +4 -0
  209. package/dist/cli/format.d.ts.map +1 -1
  210. package/dist/cli/format.js +352 -65
  211. package/dist/cli/format.js.map +1 -1
  212. package/dist/cli/interactive.d.ts.map +1 -1
  213. package/dist/cli/interactive.js +80 -2
  214. package/dist/cli/interactive.js.map +1 -1
  215. package/dist/cli/menu.d.ts.map +1 -1
  216. package/dist/cli/menu.js +93 -83
  217. package/dist/cli/menu.js.map +1 -1
  218. package/dist/cli/render.d.ts.map +1 -1
  219. package/dist/cli/render.js +2 -1
  220. package/dist/cli/render.js.map +1 -1
  221. package/dist/cli/setup.d.ts.map +1 -1
  222. package/dist/cli/setup.js +262 -27
  223. package/dist/cli/setup.js.map +1 -1
  224. package/dist/cli/swarm.d.ts.map +1 -1
  225. package/dist/cli/swarm.js +13 -10
  226. package/dist/cli/swarm.js.map +1 -1
  227. package/dist/cli/theme.d.ts +7 -1
  228. package/dist/cli/theme.d.ts.map +1 -1
  229. package/dist/cli/theme.js +4 -16
  230. package/dist/cli/theme.js.map +1 -1
  231. package/dist/cli/update.d.ts.map +1 -1
  232. package/dist/cli/update.js +27 -4
  233. package/dist/cli/update.js.map +1 -1
  234. package/dist/config/env.d.ts +3 -1
  235. package/dist/config/env.d.ts.map +1 -1
  236. package/dist/config/env.js +22 -2
  237. package/dist/config/env.js.map +1 -1
  238. package/dist/config/models.d.ts +1 -0
  239. package/dist/config/models.d.ts.map +1 -1
  240. package/dist/config/models.js +17 -1
  241. package/dist/config/models.js.map +1 -1
  242. package/dist/documents/pdf.d.ts.map +1 -1
  243. package/dist/documents/pdf.js +282 -22
  244. package/dist/documents/pdf.js.map +1 -1
  245. package/dist/documents/slides.d.ts.map +1 -1
  246. package/dist/documents/slides.js +160 -30
  247. package/dist/documents/slides.js.map +1 -1
  248. package/dist/index.js +73 -18
  249. package/dist/index.js.map +1 -1
  250. package/dist/memory/history.js +1 -1
  251. package/dist/observability/doctor.d.ts.map +1 -1
  252. package/dist/observability/doctor.js +3 -0
  253. package/dist/observability/doctor.js.map +1 -1
  254. package/dist/runtime/progress.d.ts +5 -1
  255. package/dist/runtime/progress.d.ts.map +1 -1
  256. package/dist/runtime/progress.js.map +1 -1
  257. package/dist/runtime/swarm.d.ts +1 -1
  258. package/dist/runtime/swarm.d.ts.map +1 -1
  259. package/dist/runtime/swarm.js +19 -3
  260. package/dist/runtime/swarm.js.map +1 -1
  261. package/dist/runtime/tool-utils.d.ts +2 -0
  262. package/dist/runtime/tool-utils.d.ts.map +1 -1
  263. package/dist/runtime/tool-utils.js +91 -0
  264. package/dist/runtime/tool-utils.js.map +1 -1
  265. package/dist/server.js +1 -1
  266. package/dist/server.js.map +1 -1
  267. package/dist/skills/loader.d.ts.map +1 -1
  268. package/dist/skills/loader.js +16 -0
  269. package/dist/skills/loader.js.map +1 -1
  270. package/dist/test-call.d.ts +2 -0
  271. package/dist/test-call.d.ts.map +1 -0
  272. package/dist/test-call.js +29 -0
  273. package/dist/test-call.js.map +1 -0
  274. package/dist/test-manager-call.d.ts +2 -0
  275. package/dist/test-manager-call.d.ts.map +1 -0
  276. package/dist/test-manager-call.js +138 -0
  277. package/dist/test-manager-call.js.map +1 -0
  278. package/dist/test-manager-filtered.d.ts +2 -0
  279. package/dist/test-manager-filtered.d.ts.map +1 -0
  280. package/dist/test-manager-filtered.js +130 -0
  281. package/dist/test-manager-filtered.js.map +1 -0
  282. package/dist/test-mcp-call.d.ts +2 -0
  283. package/dist/test-mcp-call.d.ts.map +1 -0
  284. package/dist/test-mcp-call.js +103 -0
  285. package/dist/test-mcp-call.js.map +1 -0
  286. package/dist/tools/composio.tool.d.ts +1 -1
  287. package/dist/tools/composio.tool.d.ts.map +1 -1
  288. package/dist/tools/composio.tool.js +7 -16
  289. package/dist/tools/composio.tool.js.map +1 -1
  290. package/dist/tools/daytona-browser.tool.js +1 -1
  291. package/dist/tools/daytona-browser.tool.js.map +1 -1
  292. package/dist/tools/executive.tool.d.ts +40 -0
  293. package/dist/tools/executive.tool.d.ts.map +1 -0
  294. package/dist/tools/executive.tool.js +74 -0
  295. package/dist/tools/executive.tool.js.map +1 -0
  296. package/dist/tools/filesystem.tool.d.ts +183 -40
  297. package/dist/tools/filesystem.tool.d.ts.map +1 -1
  298. package/dist/tools/filesystem.tool.js +564 -111
  299. package/dist/tools/filesystem.tool.js.map +1 -1
  300. package/dist/tools/mcp.tool.d.ts +56 -0
  301. package/dist/tools/mcp.tool.d.ts.map +1 -0
  302. package/dist/tools/mcp.tool.js +285 -0
  303. package/dist/tools/mcp.tool.js.map +1 -0
  304. package/dist/tools/osint.tool.d.ts +4 -4
  305. package/dist/tools/pentest.tool.d.ts +2 -2
  306. package/dist/tools/setup-assistant.tool.d.ts +1 -1
  307. package/dist/tools/setup-assistant.tool.js +1 -1
  308. package/dist/tools/setup-assistant.tool.js.map +1 -1
  309. package/dist/workspace/paths.d.ts +1 -0
  310. package/dist/workspace/paths.d.ts.map +1 -1
  311. package/dist/workspace/paths.js +3 -4
  312. package/dist/workspace/paths.js.map +1 -1
  313. package/package.json +8 -4
  314. package/scripts/postinstall.mjs +19 -4
  315. package/scripts/release-github.mjs +11 -11
@@ -0,0 +1,213 @@
1
+ # Receiver - Message Verification
2
+
3
+ ## Overview
4
+
5
+ The `Receiver` class verifies that incoming requests are genuinely from QStash by validating JWT signatures. This prevents unauthorized requests from reaching your endpoints.
6
+
7
+ ## Getting Your Signing Keys
8
+
9
+ Sign in to the [Upstash Console](https://console.upstash.com/qstash) and navigate to your QStash instance to find:
10
+
11
+ - **Current Signing Key**: Active key for signature verification
12
+ - **Next Signing Key**: Key to use after rotation
13
+
14
+ Store these as environment variables:
15
+
16
+ ```bash
17
+ QSTASH_CURRENT_SIGNING_KEY="your_current_key"
18
+ QSTASH_NEXT_SIGNING_KEY="your_next_key"
19
+ ```
20
+
21
+ ## Creating a Receiver Instance
22
+
23
+ ### Basic Setup
24
+
25
+ ```typescript
26
+ import { Receiver } from "@upstash/qstash";
27
+
28
+ const receiver = new Receiver({
29
+ currentSigningKey: process.env.QSTASH_CURRENT_SIGNING_KEY!,
30
+ nextSigningKey: process.env.QSTASH_NEXT_SIGNING_KEY!,
31
+ });
32
+ ```
33
+
34
+ ### Multi-Region Mode
35
+
36
+ If you're using multi-region QStash (with `QSTASH_REGION` environment variable set), signature verification requires additional configuration. The SDK automatically detects the region from the `upstash-region` header and uses region-specific signing keys.
37
+
38
+ > **Important:** Multi-region signature verification requires careful setup. See [Multi-Region Setup](../advanced/multi-region.md) for complete details on environment variables, region detection, and verification strategies.
39
+
40
+ ## Verifying Incoming Requests
41
+
42
+ ### Basic Verification
43
+
44
+ ```typescript
45
+ try {
46
+ await receiver.verify({
47
+ signature: request.headers.get("upstash-signature")!,
48
+ body: await request.text(),
49
+ });
50
+
51
+ // Request is valid - process it
52
+ return new Response("OK", { status: 200 });
53
+ } catch (error) {
54
+ // Invalid signature
55
+ return new Response("Unauthorized", { status: 401 });
56
+ }
57
+ ```
58
+
59
+ ### With URL Verification
60
+
61
+ For extra security, verify the request was sent to the correct URL:
62
+
63
+ ```typescript
64
+ await receiver.verify({
65
+ signature: request.headers.get("upstash-signature")!,
66
+ body: await request.text(),
67
+ url: "https://my-api.example.com/webhook",
68
+ });
69
+ ```
70
+
71
+ ### With Clock Tolerance
72
+
73
+ Handle minor clock differences between servers:
74
+
75
+ ```typescript
76
+ await receiver.verify({
77
+ signature: request.headers.get("upstash-signature")!,
78
+ body: await request.text(),
79
+ clockTolerance: 5, // Allow 5 seconds difference
80
+ });
81
+ ```
82
+
83
+ ## Required Headers
84
+
85
+ QStash sends these headers with every request:
86
+
87
+ - `Upstash-Signature`: JWT signature to verify
88
+
89
+ > **Note:** In multi-region mode, QStash also sends an `Upstash-Region` header. See [Multi-Region Setup](../advanced/multi-region.md) for details.
90
+
91
+ ## Handling Verification Failures
92
+
93
+ ### SignatureError
94
+
95
+ The `verify()` method throws `SignatureError` for invalid signatures:
96
+
97
+ ```typescript
98
+ import { Receiver, SignatureError } from "@upstash/qstash";
99
+
100
+ try {
101
+ await receiver.verify({
102
+ signature: request.headers.get("upstash-signature")!,
103
+ body: await request.text(),
104
+ });
105
+ } catch (error) {
106
+ if (error instanceof SignatureError) {
107
+ console.error("Invalid signature:", error.message);
108
+ return new Response("Invalid signature", { status: 401 });
109
+ }
110
+ throw error;
111
+ }
112
+ ```
113
+
114
+ ### Common Failure Reasons
115
+
116
+ 1. **Missing or wrong signing keys**
117
+ - Verify keys in Upstash Console match environment variables
118
+ 2. **Body mismatch**
119
+
120
+ - Ensure you pass the raw request body (not parsed JSON)
121
+ - Don't modify the body before verification
122
+
123
+ 3. **Expired signature**
124
+
125
+ - QStash signatures expire after 5 minutes
126
+ - Check server clock is synchronized
127
+ - Use `clockTolerance` if needed
128
+
129
+ 4. **URL mismatch**
130
+ - Ensure the `url` parameter matches the destination URL
131
+ - Include protocol, domain, and path
132
+
133
+ ## Key Rotation
134
+
135
+ The Receiver supports seamless key rotation:
136
+
137
+ 1. Verification tries `currentSigningKey` first
138
+ 2. If that fails, tries `nextSigningKey`
139
+ 3. Only throws error if both fail
140
+
141
+ To rotate keys:
142
+
143
+ 1. Set new key as `QSTASH_NEXT_SIGNING_KEY`
144
+ 2. Wait for all in-flight requests to complete
145
+ 3. Update `QSTASH_CURRENT_SIGNING_KEY` to the new key
146
+ 4. Generate a new `QSTASH_NEXT_SIGNING_KEY`
147
+
148
+ ## Best Practices
149
+
150
+ ### Always Verify
151
+
152
+ Never trust incoming requests without verification:
153
+
154
+ ```typescript
155
+ // ❌ Don't do this
156
+ app.post("/webhook", async (req) => {
157
+ const data = await req.json();
158
+ processWebhook(data); // Unverified!
159
+ });
160
+
161
+ // ✅ Do this
162
+ app.post("/webhook", async (req) => {
163
+ const body = await req.text();
164
+
165
+ await receiver.verify({
166
+ signature: req.headers.get("upstash-signature")!,
167
+ body,
168
+ });
169
+
170
+ const data = JSON.parse(body);
171
+ processWebhook(data);
172
+ });
173
+ ```
174
+
175
+ ### Use Environment Variables
176
+
177
+ Never hardcode signing keys:
178
+
179
+ ```typescript
180
+ // ❌ Don't do this
181
+ const receiver = new Receiver({
182
+ currentSigningKey: "sig_abc123...",
183
+ });
184
+
185
+ // ✅ Do this
186
+ const receiver = new Receiver({
187
+ currentSigningKey: process.env.QSTASH_CURRENT_SIGNING_KEY!,
188
+ nextSigningKey: process.env.QSTASH_NEXT_SIGNING_KEY!,
189
+ });
190
+ ```
191
+
192
+ ### Read Body Once
193
+
194
+ Request bodies can only be read once. Save it for reuse:
195
+
196
+ ```typescript
197
+ const body = await request.text();
198
+
199
+ // Verify with raw body
200
+ await receiver.verify({
201
+ signature: request.headers.get("upstash-signature")!,
202
+ body,
203
+ });
204
+
205
+ // Parse after verification
206
+ const data = JSON.parse(body);
207
+ ```
208
+
209
+ ## Platform-Specific Verification
210
+
211
+ For framework-specific implementations, see:
212
+
213
+ - [Next.js Verification](platform-specific/nextjs.md)
@@ -0,0 +1,31 @@
1
+ ---
2
+ name: upstash-ratelimit-js
3
+ description: Lightweight guidance for using the Upstash Redis RateLimit TypeScript/JavaScript SDK, including setup steps, basic usage, and pointers to advanced algorithm, features, pricing, and traffic‑protection docs.
4
+ ---
5
+
6
+ # Rate Limit TS SDK
7
+
8
+ ## Quick Start
9
+ - Install the SDK and connect to Redis.
10
+ - Create a rate limiter and apply it to incoming operations.
11
+
12
+ Example:
13
+ ```ts
14
+ import { Ratelimit } from "@upstash/ratelimit";
15
+ import { Redis } from "@upstash/redis";
16
+
17
+ const redis = new Redis({ url: "<url>", token: "<token>" });
18
+ const limiter = new Ratelimit({ redis, limiter: Ratelimit.slidingWindow(5, "10s") });
19
+
20
+ const { success } = await limiter.limit("user-id");
21
+ if (!success) {
22
+ // throttled
23
+ }
24
+ ```
25
+
26
+ ## Other Skill Files
27
+ - **algorithms.md**: Describes all available rate‑limiting algorithms and how they behave.
28
+ - **pricing-cost.md**: Explains pricing, Redis cost implications, and operational considerations.
29
+ - **features.md**: Lists SDK features such as prefixes, custom keys, and behavioral options.
30
+ - **methods-getting-started.md**: Full method reference for the SDK's API and getting started guide.
31
+ - **traffic-protection.md**: Guidance on applying rate limiting for traffic shaping, abuse prevention, and protection patterns.
@@ -0,0 +1,84 @@
1
+ # Ratelimiting Algorithms
2
+
3
+ This documentation explains the three algorithms supported by the ratelimit‑ts SDK: Fixed Window, Sliding Window, and Token Bucket. It focuses on practical usage, pitfalls, and choosing the right algorithm.
4
+
5
+ ## Fixed Window
6
+
7
+ Divides time into fixed periods (for example, 10‑second windows). Requests increment a counter for the current window and are rejected once the limit is exceeded.
8
+
9
+ **Pitfalls**
10
+ - Burst leakage: many requests at the boundary may bypass intended behavior.
11
+ - Stampedes: large client populations may all retry at the start of a window.
12
+ - Reset time is based on fixed boundaries, not on the first request.
13
+
14
+ **When to use**
15
+ - When performance and low computational cost are important.
16
+ - When small inaccuracies at boundaries are acceptable.
17
+
18
+ **Example**
19
+ ```ts
20
+ // 10 requests per 10 seconds
21
+ const regional = new Ratelimit({
22
+ redis: Redis.fromEnv(),
23
+ limiter: Ratelimit.fixedWindow(10, "10 s"),
24
+ });
25
+
26
+ const multi = new MultiRegionRatelimit({
27
+ redis: [new Redis({/* auth */}), new Redis({/* auth */})],
28
+ limiter: MultiRegionRatelimit.fixedWindow(10, "10 s"),
29
+ });
30
+ ```
31
+
32
+ ## Sliding Window
33
+
34
+ Uses rolling time windows to smooth boundary behavior. Counts requests in the previous window proportionally based on elapsed time.
35
+
36
+ **Pitfalls**
37
+ - Slightly more expensive to compute and approximate.
38
+ - Assumes uniform distribution of past requests.
39
+ - In multi‑region mode, generates many Redis commands and can slow down operations.
40
+ - Reset time exposed via `limit` and `getRemaining` is only the start of the next full window.
41
+
42
+ **When to use**
43
+ - When smoother behavior around window boundaries is important.
44
+ - Avoid in multi‑region setups if command count is a concern.
45
+
46
+ **Example**
47
+ ```ts
48
+ // 10 requests per 10 seconds
49
+ const regional = new Ratelimit({
50
+ redis: Redis.fromEnv(),
51
+ limiter: Ratelimit.slidingWindow(10, "10 s"),
52
+ });
53
+
54
+ // Multi-region is possible but inefficient
55
+ const multi = new MultiRegionRatelimit({
56
+ redis: [new Redis({/* auth */}), new Redis({/* auth */})],
57
+ limiter: MultiRegionRatelimit.slidingWindow(10, "10 s"),
58
+ });
59
+ ```
60
+
61
+ ## Token Bucket
62
+
63
+ Maintains a bucket of tokens that refill at a defined rate. Each request consumes one token; if none remain, requests are rejected.
64
+
65
+ **Advantages**
66
+ - Smooths bursts naturally.
67
+ - Allows high initial burst capacity (`maxTokens > refillRate`).
68
+
69
+ **Pitfalls**
70
+ - Higher computational cost.
71
+ - Not yet supported for multi‑region.
72
+
73
+ **When to use**
74
+ - When smoothing request traffic and allowing controlled bursts is important.
75
+
76
+ **Example**
77
+ ```ts
78
+ // Bucket with max 10 tokens, refilling 5 tokens every 10s
79
+ const ratelimit = new Ratelimit({
80
+ redis: Redis.fromEnv(),
81
+ limiter: Ratelimit.tokenBucket(5, "10 s", 10),
82
+ analytics: true,
83
+ });
84
+ ```
@@ -0,0 +1,117 @@
1
+ # Features
2
+
3
+ This Skill documents the core features of the Upstash Rate Limiter for TypeScript. It highlights how to apply caching, timeouts, analytics, multiple limit strategies, dynamic limits, and multi-region setups.
4
+
5
+ ## Caching
6
+
7
+ Caching prevents unnecessary Redis calls when identifiers are already blocked.
8
+
9
+ Key points:
10
+ - Use an in-memory `Map<string, number>` as `ephemeralCache`.
11
+ - Default: a new `Map()` is created automatically.
12
+ - Disable by setting `ephemeralCache: false`.
13
+ - Works only when the cache or rate limiter is created outside serverless handlers.
14
+ - Responses blocked by cache return `reason: cacheBlock`.
15
+
16
+ Example:
17
+ ```ts
18
+ const cache = new Map();
19
+ const ratelimit = new Ratelimit({
20
+ limiter: Ratelimit.slidingWindow(10, "10 s"),
21
+ ephemeralCache: cache,
22
+ });
23
+ ```
24
+
25
+ ## Timeout
26
+
27
+ A timeout allows requests to proceed if Redis is slow or unreachable.
28
+ - Default timeout: 5 seconds
29
+ - On timeout success, `reason` reflects this
30
+
31
+ Example:
32
+ ```ts
33
+ const ratelimit = new Ratelimit({
34
+ redis: Redis.fromEnv(),
35
+ limiter: Ratelimit.slidingWindow(10, "10 s"),
36
+ timeout: 1000,
37
+ });
38
+ ```
39
+
40
+ ## Analytics & Dashboard
41
+
42
+ Analytics collect counts of success/blocked requests.
43
+ - Disabled by default; enable via `analytics: true`
44
+ - Data is viewable in the Upstash Rate Limit Dashboard
45
+ - In edge runtimes, ensure analytics requests complete using `pending` from `limit()`
46
+
47
+ Example:
48
+ ```ts
49
+ const { pending } = await ratelimit.limit("id");
50
+ context.waitUntil(pending);
51
+ ```
52
+
53
+ ## Using Multiple Limits
54
+
55
+ Different user tiers can use different limiters.
56
+
57
+ Example:
58
+ ```ts
59
+ const ratelimit = {
60
+ free: new Ratelimit({ prefix: "free", limiter: Ratelimit.slidingWindow(10, "10s") }),
61
+ paid: new Ratelimit({ prefix: "paid", limiter: Ratelimit.slidingWindow(60, "10s") }),
62
+ };
63
+
64
+ await ratelimit.free.limit(ip);
65
+ await ratelimit.paid.limit(userId);
66
+ ```
67
+
68
+ ## Custom Rates
69
+
70
+ Specify how many tokens to subtract per request using `rate`.
71
+
72
+ Example:
73
+ ```ts
74
+ await ratelimit.limit("identifier", { rate: batchSize });
75
+ ```
76
+
77
+ ## Multi Region
78
+
79
+ Multi-region rate limiting provides lower latency and state replication via CRDTs.
80
+ - Uses multiple Redis instances
81
+ - Trades strict accuracy for global performance
82
+
83
+ Example:
84
+ ```ts
85
+ const ratelimit = new MultiRegionRatelimit({
86
+ redis: [redisUS, redisEU],
87
+ limiter: MultiRegionRatelimit.slidingWindow(10, "10 s"),
88
+ });
89
+
90
+ const { pending } = await ratelimit.limit("id");
91
+ context.waitUntil(pending);
92
+ ```
93
+
94
+ ## Dynamic Limits
95
+
96
+ Update rate limits at runtime without recreating the limiter.
97
+ - Works only for single-region limiters (fixedWindow, slidingWindow, tokenBucket)
98
+
99
+ Example:
100
+ ```ts
101
+ const ratelimit = new Ratelimit({
102
+ redis: Redis.fromEnv(),
103
+ limiter: Ratelimit.slidingWindow(10, "10s"),
104
+ dynamicLimits: true,
105
+ });
106
+
107
+ await ratelimit.setDynamicLimit({ limit: 5 });
108
+ const current = await ratelimit.getDynamicLimit();
109
+ await ratelimit.setDynamicLimit({ limit: false });
110
+ ```
111
+
112
+ ## Common Pitfalls
113
+
114
+ - Forgetting to place the cache outside serverless handlers disables effective caching.
115
+ - Not calling `context.waitUntil(pending)` in edge runtimes may cause lost analytics/sync requests.
116
+ - Multi-region setups cannot guarantee strict limit enforcement.
117
+ - Dynamic limits do not work with multi-region limiters.
@@ -0,0 +1,77 @@
1
+ # Upstash Ratelimit Methods (TypeScript)
2
+
3
+ This document provides a focused, practical reference for all Ratelimit methods. Each section includes direct examples, usage patterns, and common pitfalls.
4
+
5
+ ## limit
6
+ Primary method for checking and consuming tokens.
7
+
8
+ ```ts
9
+ const { success, remaining, reset, reason, pending } = await ratelimit.limit(
10
+ identifier,
11
+ {
12
+ rate: 2, // optional: consume N tokens
13
+ ip: req.ip, // optional: used for deny‑list checks
14
+ userAgent: ua, // optional
15
+ country: geo?.country,
16
+ }
17
+ );
18
+
19
+ if (!success) return "blocked";
20
+
21
+ // In Cloudflare/Vercel Edge, flush async work
22
+ context.waitUntil(pending);
23
+ ```
24
+
25
+ Notes:
26
+ - `rate` lets a request consume more than 1 token.
27
+ - `reason` can be: `timeout`, `cacheBlock`, `denyList`, or undefined.
28
+ - When analytics or MultiRegion is enabled, **always handle `pending`** in serverless environments.
29
+
30
+ ## blockUntilReady
31
+ Waits for a request to become allowed instead of rejecting immediately.
32
+
33
+ ```ts
34
+ const { success } = await ratelimit.blockUntilReady("id", 30_000);
35
+ if (!success) return "still blocked after timeout";
36
+ ```
37
+
38
+ ## resetUsedTokens
39
+ Clears the state for an identifier.
40
+
41
+ ```ts
42
+ await ratelimit.resetUsedTokens("user123");
43
+ ```
44
+
45
+ Useful when granting temporary resets or admin overrides.
46
+
47
+ ## getRemaining
48
+ Read-only view of remaining quota.
49
+
50
+ ```ts
51
+ const { remaining, reset } = await ratelimit.getRemaining("user123");
52
+ ```
53
+
54
+ Common use cases:
55
+ - Dashboard queries
56
+ - Showing users their remaining quota
57
+
58
+ ## setDynamicLimit
59
+ Overrides the global limit at runtime.
60
+
61
+ ```ts
62
+ await ratelimit.setDynamicLimit({ limit: 5 }); // set
63
+ await ratelimit.setDynamicLimit({ limit: false }); // remove
64
+ ```
65
+
66
+ Notes:
67
+ - Requires `dynamicLimits: true` in constructor.
68
+ - Applies to all future rate checks.
69
+
70
+ ## getDynamicLimit
71
+ Fetch the currently active dynamic limit.
72
+
73
+ ```ts
74
+ const { dynamicLimit } = await ratelimit.getDynamicLimit();
75
+ ```
76
+
77
+ Returns `null` when no override is active.
@@ -0,0 +1,146 @@
1
+ # Pricing & Cost Considerations for Ratelimit Operations
2
+
3
+ This document explains how Redis command costs vary across Ratelimit algorithms, cache states, and optional features. Use it to reason about latency, throughput, and pricing impacts when designing systems with Upstash Ratelimit.
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ Redis command usage depends on:
10
+ - Algorithm type (Fixed Window, Sliding Window, Token Bucket)
11
+ - Algorithm state for a given identifier (first request, intermediate, rate‑limited)
12
+ - Cache hit/miss in the runtime environment
13
+ - Optional features (deny lists, analytics, dynamic limits, multi‑region replication)
14
+
15
+ A Global Upstash Redis setup multiplies write commands by `(1 + readRegionCount)` and adds 1 extra command when analytics is enabled.
16
+
17
+ ---
18
+
19
+ ## Algorithm States
20
+
21
+ Each identifier (e.g., an IP or user ID) has an associated state:
22
+ - **First**: No existing key; creates state and sets expiry
23
+ - **Intermediate**: Key exists; normal operation
24
+ - **Rate‑Limited**: Request blocked; may avoid Redis if cache contains an unexpired block timestamp
25
+
26
+ Cache hits allow skipping Redis entirely for rate‑limited requests.
27
+
28
+ ---
29
+
30
+ ## Cache Behavior
31
+
32
+ - **Hit**: Identifier found in in‑memory cache → request may be denied without Redis calls.
33
+ - **Miss**: Cache empty or value does not indicate a block → algorithm consults Redis.
34
+
35
+ Only rate‑limited results populate the cache.
36
+
37
+ ---
38
+
39
+ ## Command Costs by Operation
40
+
41
+ ### `limit()`
42
+ Costs depend on algorithm, cache state, and identifier state.
43
+
44
+ **Fixed Window:**
45
+ - First: 3 commands (EVAL, INCR, PEXPIRE)
46
+ - Intermediate: 2 commands (EVAL, INCR)
47
+ - Rate‑limited miss: 2 commands (EVAL, INCR)
48
+ - Rate‑limited hit: 0 commands
49
+
50
+ **Sliding Window:**
51
+ - First: 5 commands (EVAL, GET, GET, INCR, PEXPIRE)
52
+ - Intermediate: 4 commands (EVAL, GET, GET, INCR)
53
+ - Rate‑limited miss: 3 commands (EVAL, GET, GET)
54
+ - Rate‑limited hit: 0 commands
55
+
56
+ **Token Bucket:**
57
+ - First/Intermediate: 4 commands (EVAL, HMGET, HSET, PEXPIRE)
58
+ - Rate‑limited miss: 2 commands (EVAL, HMGET)
59
+ - Rate‑limited hit: 0 commands
60
+
61
+ ### `getRemaining()`
62
+ Always deterministic, no cache effects:
63
+ - Fixed Window: 2 commands (EVAL, GET)
64
+ - Sliding Window: 3 commands (EVAL, GET, GET)
65
+ - Token Bucket: 2 commands (EVAL, HMGET)
66
+
67
+ ### `resetUsedTokens()`
68
+ Starts with SCAN and deletes all matching keys:
69
+ - Fixed Window: 3 commands (EVAL, SCAN, DEL)
70
+ - Sliding Window: 4 commands (EVAL, SCAN, DEL, DEL)
71
+ - Token Bucket: 3 commands (EVAL, SCAN, DEL)
72
+
73
+ ### `blockUntilReady()`
74
+ Same cost model as `limit()`.
75
+
76
+ ---
77
+
78
+ ## Optional Features Impact
79
+
80
+ ### Deny List
81
+ Adds **2 commands per `limit()` call**:
82
+ - One `SMISMEMBER` check
83
+ - One TTL fetch for deny list validity
84
+
85
+ Auto‑IP deny list refresh uses **9 commands once per day** (first limit call after 02:00 UTC).
86
+
87
+ A deny‑listed identifier is cached for a minute, skipping Redis for subsequent checks.
88
+
89
+ ### Analytics
90
+ Adds **1 Redis command per `limit()`** via `ZINCRBY`.
91
+
92
+ ### Dynamic Limits
93
+ Adds **1 command** to each `limit()` and `getRemaining()` call.
94
+ - `setDynamicLimit()` = 1 command
95
+ - `getDynamicLimit()` = 1 command
96
+
97
+ ### Multi‑Region
98
+ Effective cost becomes:
99
+ ```
100
+ (1 + readRegionCount) * writeCommandCount + readCommandCount
101
+ +1 if analytics is enabled
102
+ ```
103
+
104
+ ---
105
+
106
+ ## Example Usage
107
+
108
+ ```ts
109
+ import { Ratelimit } from "@upstash/ratelimit";
110
+ import { Redis } from "@upstash/redis";
111
+
112
+ const redis = new Redis({ url: process.env.UPSTASH_URL!, token: process.env.UPSTASH_TOKEN! });
113
+
114
+ const limiter = new Ratelimit({
115
+ redis,
116
+ limiter: Ratelimit.slidingWindow(10, "60 s"),
117
+ analytics: true, // adds +1 ZINCRBY per call
118
+ enableProtection: true, // adds +2 per call
119
+ dynamicLimits: true // adds +1 per call
120
+ });
121
+
122
+ async function handle(ip) {
123
+ const { success, reset } = await limiter.limit(ip);
124
+ if (!success) {
125
+ return { status: 429, retryAfter: reset - Date.now() };
126
+ }
127
+
128
+ const remaining = await limiter.getRemaining(ip);
129
+ return { status: 200, remaining };
130
+ }
131
+ ```
132
+
133
+ This example shows all cost‑impacting features enabled. Sliding Window + deny list + analytics + dynamic limits can increase the base 4–5 command cost per `limit()`.
134
+
135
+ ---
136
+
137
+ ## Common Pitfalls
138
+
139
+ - **Ignoring cold starts**: Serverless environments often start with empty caches → initial calls incur higher Redis usage.
140
+ - **Using Sliding Window when cost‑sensitive**: It requires multiple GET operations, making it the most expensive algorithm.
141
+ - **Unexpected multi‑region amplification**: Write commands scale with region count; cost can rise significantly.
142
+ - **Assuming deny list is free**: Even when no identifier is blocked, two extra commands execute per request.
143
+
144
+ ---
145
+
146
+ This file provides an operational reference for estimating Redis usage and optimizing Ratelimit performance and cost.