<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Kartikeya Rao — writing</title><description>Kartikeya Rao is a security researcher and software developer. Notes on vulnerabilities, fixes, and the software built in between.</description><link>https://kartikeyarao.com/</link><language>en</language><item><title>Scoping every query to the tenant</title><link>https://kartikeyarao.com/writing/tenant-scoped-queries/</link><guid isPermaLink="true">https://kartikeyarao.com/writing/tenant-scoped-queries/</guid><description>A cross-tenant read in a billing API, why it slipped through review, and the three layers that now stop it.</description><pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate><content:encoded>&lt;aside class=&quot;callout callout-note&quot;&gt;
&lt;p class=&quot;callout-label&quot;&gt;Note&lt;/p&gt;
&lt;p&gt;Sample post. It’s here to show how write-ups look on this site. Replace it with your own.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Multi-tenant apps have one rule that matters more than the rest: a request from one organisation must never see another’s data. This bug broke that rule in the most common way there is. An invoice lookup trusted the ID in the URL and never checked who was asking.&lt;/p&gt;
&lt;h2 id=&quot;what-went-wrong&quot;&gt;What went wrong&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#what-went-wrong&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The handler loaded an invoice by primary key. Authentication was in place, so every caller was a real, signed-in user. The query just never asked whether that user belonged to the organisation that owned the invoice.&lt;/p&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;src/routes/invoices.ts&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;ts&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; getInvoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Request&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; ctx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Context&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; ctx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;params&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;findUnique&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; } });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; notFound&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; Response&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;It passed review because it &lt;em&gt;looks&lt;/em&gt; complete. There’s a not-found branch, the route sits behind the auth middleware, and the ORM call is idiomatic. What’s missing is a single field.&lt;/p&gt;
&lt;aside class=&quot;callout callout-important&quot;&gt;
&lt;p class=&quot;callout-label&quot;&gt;Important&lt;/p&gt;
&lt;p&gt;Authentication tells you &lt;em&gt;who&lt;/em&gt; is asking. Authorization decides &lt;em&gt;what&lt;/em&gt; they may see. Middleware usually handles the first, and every query has to handle the second.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2 id=&quot;the-fix&quot;&gt;The fix&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#the-fix&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Scope the lookup to the caller’s organisation, and return the same &lt;code&gt;404&lt;/code&gt; whether the invoice doesn’t exist or belongs to someone else. Different responses would let an outsider tell which IDs are real.&lt;/p&gt;
&lt;figure class=&quot;code has-title has-ln&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;src/routes/invoices.ts&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;ts&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black has-diff&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;export&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; function&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; getInvoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;req&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Request&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; ctx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Context&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; ctx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;params&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff remove&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;findUnique&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;({ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;where&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; } });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; db&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;findFirst&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;({ &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;    where&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: { &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;, &lt;/span&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;orgId&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;ctx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;session&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;orgId&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; }, &lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line diff add&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;  });&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;  if&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; notFound&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;  return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; Response&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;json&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Try the copy button on that block. You get the code as it reads after the change, without the removed line.&lt;/p&gt;
&lt;h2 id=&quot;defence-in-depth&quot;&gt;Defence in depth&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#defence-in-depth&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;One scoped query fixes one route. Two more layers keep the next route from making the same mistake.&lt;/p&gt;
&lt;h3 id=&quot;row-level-security-in-postgres&quot;&gt;Row-level security in Postgres&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#row-level-security-in-postgres&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Even if application code forgets the filter, the database refuses to return other tenants’ rows:&lt;/p&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;migrations/0042_invoice_rls.sql&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;sql&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;sql&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;alter&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; table&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; invoice &lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;enable&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; row&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; level&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; security&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;create&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; policy&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; tenant_isolation &lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;on&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; invoice&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;  using&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; (org_id &lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; current_setting(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;app.org_id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;)::uuid);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The app sets &lt;code&gt;app.org_id&lt;/code&gt; at the start of every transaction, from the verified session and never from the request body.&lt;/p&gt;
&lt;h3 id=&quot;a-test-that-fails-loudly&quot;&gt;A test that fails loudly&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#a-test-that-fails-loudly&quot;&gt;#&lt;/a&gt;&lt;/h3&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;test/invoices.test.ts&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;ts&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;ts&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;an invoice from another org is indistinguishable from a missing one&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;&apos;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; async&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; ()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; seedOrg&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; seedOrg&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; seedInvoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;  const &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; await&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; asUser&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;a&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;owner&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;get&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;/api/invoices/&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;${&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;invoice&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;id&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B5695977;--shiki-dark:#C98A7D77&quot;&gt;`&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;  expect&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;res&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;status&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;toBe&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt;404&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#takeaways&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;div class=&quot;table-wrap&quot; tabindex=&quot;0&quot;&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Layer&lt;/th&gt;&lt;th&gt;Catches&lt;/th&gt;&lt;th&gt;Cost&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Scoped query&lt;/td&gt;&lt;td&gt;This route&lt;/td&gt;&lt;td&gt;One field&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Postgres RLS&lt;/td&gt;&lt;td&gt;Every query, including new ones&lt;/td&gt;&lt;td&gt;One policy per table&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tenant tests&lt;/td&gt;&lt;td&gt;Regressions before they ship&lt;/td&gt;&lt;td&gt;A few seeded fixtures&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;The client patched within six weeks and asked for a retest before disclosure. Thanks to their team for the quick turnaround.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#footnote-label&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Details that could identify the client have been changed. The shape of the bug and the fix are real. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><category>websec</category><category>multi-tenant</category></item><item><title>A token-bucket rate limiter in 60 lines of Rust</title><link>https://kartikeyarao.com/writing/rust-token-bucket/</link><guid isPermaLink="true">https://kartikeyarao.com/writing/rust-token-bucket/</guid><description>The smallest rate limiter I trust in production, why a token bucket beats a fixed window, and how it compares to the Go version.</description><pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Sign-in endpoints without a rate limit are one of the most common findings in the reports I write. So here’s the limiter I reach for: small enough to read in one sitting, and correct under concurrency.&lt;/p&gt;
&lt;h2 id=&quot;why-a-token-bucket&quot;&gt;Why a token bucket&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#why-a-token-bucket&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A fixed window (“100 requests per minute”) has a known weakness. A client can send 100 requests at 12:00:59 and another 100 at 12:01:00, which is 200 requests in two seconds. A token bucket smooths that out. Tokens refill continuously, and each request spends one.&lt;/p&gt;
&lt;h2 id=&quot;the-code&quot;&gt;The code&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#the-code&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;code has-title has-ln&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;src/limiter.rs&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;rust&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;time&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Instant&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; struct&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Bucket&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    last&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Instant&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Bucket&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; Self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;        Self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; as&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; last&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Instant&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; try_take&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;&amp;#x26;mut&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Instant&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;        let&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; elapsed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;duration_since&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;as_secs_f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;tokens &lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;tokens &lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; elapsed&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;min&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line highlighted&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;last &lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;        if&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;tokens &lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;&gt;=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;            self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;tokens &lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;-=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;            true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;        }&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; else&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;            false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The highlighted lines are the whole algorithm. Everything else is bookkeeping.&lt;/p&gt;
&lt;p&gt;For many keys (one bucket per IP or per account), wrap it in a sharded map so threads don’t fight over a single lock:&lt;/p&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;src/keyed.rs&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;rust&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;rust&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; dashmap&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;DashMap&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;use&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; std&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;net&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;IpAddr&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;pub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; struct&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Limiter&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    buckets&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; DashMap&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;&amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;IpAddr&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Bucket&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; u32&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;    refill&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; f64&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;impl&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; Limiter&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;    pub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; fn&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; check&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; ip&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; IpAddr&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; -&gt;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;        self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;buckets&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;entry&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;ip&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;or_insert_with&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;||&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; Bucket&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;::&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;new&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt;self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; self&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;refill&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;            .&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;try_take&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;the-go-version-for-comparison&quot;&gt;The Go version, for comparison&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#the-go-version-for-comparison&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;limiter.go&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;go&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;func&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; (&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b &lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2E8F82;--shiki-dark:#5DA994&quot;&gt;Bucket&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; TryTake&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; bool&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;	b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;mu&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;Lock&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;	defer&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;mu&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;Unlock&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;	now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; :=&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; time&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;Now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;	b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; min&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;now&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;Sub&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;).&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;Seconds&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;()&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;refill&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;	b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;last&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; now&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;	if&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt; b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt; &amp;#x3C;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 1&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;		return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; false&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;	b&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B07D48;--shiki-dark:#BD976A&quot;&gt;tokens&lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;--&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;	return&lt;/span&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Same algorithm, different ergonomics. Go makes the lock explicit. Rust’s &lt;code&gt;&amp;#x26;mut self&lt;/code&gt; forces you to decide who owns the bucket before it compiles.&lt;/p&gt;
&lt;h2 id=&quot;configuration&quot;&gt;Configuration&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#configuration&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;config/limits.yaml&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;yaml&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;yaml&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;limits&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;  sign_in&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;    capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 5&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; # burst&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;    refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 0.1&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A0ADA0;--shiki-dark:#758575DD&quot;&gt; # one attempt every 10s after that&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;  password_reset&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;    capacity&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#998418;--shiki-dark:#B8A965&quot;&gt;    refill_per_sec&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#2F798A;--shiki-dark:#4C9A91&quot;&gt; 0.0167&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;h2 id=&quot;numbers&quot;&gt;Numbers&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#numbers&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Measured on a laptop, single process, 8 threads hammering 10,000 distinct keys:&lt;/p&gt;
&lt;div class=&quot;table-wrap&quot; tabindex=&quot;0&quot;&gt;
























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Implementation&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;Checks / sec&lt;/th&gt;&lt;th align=&quot;right&quot;&gt;p99 latency&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Rust, &lt;code&gt;DashMap&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;41.2 M&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;180 ns&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Rust, one &lt;code&gt;Mutex&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;6.8 M&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;2.1 µs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Go, &lt;code&gt;sync.Map&lt;/code&gt;&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;19.5 M&lt;/td&gt;&lt;td align=&quot;right&quot;&gt;410 ns&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;
&lt;aside class=&quot;callout callout-tip&quot;&gt;
&lt;p class=&quot;callout-label&quot;&gt;Tip&lt;/p&gt;
&lt;p&gt;Rate-limit by account &lt;em&gt;and&lt;/em&gt; by IP. IP alone punishes everyone behind a shared NAT, and account alone lets an attacker spread guesses across many usernames.&lt;/p&gt;
&lt;/aside&gt;</content:encoded><category>rust</category><category>engineering</category></item><item><title>Five minutes with your response headers</title><link>https://kartikeyarao.com/writing/response-headers/</link><guid isPermaLink="true">https://kartikeyarao.com/writing/response-headers/</guid><description>A quick pass over the HTTP headers every site should send, how to check your own, and a config that gets you most of the way.</description><pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Most sites I look at are missing at least two of these. The check takes five minutes, and the fix is usually a few lines of server config.&lt;/p&gt;
&lt;h2 id=&quot;check-what-you-send&quot;&gt;Check what you send&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#check-what-you-send&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Run this against your own site. Commands have a &lt;code&gt;$&lt;/code&gt; prompt, and the rest is output.&lt;/p&gt;
&lt;figure class=&quot;code is-shell is-session&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-lang&quot;&gt;terminal&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;console&quot;&gt;&lt;code&gt;&lt;span class=&quot;line cmd&quot;&gt;&lt;span class=&quot;prompt&quot; aria-hidden=&quot;true&quot;&gt;$ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;curl -sI https://example.com&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt;HTTP/2 200&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt;content-type: text/html; charset=utf-8&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt;strict-transport-security: max-age=63072000; includeSubDomains; preload&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt;x-content-type-options: nosniff&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#005CC5;--shiki-dark:#79B8FF&quot;&gt;referrer-policy: strict-origin-when-cross-origin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line cmd&quot;&gt;&lt;span class=&quot;prompt&quot; aria-hidden=&quot;true&quot;&gt;$ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;curl -sI https://example.com &lt;/span&gt;&lt;span style=&quot;--shiki-light:#AB5959;--shiki-dark:#CB7676&quot;&gt;|&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; grep&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -i&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; content-security-policy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;The copy button on that block copies just the two commands, without prompts or output. Paste them straight into your terminal.&lt;/p&gt;
&lt;p&gt;Quick quiz: which important header is missing from the output above? Answer: &lt;span class=&quot;redact&quot; tabindex=&quot;0&quot; role=&quot;button&quot; aria-expanded=&quot;false&quot; title=&quot;Hidden. Click to reveal.&quot;&gt;Content-Security-Policy&lt;/span&gt;. The second command printed nothing.&lt;/p&gt;
&lt;h2 id=&quot;the-headers-that-matter&quot;&gt;The headers that matter&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#the-headers-that-matter&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Strict-Transport-Security&lt;/code&gt;&lt;/strong&gt; makes browsers use HTTPS only, even when someone types &lt;code&gt;http://&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Content-Security-Policy&lt;/code&gt;&lt;/strong&gt; restricts where scripts, styles and frames can load from. It’s the strongest defence against XSS you can deploy without code changes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;&lt;/strong&gt; stops browsers from guessing file types.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Referrer-Policy&lt;/code&gt;&lt;/strong&gt; keeps full URLs, including tokens in query strings, from leaking to other sites.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Permissions-Policy&lt;/code&gt;&lt;/strong&gt; turns off browser features you don’t use, such as camera, microphone and geolocation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;a-starting-config&quot;&gt;A starting config&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#a-starting-config&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;figure class=&quot;code has-title&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-title&quot;&gt;/etc/nginx/snippets/security-headers.conf&lt;/span&gt;&lt;span class=&quot;code-lang&quot;&gt;nginx&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;nginx&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;add_header &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;Strict-Transport-Security &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;&quot;max-age=63072000; includeSubDomains; preload&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; always&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;add_header &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;Content-Security-Policy &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;&quot;default-src &apos;self&apos;; img-src &apos;self&apos; data:; object-src &apos;none&apos;; base-uri &apos;none&apos;; frame-ancestors &apos;none&apos;&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; always&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;add_header &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;X-Content-Type-Options &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;&quot;nosniff&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; always&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;add_header &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;Referrer-Policy &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;&quot;strict-origin-when-cross-origin&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; always&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span style=&quot;--shiki-light:#1E754F;--shiki-dark:#4D9375&quot;&gt;add_header &lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt;Permissions-Policy &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;&quot;camera=(), microphone=(), geolocation=()&quot;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#393A34;--shiki-dark:#DBD7CACC&quot;&gt; always&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;aside class=&quot;callout callout-warning&quot;&gt;
&lt;p class=&quot;callout-label&quot;&gt;Warning&lt;/p&gt;
&lt;p&gt;Roll out CSP with &lt;code&gt;Content-Security-Policy-Report-Only&lt;/code&gt; first. A strict policy on a site with inline scripts will break it, and you want to find that out from reports, not from users.&lt;/p&gt;
&lt;/aside&gt;
&lt;p&gt;Reload and check again:&lt;/p&gt;
&lt;figure class=&quot;code is-shell is-session&quot;&gt;&lt;figcaption class=&quot;code-head&quot;&gt;&lt;span class=&quot;code-lang&quot;&gt;terminal&lt;/span&gt;&lt;button type=&quot;button&quot; class=&quot;code-copy&quot; data-copy=&quot;&quot; aria-label=&quot;Copy code&quot;&gt;Copy&lt;/button&gt;&lt;/figcaption&gt;&lt;pre class=&quot;astro-code astro-code-themes vitesse-light vitesse-black&quot; style=&quot;--shiki-light:#393a34;--shiki-dark:#dbd7cacc;--shiki-light-bg:#ffffff;--shiki-dark-bg:#000&quot; tabindex=&quot;0&quot; data-language=&quot;bash&quot;&gt;&lt;code&gt;&lt;span class=&quot;line cmd&quot;&gt;&lt;span class=&quot;prompt&quot; aria-hidden=&quot;true&quot;&gt;$ &lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; nginx&lt;/span&gt;&lt;span style=&quot;--shiki-light:#A65E2B;--shiki-dark:#C99076&quot;&gt; -t&lt;/span&gt;&lt;span style=&quot;--shiki-light:#999999;--shiki-dark:#444444&quot;&gt; &amp;#x26;&amp;#x26;&lt;/span&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt; sudo&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; systemctl&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; reload&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; nginx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line out&quot;&gt;&lt;span style=&quot;--shiki-light:#59873A;--shiki-dark:#80A665&quot;&gt;nginx:&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; configuration&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; file&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; /etc/nginx/nginx.conf&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; test&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; is&lt;/span&gt;&lt;span style=&quot;--shiki-light:#B56959;--shiki-dark:#C98A7D&quot;&gt; successful&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;
&lt;p&gt;Press &lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;Shift&lt;/kbd&gt; + &lt;kbd&gt;I&lt;/kbd&gt; in your browser, open the Network tab, and click the document request to see the same headers without a terminal.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#footnote-label&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;On macOS it’s &lt;kbd&gt;⌘&lt;/kbd&gt; + &lt;kbd&gt;⌥&lt;/kbd&gt; + &lt;kbd&gt;I&lt;/kbd&gt;. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded><category>websec</category><category>checklist</category></item><item><title>What a year of writing security reports taught me</title><link>https://kartikeyarao.com/writing/writing-reports/</link><guid isPermaLink="true">https://kartikeyarao.com/writing/writing-reports/</guid><description>Findings get fixed when the report is written for the person who has to fix them.</description><pubDate>Wed, 10 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A finding that nobody fixes is only a note. Over the past year I’ve written a lot of reports, and whether a bug gets fixed depends less on its severity than on how clearly it’s explained.&lt;/p&gt;
&lt;h2 id=&quot;write-for-the-person-fixing-it&quot;&gt;Write for the person fixing it&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#write-for-the-person-fixing-it&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;The reader is usually a developer who didn’t write the vulnerable code and has a sprint full of other work. They need three things, in this order: what’s wrong, why it matters to &lt;em&gt;this&lt;/em&gt; business, and exactly what to change.&lt;/p&gt;
&lt;h2 id=&quot;one-finding-one-fix&quot;&gt;One finding, one fix&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#one-finding-one-fix&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;When a finding says “improve input validation”, it stays open forever. When it names the file, the function and the change, it’s closed by Friday.&lt;/p&gt;
&lt;h2 id=&quot;severity-is-a-conversation&quot;&gt;Severity is a conversation&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#severity-is-a-conversation&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CVSS gives you a number. The client knows their business better than you do, so ask before you rate. A medium-severity bug in their payments flow can matter more than a high in an internal tool.&lt;/p&gt;
&lt;h2 id=&quot;retest-everything&quot;&gt;Retest everything&lt;a class=&quot;anchor&quot; aria-hidden=&quot;true&quot; tabindex=&quot;-1&quot; href=&quot;#retest-everything&quot;&gt;#&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;A fix that hasn’t been retested is a guess. Every engagement I run now ends with a retest, and about one in five fixes needs a second attempt.&lt;/p&gt;</content:encoded><category>writing</category><category>consulting</category></item></channel></rss>