<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Loadcurl Blog</title>
        <link>https://docs.loadcurl.com/blog/</link>
        <description>Practical guides on API load testing from the Loadcurl team.</description>
        <lastBuildDate>Sun, 20 Sep 2026 00:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Personal vs Team Workspace for Load Testing]]></title>
            <link>https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/</link>
            <guid>https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/</guid>
            <pubDate>Sun, 20 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How Loadcurl personal and company workspaces differ — domains, shared quota, roles, and when to upgrade from solo testing to a team.]]></description>
            <content:encoded><![CDATA[<p>Loadcurl organizes everything around a <strong>workspace</strong> (organization): tests, reports, domains, request quota, and billing. You always have exactly <strong>one active</strong> workspace.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="personal-workspace">Personal workspace<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#personal-workspace" class="hash-link" aria-label="Direct link to Personal workspace" title="Direct link to Personal workspace" translate="no">​</a></h2>
<p>Created automatically when you register.</p>
<ul>
<li class="">You are the only member (<strong>Owner</strong>)</li>
<li class="">Up to <strong>1</strong> verified domain</li>
<li class="">Quota and billing are yours alone</li>
<li class="">Sidebar: Dashboard, Tests, Domains, Plan, Usage, Account, Support</li>
</ul>
<p>Ideal for solo engineers validating an API from the browser.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="company-workspace">Company workspace<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#company-workspace" class="hash-link" aria-label="Direct link to Company workspace" title="Direct link to Company workspace" translate="no">​</a></h2>
<p>Created when you <strong>upgrade</strong> from Account, or when you <strong>invite</strong> someone from a personal workspace.</p>
<ul>
<li class="">Roles: <strong>Owner</strong>, <strong>Admin</strong>, <strong>Member</strong></li>
<li class="">Up to <strong>10</strong> verified domains (app, API, staging, …)</li>
<li class=""><strong>Shared</strong> request quota and plan</li>
<li class="">Extra <strong>Organization</strong> nav for members</li>
<li class="">Tests show as team history</li>
</ul>
<p>Conversion is <strong>one-way</strong>. You cannot turn a company back into personal.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="side-by-side">Side-by-side<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#side-by-side" class="hash-link" aria-label="Direct link to Side-by-side" title="Direct link to Side-by-side" translate="no">​</a></h2>
<table><thead><tr><th></th><th>Personal</th><th>Company</th></tr></thead><tbody><tr><td>Members</td><td>Only you</td><td>Owner / Admin / Member</td></tr><tr><td>Domains</td><td>1</td><td>Up to 10</td></tr><tr><td>Quota</td><td>Solo</td><td>Shared pool</td></tr><tr><td>Invites</td><td>N/A</td><td>Owner/Admin invite Admin or Member</td></tr><tr><td>Best for</td><td>Solo rehearsal</td><td>Launch teams</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-upgrade">When to upgrade<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#when-to-upgrade" class="hash-link" aria-label="Direct link to When to upgrade" title="Direct link to When to upgrade" translate="no">​</a></h2>
<p>Upgrade when you need any of:</p>
<ul>
<li class="">Teammates to start runs or view reports without sharing a login</li>
<li class="">Multiple verified hosts</li>
<li class="">One shared monthly request pool and Razorpay plan</li>
<li class="">Clear Owner/Admin checkout vs Member run access</li>
</ul>
<p>You can upgrade and remain the only member — invites are optional.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="roles-in-practice">Roles in practice<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#roles-in-practice" class="hash-link" aria-label="Direct link to Roles in practice" title="Direct link to Roles in practice" translate="no">​</a></h2>
<ul>
<li class=""><strong>Owner / Admin</strong> — invite, manage domains, Razorpay checkout</li>
<li class=""><strong>Member</strong> — run tests, view usage; cannot check out</li>
<li class="">Invites go to email with a 7-day accept link; invitee must use that same email</li>
<li class="">Owner cannot leave until ownership is transferred</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quota-implication-for-teams">Quota implication for teams<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#quota-implication-for-teams" class="hash-link" aria-label="Direct link to Quota implication for teams" title="Direct link to Quota implication for teams" translate="no">​</a></h2>
<p>Starting a test holds <code>duration × RPS</code> on the <strong>shared</strong> wallet. Coordinate large rehearsals on <strong>Usage</strong> so two peak runs do not collide. Unused requests still do not carry over at period end.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-upgrade">How to upgrade<a href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/#how-to-upgrade" class="hash-link" aria-label="Direct link to How to upgrade" title="Direct link to How to upgrade" translate="no">​</a></h2>
<ol>
<li class="">Open <strong>Account</strong></li>
<li class=""><strong>Upgrade to a company</strong></li>
<li class="">Enter company name → confirm</li>
<li class="">Invite from <strong>Organization</strong> when ready</li>
</ol>
<p>Docs: <a class="" href="https://docs.loadcurl.com/docs/tutorial/organisation-management/">Workspaces</a> · <a class="" href="https://docs.loadcurl.com/docs/tutorial/billing/">Plan and usage</a></p>]]></content:encoded>
            <category>Loadcurl platform</category>
            <category>workspaces</category>
            <category>teams</category>
            <category>organization</category>
        </item>
        <item>
            <title><![CDATA[Pre-Launch Load Testing Checklist]]></title>
            <link>https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/</link>
            <guid>https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/</guid>
            <pubDate>Sat, 19 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical pre-launch API load testing checklist: domain verify, RPS targets, SLOs, staging safety, quota, reports, and abort criteria.]]></description>
            <content:encoded><![CDATA[<p>Use this checklist before a launch or big traffic moment. Print it, paste it in the runbook, or attach PDFs next to each checked item.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-scope">1. Scope<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#1-scope" class="hash-link" aria-label="Direct link to 1. Scope" title="Direct link to 1. Scope" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Critical HTTP endpoints listed (not “the whole monorepo”)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Expected peak <strong>RPS</strong> estimated per endpoint</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Latency SLOs written (percentile + threshold + RPS context)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Error / timeout budgets written</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-environment">2. Environment<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#2-environment" class="hash-link" aria-label="Direct link to 2. Environment" title="Direct link to 2. Environment" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Staging sized meaningfully (or scale factor documented)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Hostname <strong>verified</strong> in Loadcurl Domains</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Staging credentials only in the composer</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Production game day only if explicitly approved</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-request-realism">3. Request realism<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#3-request-realism" class="hash-link" aria-label="Direct link to 3. Request realism" title="Direct link to 3. Request realism" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->curl / Postman request matches production shape</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Auth path enabled (not a fake bypass)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Bodies and params representative</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->One endpoint per Loadcurl test (hottest first)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-load-profile">4. Load profile<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#4-load-profile" class="hash-link" aria-label="Direct link to 4. Load profile" title="Direct link to 4. Load profile" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Smoke run completed</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Ramp-up set (not always <code>0</code>)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Duration long enough for steady-state</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Quota hold <code>duration × RPS</code> fits <strong>Available</strong></li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Plan max RPS / duration sufficient</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-observability">5. Observability<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#5-observability" class="hash-link" aria-label="Direct link to 5. Observability" title="Direct link to 5. Observability" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->App, DB, queue, and dependency dashboards open</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->On-call informed for high RPS / prod windows</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Abort criteria agreed (error %, p99, customer impact)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-execute-the-ladder">6. Execute the ladder<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#6-execute-the-ladder" class="hash-link" aria-label="Direct link to 6. Execute the ladder" title="Direct link to 6. Execute the ladder" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Baseline (~50% peak)</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Target peak load</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Optional stress on staging</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Optional soak if leak risk is high</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-read-and-share">7. Read and share<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#7-read-and-share" class="hash-link" aria-label="Direct link to 7. Read and share" title="Direct link to 7. Read and share" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Throughput vs target reviewed</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Successful p95/p99 vs SLO</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->4xx/5xx/timeouts explained</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->PDF downloaded and attached to launch doc</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Bottlenecks filed or fixed before go-live</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="8-after-launch">8. After launch<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#8-after-launch" class="hash-link" aria-label="Direct link to 8. After launch" title="Direct link to 8. After launch" translate="no">​</a></h2>
<ul class="contains-task-list containsTaskList_mC6p">
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Keep a short regression profile for post-deploy runs</li>
<li class="task-list-item"><input type="checkbox" disabled=""> <!-- -->Revisit RPS assumptions with real traffic</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="loadcurl-quick-path">Loadcurl quick path<a href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/#loadcurl-quick-path" class="hash-link" aria-label="Direct link to Loadcurl quick path" title="Direct link to Loadcurl quick path" translate="no">​</a></h2>
<p>Register → verify domain → New test (paste curl/Postman) → set duration / ramp-up / RPS → Start → poll run → report → PDF.</p>
<p>Guides: <a class="" href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/">Staging vs Production</a> · <a class="" href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/">Read a report</a> · <a class="" href="https://docs.loadcurl.com/docs/tutorial/getting-started/">Getting started</a></p>]]></content:encoded>
            <category>Best practices</category>
            <category>checklist</category>
            <category>launch</category>
            <category>API load testing</category>
        </item>
        <item>
            <title><![CDATA[Load Testing GraphQL over HTTP]]></title>
            <link>https://docs.loadcurl.com/blog/load-testing-graphql-over-http/</link>
            <guid>https://docs.loadcurl.com/blog/load-testing-graphql-over-http/</guid>
            <pubDate>Fri, 18 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[How to load test GraphQL APIs over HTTP with POST, headers, and JSON bodies — what works in Loadcurl today, and pitfalls unique to GraphQL.]]></description>
            <content:encoded><![CDATA[<p>GraphQL usually rides on <strong>HTTP POST</strong> (sometimes GET). That means you can load test it with any HTTP load tool — including Loadcurl — as long as you send the right URL, headers, and JSON body.</p>
<!-- -->
<p>There is <strong>no separate GraphQL protocol mode</strong> in Loadcurl today (and no gRPC/WebSocket tester). Treat GraphQL as HTTP.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-to-put-in-the-request">What to put in the request<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#what-to-put-in-the-request" class="hash-link" aria-label="Direct link to What to put in the request" title="Direct link to What to put in the request" translate="no">​</a></h2>
<p>Typical shape:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">POST /graphql</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Content-Type: application/json</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">Authorization: Bearer STAGE_TOKEN</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">{</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "query": "query HeroName { hero { name } }",</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  "variables": {}</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">}</span><br></div></code></pre></div></div>
<p>Validate once in Postman/curl, then paste into <strong>New test</strong>. Verify the hostname first.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="graphql-specific-pitfalls-under-load">GraphQL-specific pitfalls under load<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#graphql-specific-pitfalls-under-load" class="hash-link" aria-label="Direct link to GraphQL-specific pitfalls under load" title="Direct link to GraphQL-specific pitfalls under load" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-http-200-with-errors-in-the-body">1. HTTP 200 with errors in the body<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#1-http-200-with-errors-in-the-body" class="hash-link" aria-label="Direct link to 1. HTTP 200 with errors in the body" title="Direct link to 1. HTTP 200 with errors in the body" translate="no">​</a></h3>
<p>Many GraphQL servers return <strong>200</strong> even when <code>errors</code> is populated. Your load report may show a healthy 2xx rate while clients are failing. Check response samples / request results, and monitor app-level error metrics.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-over-fetching-hides-the-real-hotspot">2. Over-fetching hides the real hotspot<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#2-over-fetching-hides-the-real-hotspot" class="hash-link" aria-label="Direct link to 2. Over-fetching hides the real hotspot" title="Direct link to 2. Over-fetching hides the real hotspot" translate="no">​</a></h3>
<p>A single “simple” query can fan out to many resolvers and services. p99 may reflect the heaviest resolver, not the gateway.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-persisted-vs-ad-hoc-queries">3. Persisted vs ad-hoc queries<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#3-persisted-vs-ad-hoc-queries" class="hash-link" aria-label="Direct link to 3. Persisted vs ad-hoc queries" title="Direct link to 3. Persisted vs ad-hoc queries" translate="no">​</a></h3>
<p>Ad-hoc queries stress parsing and planning differently than persisted queries in production. Match what you actually ship.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-n1-resolver-patterns">4. N+1 resolver patterns<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#4-n1-resolver-patterns" class="hash-link" aria-label="Direct link to 4. N+1 resolver patterns" title="Direct link to 4. N+1 resolver patterns" translate="no">​</a></h3>
<p>Load tests that only hit a tiny entity look fine until a list field explodes. Include representative list queries in a separate test.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-auth-and-complexity-limits">5. Auth and complexity limits<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#5-auth-and-complexity-limits" class="hash-link" aria-label="Direct link to 5. Auth and complexity limits" title="Direct link to 5. Auth and complexity limits" translate="no">​</a></h3>
<p>Complexity/depth limiters and per-token rate limits often show up as 429 or GraphQL errors before CPU saturates.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-to-structure-loadcurl-tests">How to structure Loadcurl tests<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#how-to-structure-loadcurl-tests" class="hash-link" aria-label="Direct link to How to structure Loadcurl tests" title="Direct link to How to structure Loadcurl tests" translate="no">​</a></h2>
<p>Because each test is <strong>one HTTP request</strong> under a load profile:</p>
<ul>
<li class="">Test the <strong>hottest query</strong> alone first</li>
<li class="">Add a second test for a <strong>mutation</strong> path</li>
<li class="">Use smoke → load ladders like REST</li>
<li class="">Compare PDFs when you change dataloader / caching / indexes</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pass-criteria-ideas">Pass criteria ideas<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#pass-criteria-ideas" class="hash-link" aria-label="Direct link to Pass criteria ideas" title="Direct link to Pass criteria ideas" translate="no">​</a></h2>
<ul>
<li class="">Target RPS sustained</li>
<li class="">Gateway + resolver p95/p99 under budget (from APM)</li>
<li class="">Transport error/timeout rates low</li>
<li class="">Application-level GraphQL error rate under budget (not only HTTP 2xx)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/load-testing-graphql-over-http/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/">How to Load Test from Postman</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/faq/">FAQ — what you can test</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>GraphQL</category>
            <category>HTTP</category>
            <category>API load testing</category>
        </item>
        <item>
            <title><![CDATA[How Many Requests Do I Need for a Meaningful Load Test?]]></title>
            <link>https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/</link>
            <guid>https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/</guid>
            <pubDate>Thu, 17 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Estimate how many total requests make a load test meaningful using duration × RPS, warmup, percentile stability, and Loadcurl quota holds.]]></description>
            <content:encoded><![CDATA[<p>People ask “how many requests?” when they mean “how long and how hard should I run?” In RPS-based tools the honest answer is:</p>
<!-- -->
<blockquote>
<p><strong>Total attempt budget ≈ duration × target RPS</strong></p>
</blockquote>
<p>Plus enough <strong>steady-state time after ramp-up</strong> for percentiles to mean something.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-budget-formula">The budget formula<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#the-budget-formula" class="hash-link" aria-label="Direct link to The budget formula" title="Direct link to The budget formula" translate="no">​</a></h2>
<p>Loadcurl holds <strong><code>duration × RPS</code></strong> (minimum 1) at start. Examples:</p>
<table><thead><tr><th>Goal</th><th>Example profile</th><th>Approx. hold</th></tr></thead><tbody><tr><td>Smoke</td><td>10 RPS × 120s</td><td>1,200</td></tr><tr><td>Standard load</td><td>150 RPS × 600s</td><td>90,000</td></tr><tr><td>Heavier rehearsal</td><td>300 RPS × 900s</td><td>270,000</td></tr></tbody></table>
<p>Check <strong>Usage</strong> before you click Start.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-short-runs-mislead">Why short runs mislead<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#why-short-runs-mislead" class="hash-link" aria-label="Direct link to Why short runs mislead" title="Direct link to Why short runs mislead" translate="no">​</a></h2>
<p>A 20-second blast may never leave warmup. p99 from a few hundred requests is noisy — especially with ramp-up <code>0</code>.</p>
<p>Rules of thumb:</p>
<ul>
<li class="">Prefer <strong>several minutes</strong> at target RPS for load SLOs</li>
<li class="">Use ramp-up so the hold window is mostly steady</li>
<li class="">Re-run once if the first report looks like a cold-start artifact</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="percentiles-need-samples">Percentiles need samples<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#percentiles-need-samples" class="hash-link" aria-label="Direct link to Percentiles need samples" title="Direct link to Percentiles need samples" translate="no">​</a></h2>
<p>Rough intuition: to talk about p99 with any confidence, you want <strong>thousands</strong> of successful requests in the measurement window — not dozens. Higher RPS reaches that sooner; lower RPS needs more duration.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="separate-smoke-from-proof">Separate smoke from proof<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#separate-smoke-from-proof" class="hash-link" aria-label="Direct link to Separate smoke from proof" title="Direct link to Separate smoke from proof" translate="no">​</a></h2>
<table><thead><tr><th>Intent</th><th>Requests mindset</th></tr></thead><tbody><tr><td>Prove curl/auth works</td><td>Hundreds are enough</td></tr><tr><td>Prove SLO at peak</td><td>Tens of thousands+ often</td></tr><tr><td>Soak for leaks</td><td>High total count over long time at moderate RPS</td></tr></tbody></table>
<p>Do not spend a Scale-plan hold debugging a wrong header — smoke first.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="plan-caps-still-apply">Plan caps still apply<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#plan-caps-still-apply" class="hash-link" aria-label="Direct link to Plan caps still apply" title="Direct link to Plan caps still apply" translate="no">​</a></h2>
<p>Quota is one limit. <strong>Max RPS</strong> and <strong>max duration</strong> on your plan also cap the composer. Free plans intentionally keep rehearsals smaller.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="practical-recipe">Practical recipe<a href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/#practical-recipe" class="hash-link" aria-label="Direct link to Practical recipe" title="Direct link to Practical recipe" translate="no">​</a></h2>
<ol>
<li class="">Smoke: ~1k–2k request hold</li>
<li class="">Baseline: ~25–50% of peak for 5 minutes</li>
<li class="">Peak load: full target for 10 minutes with ramp-up</li>
<li class="">Compare PDFs; only then consider stress/soak</li>
</ol>
<p>Details on holds: <a class="" href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/">Request Quota Explained</a> · <a class="" href="https://docs.loadcurl.com/docs/tutorial/billing/">Billing docs</a></p>]]></content:encoded>
            <category>Metrics &amp; SLOs</category>
            <category>RPS</category>
            <category>duration</category>
            <category>quota</category>
            <category>planning</category>
        </item>
        <item>
            <title><![CDATA[What Causes High p99 Latency in APIs?]]></title>
            <link>https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/</link>
            <guid>https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/</guid>
            <pubDate>Wed, 16 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Common causes of high API p99 latency under load — queues, pools, GC, locks, dependencies — and how to confirm them with load-test reports.]]></description>
            <content:encoded><![CDATA[<p>When <strong>p99</strong> blows up while <strong>p50</strong> looks fine, a small fraction of requests are stuck in queues, locks, or slow dependencies. That fraction is often what users and retries feel.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-p99-is-telling-you">What p99 is telling you<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#what-p99-is-telling-you" class="hash-link" aria-label="Direct link to What p99 is telling you" title="Direct link to What p99 is telling you" translate="no">​</a></h2>
<p>p99 is the latency threshold that 99% of requests beat. Spikes usually mean <strong>queueing delay</strong> or <strong>occasional expensive work</strong>, not that every request got slower.</p>
<p>Pair it with error/timeout rates and successful-vs-all scopes in the report.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="frequent-root-causes">Frequent root causes<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#frequent-root-causes" class="hash-link" aria-label="Direct link to Frequent root causes" title="Direct link to Frequent root causes" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-thread--connection-pool-saturation">1. Thread / connection pool saturation<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#1-thread--connection-pool-saturation" class="hash-link" aria-label="Direct link to 1. Thread / connection pool saturation" title="Direct link to 1. Thread / connection pool saturation" translate="no">​</a></h3>
<p>Requests wait for a DB, Redis, or HTTP client connection. CPU may look calm while p99 climbs.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-database-locks-and-hot-rows">2. Database locks and hot rows<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#2-database-locks-and-hot-rows" class="hash-link" aria-label="Direct link to 2. Database locks and hot rows" title="Direct link to 2. Database locks and hot rows" translate="no">​</a></h3>
<p>Contended updates, missing indexes, or single-row hotspots create long tails under RPS.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-garbage-collection-and-runtime-pauses">3. Garbage collection and runtime pauses<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#3-garbage-collection-and-runtime-pauses" class="hash-link" aria-label="Direct link to 3. Garbage collection and runtime pauses" title="Direct link to 3. Garbage collection and runtime pauses" translate="no">​</a></h3>
<p>Language runtimes under allocation pressure add multi-hundred-millisecond stalls visible at p99 before p50 moves.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-downstream-dependency-latency">4. Downstream dependency latency<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#4-downstream-dependency-latency" class="hash-link" aria-label="Direct link to 4. Downstream dependency latency" title="Direct link to 4. Downstream dependency latency" translate="no">​</a></h3>
<p>Your handler is “fine” but a billing, search, or auth dependency saturates. Fan-out multiplies the effect.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-synchronous-logging--tracing-overload">5. Synchronous logging / tracing overload<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#5-synchronous-logging--tracing-overload" class="hash-link" aria-label="Direct link to 5. Synchronous logging / tracing overload" title="Direct link to 5. Synchronous logging / tracing overload" translate="no">​</a></h3>
<p>Chatty logs or heavy trace export at high RPS steal tail latency.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-cold-path-vs-warm-path">6. Cold path vs warm path<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#6-cold-path-vs-warm-path" class="hash-link" aria-label="Direct link to 6. Cold path vs warm path" title="Direct link to 6. Cold path vs warm path" translate="no">​</a></h3>
<p>Cache misses, first-request JIT, or per-tenant cold starts create rare slow calls — classic p99 fuel.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-retries-amplifying-load">7. Retries amplifying load<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#7-retries-amplifying-load" class="hash-link" aria-label="Direct link to 7. Retries amplifying load" title="Direct link to 7. Retries amplifying load" translate="no">​</a></h3>
<p>Client timeouts trigger retries, which raise RPS and create more timeouts — a feedback loop.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-a-load-report-points-the-way">How a load report points the way<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#how-a-load-report-points-the-way" class="hash-link" aria-label="Direct link to How a load report points the way" title="Direct link to How a load report points the way" translate="no">​</a></h2>
<p>In Loadcurl-style reports:</p>
<ul>
<li class=""><strong>p50 flat, p99 rising during hold</strong> → saturation building</li>
<li class=""><strong>Achieved RPS below target</strong> → system cannot accept work fast enough</li>
<li class=""><strong>Timeouts up</strong> → somewhere exceeded budgets</li>
<li class=""><strong>5xx up</strong> → hard failures, not just slowness</li>
<li class=""><strong>Successful p99 OK, all p99 bad</strong> → failures dominate the mixed distribution</li>
</ul>
<p>Then confirm with DB pool metrics, lock times, and dependency dashboards. Playbook: <a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-usually-does-not-fix-p99">What usually does <em>not</em> fix p99<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#what-usually-does-not-fix-p99" class="hash-link" aria-label="Direct link to what-usually-does-not-fix-p99" title="Direct link to what-usually-does-not-fix-p99" translate="no">​</a></h2>
<ul>
<li class="">Raising timeouts (hides queueing)</li>
<li class="">Adding app replicas when the DB is the limiter</li>
<li class="">Averaging away the tail in executive slides</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/what-causes-high-p99-latency-in-apis/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/">What Is p95 and p99 Latency?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/">How to Set Latency SLOs</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">Report docs</a></li>
</ul>]]></content:encoded>
            <category>Metrics &amp; SLOs</category>
            <category>p99</category>
            <category>latency</category>
            <category>bottlenecks</category>
        </item>
        <item>
            <title><![CDATA[How to Load Test Authenticated APIs (Safely)]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/</guid>
            <pubDate>Tue, 15 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Load test authenticated HTTP APIs without leaking secrets — staging tokens, header hygiene, rate limits, and how Loadcurl stores request credentials.]]></description>
            <content:encoded><![CDATA[<p>Most real APIs need auth. Load testing them means sending <strong>Authorization headers, API keys, or cookies</strong> at RPS — which raises security and realism issues at the same time.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prefer-staging-credentials">Prefer staging credentials<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#prefer-staging-credentials" class="hash-link" aria-label="Direct link to Prefer staging credentials" title="Direct link to Prefer staging credentials" translate="no">​</a></h2>
<ul>
<li class="">Issue tokens scoped to staging</li>
<li class="">Avoid production admin keys in the composer</li>
<li class="">Rotate anything pasted into tickets, chat, or screenshots</li>
<li class="">Use short-lived tokens when your IdP allows</li>
</ul>
<p>Loadcurl stores headers and bodies you enter so it can run the test and build the report. Data is sent over TLS. Prefer staging tokens — see the product FAQ and Privacy Policy for how account data is handled.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="make-auth-realistic-not-theatrical">Make auth realistic, not theatrical<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#make-auth-realistic-not-theatrical" class="hash-link" aria-label="Direct link to Make auth realistic, not theatrical" title="Direct link to Make auth realistic, not theatrical" translate="no">​</a></h2>
<p>Under load you want the <strong>same auth path users hit</strong>:</p>
<ul>
<li class="">Real JWT validation / introspection cost</li>
<li class="">Same required headers and content types</li>
<li class="">Same failure mode when tokens expire mid-run</li>
</ul>
<p>Avoid “auth disabled on staging” if you claim production readiness from that run.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="token-expiry-during-long-runs">Token expiry during long runs<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#token-expiry-during-long-runs" class="hash-link" aria-label="Direct link to Token expiry during long runs" title="Direct link to Token expiry during long runs" translate="no">​</a></h2>
<p>Soak and long load tests can outlive access tokens.</p>
<p>Options:</p>
<ul>
<li class="">Use a longer-lived staging token for the rehearsal window</li>
<li class="">Keep duration inside token lifetime</li>
<li class="">Re-run shorter holds rather than one multi-hour authenticated blast with a dying token</li>
</ul>
<p>(Loadcurl runs one static request definition per test — it does not refresh OAuth for you mid-run today.)</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="rate-limits-and-429s">Rate limits and 429s<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#rate-limits-and-429s" class="hash-link" aria-label="Direct link to Rate limits and 429s" title="Direct link to Rate limits and 429s" translate="no">​</a></h2>
<p>Authenticated endpoints often have stricter per-token or per-user limits. Under high RPS you may be measuring the <strong>limiter</strong>, not the handler.</p>
<p>Interpret 429s explicitly:</p>
<ul>
<li class="">Expected protection → adjust RPS or use a load-test-aware limit on staging</li>
<li class="">Accidental low limit → fix config before blaming app CPU</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="header-hygiene-checklist">Header hygiene checklist<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#header-hygiene-checklist" class="hash-link" aria-label="Direct link to Header hygiene checklist" title="Direct link to Header hygiene checklist" translate="no">​</a></h2>
<ul>
<li class="">No production secrets in Postman exports you paste</li>
<li class="">Strip cookies you do not need</li>
<li class="">Do not put PII in JSON bodies “just to be realistic” if synthetic IDs work</li>
<li class="">Verify only hosts you own (<a class="" href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/">domain verification</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="workflow-in-loadcurl">Workflow in Loadcurl<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#workflow-in-loadcurl" class="hash-link" aria-label="Direct link to Workflow in Loadcurl" title="Direct link to Workflow in Loadcurl" translate="no">​</a></h2>
<ol>
<li class="">Verify staging domain</li>
<li class="">Prove one authenticated call in Postman/curl</li>
<li class="">Paste into <strong>New test</strong> (headers included)</li>
<li class="">Start with a <strong>smoke</strong> RPS first</li>
<li class="">Climb to target; read 401/403/429 vs 5xx carefully in the report</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/how-to-load-test-authenticated-apis-safely/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/">Staging vs Production Load Testing</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/">How to Load Test from Postman</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/faq/">Loadcurl FAQ</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>authentication</category>
            <category>security</category>
            <category>API load testing</category>
        </item>
        <item>
            <title><![CDATA[Smoke Test vs Load Test vs Soak Test for APIs]]></title>
            <link>https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/</link>
            <guid>https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/</guid>
            <pubDate>Mon, 14 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Know when to run API smoke, load, and soak tests — different RPS, duration, and questions — and how to configure each profile in practice.]]></description>
            <content:encoded><![CDATA[<p>Not every performance run should be a peak-RPS rehearsal. <strong>Smoke</strong>, <strong>load</strong>, and <strong>soak</strong> answer different questions — and should use different duration and quota budgets.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="smoke-test">Smoke test<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#smoke-test" class="hash-link" aria-label="Direct link to Smoke test" title="Direct link to Smoke test" translate="no">​</a></h2>
<p><strong>Question:</strong> Does the path work under a little traffic?</p>
<ul>
<li class="">Low RPS (often 5–20)</li>
<li class="">Short duration (1–3 minutes)</li>
<li class="">Ramp-up optional / small</li>
<li class="">Watch for 4xx/5xx and obvious timeouts</li>
</ul>
<p>Use after changing the Postman/curl request, auth headers, or domain — before spending a large <code>duration × RPS</code> hold.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="load-test">Load test<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#load-test" class="hash-link" aria-label="Direct link to Load test" title="Direct link to Load test" translate="no">​</a></h2>
<p><strong>Question:</strong> Can we sustain <strong>expected peak</strong> with acceptable p95/p99 and errors?</p>
<ul>
<li class="">Target RPS from traffic math</li>
<li class="">Minutes-long hold after ramp-up</li>
<li class="">Pass/fail criteria written first</li>
</ul>
<p>This is Loadcurl’s default job: target RPS, ramp-up, duration, then a report. See <a class="" href="https://docs.loadcurl.com/blog/load-testing-vs-stress-testing-vs-performance-testing/">Load vs Stress vs Performance Testing</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="soak-endurance-test">Soak (endurance) test<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#soak-endurance-test" class="hash-link" aria-label="Direct link to Soak (endurance) test" title="Direct link to Soak (endurance) test" translate="no">​</a></h2>
<p><strong>Question:</strong> Does performance <strong>drift</strong> over time — leaks, saturation, disk, connection exhaustion?</p>
<ul>
<li class="">Moderate RPS (often below peak)</li>
<li class="">Long duration (tens of minutes to hours — within plan max duration)</li>
<li class="">Watch p99 and error rate <strong>over time</strong>, not only averages</li>
</ul>
<p>Soak is still a load profile — same composer — with different intent and patience. Check quota hold first; long × RPS gets expensive.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="stress-for-contrast">Stress (for contrast)<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#stress-for-contrast" class="hash-link" aria-label="Direct link to Stress (for contrast)" title="Direct link to Stress (for contrast)" translate="no">​</a></h2>
<p><strong>Question:</strong> Where does it break above peak? Prefer staging. Not the same as soak or smoke.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quick-comparison">Quick comparison<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#quick-comparison" class="hash-link" aria-label="Direct link to Quick comparison" title="Direct link to Quick comparison" translate="no">​</a></h2>
<table><thead><tr><th>Type</th><th>RPS</th><th>Duration</th><th>Primary signal</th></tr></thead><tbody><tr><td>Smoke</td><td>Low</td><td>Short</td><td>Correctness</td></tr><tr><td>Load</td><td>Expected peak</td><td>Minutes</td><td>SLO at peak</td></tr><tr><td>Soak</td><td>Moderate</td><td>Long</td><td>Drift / leaks</td></tr><tr><td>Stress</td><td>Above peak</td><td>Until degrade</td><td>Breaking point</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="suggested-loadcurl-sequences">Suggested Loadcurl sequences<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#suggested-loadcurl-sequences" class="hash-link" aria-label="Direct link to Suggested Loadcurl sequences" title="Direct link to Suggested Loadcurl sequences" translate="no">​</a></h2>
<ol>
<li class="">Smoke at 10 RPS × 120s</li>
<li class="">Load at target × 600s with 60s ramp-up</li>
<li class="">Optional soak at 50% peak × as long as plan + quota allow</li>
<li class="">Optional stress on staging only</li>
</ol>
<p>Stop early if the smoke fails — do not burn Growth-plan quota on a bad Authorization header.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/smoke-vs-load-vs-soak-testing-for-apis/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/">What Is Ramp-Up in Load Testing?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/">Request Quota Explained</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/">Pre-Launch Checklist</a></li>
</ul>]]></content:encoded>
            <category>Fundamentals</category>
            <category>smoke test</category>
            <category>soak test</category>
            <category>load test</category>
        </item>
        <item>
            <title><![CDATA[How to Set Latency SLOs for an HTTP API]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/</guid>
            <pubDate>Sun, 13 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Set practical HTTP API latency SLOs using p95 and p99, tie them to load-test pass criteria, and avoid averages that hide user pain.]]></description>
            <content:encoded><![CDATA[<p>An SLO turns “the API should feel fast” into a number you can test. For HTTP APIs, that number should almost always be a <strong>latency percentile under a defined load</strong> — not an average from a quiet afternoon.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="pick-the-user-visible-interaction">Pick the user-visible interaction<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#pick-the-user-visible-interaction" class="hash-link" aria-label="Direct link to Pick the user-visible interaction" title="Direct link to Pick the user-visible interaction" translate="no">​</a></h2>
<p>Examples:</p>
<ul>
<li class=""><code>POST /checkout</code> p95 &lt; 300 ms at 150 RPS</li>
<li class=""><code>GET /search</code> p99 &lt; 500 ms at 400 RPS</li>
<li class="">Auth token exchange p95 &lt; 150 ms at expected peak</li>
</ul>
<p>Write the <strong>endpoint</strong>, <strong>percentile</strong>, <strong>threshold</strong>, and <strong>RPS context</strong> together. An SLO without a load context is incomplete.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prefer-p95-or-p99-over-the-mean">Prefer p95 or p99 over the mean<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#prefer-p95-or-p99-over-the-mean" class="hash-link" aria-label="Direct link to Prefer p95 or p99 over the mean" title="Direct link to Prefer p95 or p99 over the mean" translate="no">​</a></h2>
<p>Averages hide tails. Clients abandon and retry on the tail. Background: <a class="" href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/">What Is p95 and p99 Latency?</a>.</p>
<p>Common patterns:</p>
<ul>
<li class=""><strong>User-facing read APIs:</strong> p95</li>
<li class=""><strong>Payments / auth / fan-out critical paths:</strong> p99</li>
<li class=""><strong>Internal mesh hops:</strong> tighter budgets so end-to-end still fits</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="separate-correctness-from-speed">Separate correctness from speed<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#separate-correctness-from-speed" class="hash-link" aria-label="Direct link to Separate correctness from speed" title="Direct link to Separate correctness from speed" translate="no">​</a></h2>
<p>A latency SLO should sit next to an <strong>availability / error</strong> objective:</p>
<ul>
<li class="">Success rate ≥ 99.5% at the same RPS profile</li>
<li class="">Timeout rate under a small budget</li>
</ul>
<p>Fast 500s are not success. Loadcurl reports make you look at both status mix and percentiles.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="derive-thresholds-from-product-reality">Derive thresholds from product reality<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#derive-thresholds-from-product-reality" class="hash-link" aria-label="Direct link to Derive thresholds from product reality" title="Direct link to Derive thresholds from product reality" translate="no">​</a></h2>
<p>Sources, in order of honesty:</p>
<ol>
<li class="">Current production percentiles at known RPS (APM)</li>
<li class="">Competitor/UX research budgets</li>
<li class="">Dependency math (your p99 must fit inside the caller’s timeout)</li>
</ol>
<p>Then add headroom for regressions. Do not invent “50 ms p99 at 10k RPS” if production never saw that load.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="turn-slos-into-load-test-pass-criteria">Turn SLOs into load-test pass criteria<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#turn-slos-into-load-test-pass-criteria" class="hash-link" aria-label="Direct link to Turn SLOs into load-test pass criteria" title="Direct link to Turn SLOs into load-test pass criteria" translate="no">​</a></h2>
<p>Before Start in Loadcurl:</p>
<blockquote>
<p>Duration 600s, ramp-up 60s, target 150 RPS. Pass if successful p95 &lt; 300 ms, errors &lt; 0.5%, average RPS within 10% of target.</p>
</blockquote>
<p>After the run, read the report scopes (<strong>successful</strong> vs <strong>all</strong>) so timeouts do not silently invent a fake p99. Guide: <a class="" href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/">How to Read an API Load Test Report</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="keep-slos-testable">Keep SLOs testable<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#keep-slos-testable" class="hash-link" aria-label="Direct link to Keep SLOs testable" title="Direct link to Keep SLOs testable" translate="no">​</a></h2>
<ul>
<li class="">One primary percentile per endpoint</li>
<li class="">Same load profile when comparing releases</li>
<li class="">Document staging vs production scale factor</li>
<li class="">Re-run after risky deploys; attach PDF</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="anti-patterns">Anti-patterns<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#anti-patterns" class="hash-link" aria-label="Direct link to Anti-patterns" title="Direct link to Anti-patterns" translate="no">​</a></h2>
<ul>
<li class="">SLO on average latency only</li>
<li class="">SLO without RPS or concurrency context</li>
<li class="">Tightening timeouts instead of fixing queues</li>
<li class="">Different payloads every run so trends are meaningless</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/how-to-set-latency-slos-for-an-http-api/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/">API Performance Testing Best Practices</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">Tests and reports docs</a></li>
</ul>]]></content:encoded>
            <category>Metrics &amp; SLOs</category>
            <category>SLO</category>
            <category>latency</category>
            <category>p95</category>
            <category>p99</category>
        </item>
        <item>
            <title><![CDATA[Loadcurl vs k6, Locust, and JMeter: When a Dashboard Is Enough]]></title>
            <link>https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/</link>
            <guid>https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/</guid>
            <pubDate>Sat, 12 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Compare a browser load-testing dashboard like Loadcurl with k6, Locust, and JMeter — scripting power vs speed to first RPS report.]]></description>
            <content:encoded><![CDATA[<p>k6, Locust, and JMeter are powerful. They are also more <strong>process</strong> than many teams need for “can this HTTP API hold 200 RPS?” A dashboard that accepts curl / Postman and runs cloud generators optimizes for a different job: <strong>time to a trustworthy report</strong>.</p>
<!-- -->
<p>This is an honest comparison — including what Loadcurl does <strong>not</strong> do yet.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-each-class-of-tool-optimizes-for">What each class of tool optimizes for<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#what-each-class-of-tool-optimizes-for" class="hash-link" aria-label="Direct link to What each class of tool optimizes for" title="Direct link to What each class of tool optimizes for" translate="no">​</a></h2>
<table><thead><tr><th>Approach</th><th>Best at</th></tr></thead><tbody><tr><td><strong>k6</strong></td><td>Scripted scenarios as code, CI-friendly workflows</td></tr><tr><td><strong>Locust</strong></td><td>Python user behavior, distributed swarms you operate</td></tr><tr><td><strong>JMeter</strong></td><td>Mature GUI/CLI, complex protocols and legacy enterprise setups</td></tr><tr><td><strong>Loadcurl dashboard</strong></td><td>One HTTP request, verify host, set RPS/ramp/duration, cloud run, PDF report</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-a-dashboard-wins">Where a dashboard wins<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#where-a-dashboard-wins" class="hash-link" aria-label="Direct link to Where a dashboard wins" title="Direct link to Where a dashboard wins" translate="no">​</a></h2>
<ul>
<li class=""><strong>No install</strong> — no local workers, Docker swarm, or agent fleet for day-one tests</li>
<li class=""><strong>Curl/Postman paste</strong> — reuse the request you already debugged</li>
<li class=""><strong>Ownership gate</strong> — domain verification before traffic</li>
<li class=""><strong>Shared workspace</strong> — tests, domains, quota, and billing in one org</li>
<li class=""><strong>Polled live run + report</strong> — latency percentiles, throughput vs target, HTTP outcomes</li>
</ul>
<p>For staging rehearsals and pre-launch checks on a single endpoint, that loop is often enough.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-scripted-tools-still-win">Where scripted tools still win<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#where-scripted-tools-still-win" class="hash-link" aria-label="Direct link to Where scripted tools still win" title="Direct link to Where scripted tools still win" translate="no">​</a></h2>
<p>Be frank with stakeholders:</p>
<ul>
<li class=""><strong>Multi-step user journeys</strong> (login → browse → checkout) — Loadcurl is <strong>one HTTP request</strong> per test today</li>
<li class=""><strong>CI pipelines / GitOps</strong> — no first-class CLI/CI integration in the current product</li>
<li class=""><strong>Custom protocols</strong> beyond HTTP (gRPC, WebSocket-native flows) — not supported yet</li>
<li class=""><strong>Exotic traffic shapes</strong> you want fully coded and reviewed like application code</li>
</ul>
<p>If those are hard requirements, keep k6/Locust/JMeter (or use both: scripts for journeys, dashboard for hotspot endpoints).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ops-cost-is-part-of-the-comparison">Ops cost is part of the comparison<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#ops-cost-is-part-of-the-comparison" class="hash-link" aria-label="Direct link to Ops cost is part of the comparison" title="Direct link to Ops cost is part of the comparison" translate="no">​</a></h2>
<p>Self-hosted generators mean you own:</p>
<ul>
<li class="">Machine sizing and regions</li>
<li class="">Result storage and report formatting</li>
<li class="">Team access control</li>
<li class="">Preventing accidental tests against the wrong host</li>
</ul>
<p>Loadcurl trades that ops surface for <strong>plan caps</strong> and <strong>request quota</strong> (<code>duration × RPS</code> holds).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-practical-decision-rule">A practical decision rule<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#a-practical-decision-rule" class="hash-link" aria-label="Direct link to A practical decision rule" title="Direct link to A practical decision rule" translate="no">​</a></h2>
<p>Choose <strong>Loadcurl-style dashboard</strong> when:</p>
<ul>
<li class="">You need an RPS answer this afternoon</li>
<li class="">The critical path is one or a few HTTP endpoints</li>
<li class="">Engineers live in Postman/curl already</li>
<li class="">You want cloud generators without maintaining them</li>
</ul>
<p>Choose <strong>k6 / Locust / JMeter</strong> when:</p>
<ul>
<li class="">Scenarios must be code-reviewed scripts</li>
<li class="">CI must gate merges on performance</li>
<li class="">Journeys span many steps or protocols</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="hybrid-workflow-many-teams-use">Hybrid workflow many teams use<a href="https://docs.loadcurl.com/blog/loadcurl-vs-k6-locust-jmeter/#hybrid-workflow-many-teams-use" class="hash-link" aria-label="Direct link to Hybrid workflow many teams use" title="Direct link to Hybrid workflow many teams use" translate="no">​</a></h2>
<ol>
<li class="">Debug in Postman/curl</li>
<li class="">Paste into Loadcurl for a fast cloud RPS hold + PDF</li>
<li class="">Promote complex journeys to k6 later if needed</li>
</ol>
<p>See <a class="" href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/">Cloud-Based vs Local Load Testing</a> and the <a class="" href="https://docs.loadcurl.com/docs/tutorial/intro/">product intro</a>.</p>]]></content:encoded>
            <category>Tools &amp; workflows</category>
            <category>k6</category>
            <category>Locust</category>
            <category>JMeter</category>
            <category>comparison</category>
        </item>
        <item>
            <title><![CDATA[Request Quota Explained: Why duration × RPS Matters]]></title>
            <link>https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/</link>
            <guid>https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/</guid>
            <pubDate>Fri, 11 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Understand Loadcurl request quota — allotted, available, held, used — and why starting a test reserves duration × RPS until the run settles.]]></description>
            <content:encoded><![CDATA[<p>Loadcurl gates usage with <strong>request quota</strong> on the current workspace plan — not a separate credit pack. The number that surprises people most is the start hold:</p>
<!-- -->
<blockquote>
<p><strong>Hold ≈ duration (seconds) × target RPS</strong> (minimum <strong>1</strong>)</p>
</blockquote>
<p>Understanding that formula prevents failed starts and “where did my quota go?” moments.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-four-quota-buckets">The four quota buckets<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#the-four-quota-buckets" class="hash-link" aria-label="Direct link to The four quota buckets" title="Direct link to The four quota buckets" translate="no">​</a></h2>
<table><thead><tr><th>Bucket</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>Allotted</strong></td><td>Requests granted for this billing period</td></tr><tr><td><strong>Used</strong></td><td>Consumed by settled tests</td></tr><tr><td><strong>Held</strong></td><td>Reserved for runs that started but have not settled</td></tr><tr><td><strong>Available</strong></td><td>What you can still reserve for a new test</td></tr></tbody></table>
<p>You see the same wallet on the header <strong>quota chip</strong>, <strong>Dashboard</strong>, and <strong>Usage</strong> (<code>/wallet</code>). <strong>Plan</strong> (<code>/billing</code>) is where you recharge or upgrade via Razorpay.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-multiply-duration--rps">Why multiply duration × RPS?<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#why-multiply-duration--rps" class="hash-link" aria-label="Direct link to Why multiply duration × RPS?" title="Direct link to Why multiply duration × RPS?" translate="no">​</a></h2>
<p>A test configured for <strong>200 RPS</strong> over <strong>600 seconds</strong> can attempt up to about <strong>120,000</strong> requests. Loadcurl <strong>holds</strong> that amount up front so two teammates cannot over-commit the same monthly pool.</p>
<p>If <strong>available</strong> is too low, start is blocked and you get an insufficient quota error.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-happens-after-the-run">What happens after the run?<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#what-happens-after-the-run" class="hash-link" aria-label="Direct link to What happens after the run?" title="Direct link to What happens after the run?" translate="no">​</a></h2>
<ul>
<li class="">When the report is ready, <strong>actual hits are consumed</strong> and unused hold is <strong>returned</strong></li>
<li class=""><strong>Stop</strong> on a live run (or a failed run without a usable report) <strong>releases</strong> the hold</li>
<li class="">Hold states you may see on the run page: Reserved / Consumed / Returned (HELD, SETTLED, or RELEASED)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="worked-examples">Worked examples<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#worked-examples" class="hash-link" aria-label="Direct link to Worked examples" title="Direct link to Worked examples" translate="no">​</a></h2>
<table><thead><tr><th>Duration</th><th>RPS</th><th>Hold</th></tr></thead><tbody><tr><td>60s</td><td>10</td><td>600</td></tr><tr><td>300s</td><td>100</td><td>30,000</td></tr><tr><td>600s</td><td>200</td><td>120,000</td></tr><tr><td>120s</td><td>1,000</td><td>120,000</td></tr></tbody></table>
<p>Smoke tests are cheap. Launch rehearsals are not — check <strong>Usage</strong> first.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-quota-is-not">What quota is not<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#what-quota-is-not" class="hash-link" aria-label="Direct link to What quota is not" title="Direct link to What quota is not" translate="no">​</a></h2>
<ul>
<li class="">Not a substitute for <strong>max RPS</strong> and <strong>max duration</strong> plan caps on the composer</li>
<li class="">Not carried over when the billing period ends — unused requests expire</li>
<li class="">Not per-user in a company workspace — the <strong>team shares one pool</strong></li>
</ul>
<p>Personal quota stays in the personal workspace until you convert to a company.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="practical-tips">Practical tips<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#practical-tips" class="hash-link" aria-label="Direct link to Practical tips" title="Direct link to Practical tips" translate="no">​</a></h2>
<ol>
<li class="">Estimate hold before Start: <code>duration × RPS</code></li>
<li class="">Prefer shorter smokes while debugging the request shape</li>
<li class="">Stop early if the run is clearly invalid — release unused hold</li>
<li class="">Recharge or upgrade on <strong>Plan</strong> when Available is tight</li>
<li class="">Members can view Usage; <strong>Owner/Admin</strong> check out</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/request-quota-explained-duration-times-rps/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/">How Many Requests for a Meaningful Load Test?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/personal-vs-team-workspace-for-load-testing/">Personal vs Team Workspace</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/billing/">Plan and usage docs</a></li>
</ul>]]></content:encoded>
            <category>Metrics &amp; SLOs</category>
            <category>quota</category>
            <category>billing</category>
            <category>RPS</category>
            <category>usage</category>
        </item>
        <item>
            <title><![CDATA[What Is Ramp-Up in Load Testing?]]></title>
            <link>https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/</link>
            <guid>https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/</guid>
            <pubDate>Thu, 10 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn what ramp-up means in API load testing, how it differs from duration and target RPS, and how to choose ramp-up seconds in Loadcurl.]]></description>
            <content:encoded><![CDATA[<p><strong>Ramp-up</strong> is the time your load test spends climbing from little or no traffic to the <strong>target RPS</strong>. It is one of three core knobs in an HTTP load profile — alongside target RPS and duration.</p>
<!-- -->
<p>In Loadcurl, ramp-up is configured in <strong>seconds</strong>. <code>0</code> means start at full target RPS immediately.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="the-three-knobs">The three knobs<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#the-three-knobs" class="hash-link" aria-label="Direct link to The three knobs" title="Direct link to The three knobs" translate="no">​</a></h2>
<table><thead><tr><th>Knob</th><th>Meaning</th></tr></thead><tbody><tr><td><strong>Target RPS</strong></td><td>Peak requests per second you want to reach</td></tr><tr><td><strong>Ramp-up</strong></td><td>Seconds to go from 0 → target</td></tr><tr><td><strong>Duration</strong></td><td>Total length of the run (seconds)</td></tr></tbody></table>
<p>Example: duration 600s, ramp-up 60s, target 200 RPS → roughly one minute of climb, then about nine minutes near peak (exact shape depends on the generator schedule).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-ramp-up-matters">Why ramp-up matters<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#why-ramp-up-matters" class="hash-link" aria-label="Direct link to Why ramp-up matters" title="Direct link to Why ramp-up matters" translate="no">​</a></h2>
<p>Starting at full blast mixes different failure modes:</p>
<ul>
<li class="">Cold caches and empty connection pools</li>
<li class="">Autoscalers still waking up</li>
<li class="">JIT / runtime warmup</li>
<li class="">Sudden lock or queue shocks</li>
</ul>
<p>A short ramp-up lets the system enter a steady state so <strong>p95/p99 during the hold</strong> reflect capacity — not just cold-start drama.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="choosing-a-ramp-up">Choosing a ramp-up<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#choosing-a-ramp-up" class="hash-link" aria-label="Direct link to Choosing a ramp-up" title="Direct link to Choosing a ramp-up" translate="no">​</a></h2>
<p>Practical starting points:</p>
<ul>
<li class=""><strong>Smoke / debug:</strong> 0–15 seconds</li>
<li class=""><strong>Normal load test:</strong> 30–120 seconds</li>
<li class=""><strong>Higher RPS or autoscale validation:</strong> 60–180+ seconds</li>
</ul>
<p>If your pass criteria care about steady-state latency, either use a non-zero ramp-up or <strong>ignore the first portion</strong> of the run when comparing percentiles.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ramp-up-is-not-duration">Ramp-up is not duration<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#ramp-up-is-not-duration" class="hash-link" aria-label="Direct link to Ramp-up is not duration" title="Direct link to Ramp-up is not duration" translate="no">​</a></h2>
<p>Teams sometimes set a long duration and forget ramp-up — or set ramp-up equal to duration and never reach a stable hold. Prefer:</p>
<ol>
<li class="">Enough ramp to warm</li>
<li class="">Enough remaining duration to measure at target RPS</li>
</ol>
<p>See <a class="" href="https://docs.loadcurl.com/blog/how-many-requests-for-a-meaningful-load-test/">How Many Requests Do I Need for a Meaningful Load Test?</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="quota-impact">Quota impact<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#quota-impact" class="hash-link" aria-label="Direct link to Quota impact" title="Direct link to Quota impact" translate="no">​</a></h2>
<p>Loadcurl still places a hold of roughly <strong><code>duration × RPS</code></strong> when you start (minimum 1). Ramp-up does not shrink that reservation formula — plan Usage accordingly.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-mistakes">Common mistakes<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#common-mistakes" class="hash-link" aria-label="Direct link to Common mistakes" title="Direct link to Common mistakes" translate="no">​</a></h2>
<ul>
<li class="">Ramp-up <code>0</code> on a production game day</li>
<li class="">Comparing p99 from a zero-ramp run to a 2-minute-ramp run without noting the difference</li>
<li class="">Ramp longer than the whole test, leaving no steady hold</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="in-the-product">In the product<a href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/#in-the-product" class="hash-link" aria-label="Direct link to In the product" title="Direct link to In the product" translate="no">​</a></h2>
<p>On <strong>New test</strong>, set duration, ramp-up, and target RPS (capped by plan). Paste curl / Postman or fill the composer, verify the domain, then start.</p>
<p>Docs: <a class="" href="https://docs.loadcurl.com/docs/tutorial/getting-started/">Getting started</a> · <a class="" href="https://docs.loadcurl.com/docs/tutorial/intro/">Core concepts</a></p>]]></content:encoded>
            <category>Fundamentals</category>
            <category>ramp-up</category>
            <category>RPS</category>
            <category>load profile</category>
        </item>
        <item>
            <title><![CDATA[Staging vs Production Load Testing: When Each Is Safe]]></title>
            <link>https://docs.loadcurl.com/blog/staging-vs-production-load-testing/</link>
            <guid>https://docs.loadcurl.com/blog/staging-vs-production-load-testing/</guid>
            <pubDate>Wed, 09 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[When to load test staging vs production, how domain verification fits, ramp-up and abort criteria, and how to run a production game day safely.]]></description>
            <content:encoded><![CDATA[<p>Traffic from a load test is <strong>real</strong>. Generators open connections, hit auth, touch databases, and trip rate limits. Choosing staging vs production is a safety decision first — a metrics decision second.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="default-staging">Default: staging<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#default-staging" class="hash-link" aria-label="Direct link to Default: staging" title="Direct link to Default: staging" translate="no">​</a></h2>
<p>Use staging when you want to answer:</p>
<ul>
<li class="">Can we sustain target RPS?</li>
<li class="">Do p95/p99 stay inside SLOs?</li>
<li class="">What breaks first as we climb the ladder?</li>
</ul>
<p><strong>Requirements for useful staging:</strong></p>
<ul>
<li class="">Sized similarly to production (or known scale factor)</li>
<li class="">Realistic data shapes and auth paths</li>
<li class="">Observability (CPU, DB, queues, errors)</li>
<li class="">A hostname you can <strong>verify</strong> in Loadcurl</li>
</ul>
<p>Verify <code>staging.example.com</code> (or the staging apex) under <strong>Domains</strong>, then run New test against that host only.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-production-load-testing-can-be-justified">When production load testing can be justified<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#when-production-load-testing-can-be-justified" class="hash-link" aria-label="Direct link to When production load testing can be justified" title="Direct link to When production load testing can be justified" translate="no">​</a></h2>
<p>Production game days make sense when:</p>
<ul>
<li class="">Staging cannot reproduce production dependencies or traffic paths</li>
<li class="">You need to validate autoscaling, CDN, or edge behavior for real</li>
<li class="">The business accepts controlled risk with on-call coverage</li>
</ul>
<p>Treat it as an <strong>incident rehearsal</strong>, not a casual click of Start.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="production-rules-of-engagement">Production rules of engagement<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#production-rules-of-engagement" class="hash-link" aria-label="Direct link to Production rules of engagement" title="Direct link to Production rules of engagement" translate="no">​</a></h2>
<ol>
<li class=""><strong>Permission</strong> — only systems you own / are allowed to test</li>
<li class=""><strong>Domain verification</strong> — proves control; does not make load “safe”</li>
<li class=""><strong>Modest RPS first</strong> — climb a ladder; do not jump to peak</li>
<li class=""><strong>Ramp-up</strong> — avoid cliff-edge traffic from RPS = 0</li>
<li class=""><strong>Abort criteria</strong> — max error rate, max p99, customer impact signals</li>
<li class=""><strong>On-call + observability</strong> — dashboards open before Start</li>
<li class=""><strong>Off-peak window</strong> — unless the goal is peak-hour realism</li>
<li class=""><strong>Stop early</strong> — Loadcurl can stop a live run and release unused quota hold</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="staging-pitfalls-that-create-false-confidence">Staging pitfalls that create false confidence<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#staging-pitfalls-that-create-false-confidence" class="hash-link" aria-label="Direct link to Staging pitfalls that create false confidence" title="Direct link to Staging pitfalls that create false confidence" translate="no">​</a></h2>
<ul>
<li class="">Tiny staging DB that never saturates like prod</li>
<li class="">Disabled rate limits or auth shortcuts</li>
<li class="">Synthetic payloads that skip hot queries</li>
<li class="">No cache warming difference documented</li>
</ul>
<p>Document gaps so nobody claims “staging survived 2k RPS” as a production guarantee without a scale factor.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-loadcurl-enforces-a-baseline-of-responsibility">How Loadcurl enforces a baseline of responsibility<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#how-loadcurl-enforces-a-baseline-of-responsibility" class="hash-link" aria-label="Direct link to How Loadcurl enforces a baseline of responsibility" title="Direct link to How Loadcurl enforces a baseline of responsibility" translate="no">​</a></h2>
<ul>
<li class="">Only <strong>verified</strong> hosts (or their subdomains) can be targeted</li>
<li class="">Personal: 1 domain; company: up to 10 (handy for staging + API + app)</li>
<li class="">Quota hold <code>duration × RPS</code> limits accidental multi-hour blasts without plan capacity</li>
</ul>
<p>Still: <strong>you</strong> choose the URL and the RPS. Prefer staging in the composer by default.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="decision-cheat-sheet">Decision cheat sheet<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#decision-cheat-sheet" class="hash-link" aria-label="Direct link to Decision cheat sheet" title="Direct link to Decision cheat sheet" translate="no">​</a></h2>
<table><thead><tr><th>Goal</th><th>Environment</th></tr></thead><tbody><tr><td>Feature capacity / regression</td><td>Staging</td></tr><tr><td>Find breaking point (stress)</td><td>Staging</td></tr><tr><td>Autoscale / multi-AZ realism</td><td>Production game day</td></tr><tr><td>Marketing “we tested prod at peak”</td><td>Only with formal game day</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/">How to Verify a Domain for Load Testing</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/what-is-ramp-up-in-load-testing/">What Is Ramp-Up in Load Testing?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/pre-launch-load-testing-checklist/">Pre-Launch Load Testing Checklist</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/faq/">Loadcurl FAQ</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>staging</category>
            <category>production</category>
            <category>safety</category>
            <category>load testing</category>
        </item>
        <item>
            <title><![CDATA[How to Read an API Load Test Report]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/</guid>
            <pubDate>Tue, 08 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[A practical walkthrough of Loadcurl reports: success rate, throughput vs target RPS, p95/p99 latency scopes, HTTP outcomes, and PDF export.]]></description>
            <content:encoded><![CDATA[<p>A load test without a readable report is just expensive noise. Here is how to read a Loadcurl-style HTTP report so you can decide pass/fail in minutes.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-the-report-lives">Where the report lives<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#where-the-report-lives" class="hash-link" aria-label="Direct link to Where the report lives" title="Direct link to Where the report lives" translate="no">​</a></h2>
<p>After <strong>Start test</strong>, open the run from <strong>Dashboard</strong> or <strong>Tests</strong>. The run page polls about every <strong>3 seconds</strong> (no websockets). Timeline: <strong>Created → Resources → Testing → Report</strong> (or failed / stopped).</p>
<p>While the report is calculating you may see a processing state — wait. There is <strong>no letter grade</strong> and <strong>no public share link</strong>. Download a <strong>PDF</strong> or keep teammates in the same workspace.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="start-with-the-highlights">Start with the highlights<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#start-with-the-highlights" class="hash-link" aria-label="Direct link to Start with the highlights" title="Direct link to Start with the highlights" translate="no">​</a></h2>
<p>Most reports surface:</p>
<ul>
<li class=""><strong>Success rate</strong></li>
<li class=""><strong>Total requests</strong></li>
<li class=""><strong>Average latency</strong></li>
<li class=""><strong>Average RPS</strong></li>
</ul>
<p>Use these as a headline, not the verdict. Dig into throughput, latency percentiles, and status mix next.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="request-summary-correctness-under-load">Request summary: correctness under load<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#request-summary-correctness-under-load" class="hash-link" aria-label="Direct link to Request summary: correctness under load" title="Direct link to Request summary: correctness under load" translate="no">​</a></h2>
<p>Look for counts and rates such as:</p>
<ul>
<li class="">Total, completed, successful, failed</li>
<li class="">Timeouts and transport errors</li>
<li class="">HTTP <strong>2xx / 3xx / 4xx / 5xx</strong></li>
<li class="">Success, completion, failure, and timeout rates</li>
</ul>
<p>Ask:</p>
<ul>
<li class="">Are failures <strong>5xx</strong> (server) or <strong>4xx</strong> (client/auth/validation)?</li>
<li class="">Are <strong>timeouts</strong> rising — a sign of saturation or too-tight budgets?</li>
<li class="">Is “success rate” high while p99 is terrible? Users still feel pain.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="throughput-did-you-actually-hit-the-target">Throughput: did you actually hit the target?<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#throughput-did-you-actually-hit-the-target" class="hash-link" aria-label="Direct link to Throughput: did you actually hit the target?" title="Direct link to Throughput: did you actually hit the target?" translate="no">​</a></h2>
<p>Compare:</p>
<ul>
<li class=""><strong>Target RPS</strong> (what you configured)</li>
<li class="">Average / peak / minimum RPS achieved</li>
<li class="">Successful and completed RPS</li>
<li class="">RPS vs target (achievement)</li>
<li class="">Response bytes and bytes/sec (average and peak)</li>
</ul>
<p><strong>Interpretation tips:</strong></p>
<ul>
<li class="">Average RPS ≈ target, healthy errors → capacity looks good for that profile</li>
<li class="">Average RPS ≪ target → the API, network, or errors prevented the generators from sustaining load</li>
<li class="">Peak much higher than average with a bad p99 → unstable under hold</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="latency-read-percentiles-by-scope">Latency: read percentiles by scope<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#latency-read-percentiles-by-scope" class="hash-link" aria-label="Direct link to Latency: read percentiles by scope" title="Direct link to Latency: read percentiles by scope" translate="no">​</a></h2>
<p>Reports often group latency for <strong>all</strong>, <strong>completed</strong>, and <strong>successful</strong> requests:</p>
<ul>
<li class="">Min, average, max, standard deviation</li>
<li class=""><strong>p50, p75, p90, p95, p99</strong></li>
</ul>
<p>Prefer <strong>p95 / p99 on successful requests</strong> for SLO conversations. If “all” looks much worse than “successful,” failures and timeouts are dominating the tail.</p>
<p>Deep dive: <a class="" href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/">What Is p95 and p99 Latency?</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="request-results-table">Request results table<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#request-results-table" class="hash-link" aria-label="Direct link to Request results table" title="Direct link to Request results table" translate="no">​</a></h2>
<p>Paginated per-request outcomes (<strong>Completed</strong>, <strong>Timeout</strong>, <strong>Error</strong>) with status codes help you spot patterns — a burst of 429s, a dependency 502, or slow payloads. Expand a row when body/error detail is present.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="request-hold-quota-context">Request hold (quota context)<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#request-hold-quota-context" class="hash-link" aria-label="Direct link to Request hold (quota context)" title="Direct link to Request hold (quota context)" translate="no">​</a></h2>
<p>On the live run you may also see <strong>Reserved / Consumed / Returned</strong> for the quota hold (<code>duration × RPS</code>). Stopping early <strong>releases</strong> unused hold. That is billing mechanics — not a performance metric — but it explains why Usage changed.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-simple-passfail-script">A simple pass/fail script<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#a-simple-passfail-script" class="hash-link" aria-label="Direct link to A simple pass/fail script" title="Direct link to A simple pass/fail script" translate="no">​</a></h2>
<p>Before the run, write criteria. After the report:</p>
<ol>
<li class="">Throughput within ~X% of target?</li>
<li class="">Successful p95 / p99 under budget?</li>
<li class="">Error + timeout rates under threshold?</li>
<li class="">Any surprise 429/5xx pattern?</li>
</ol>
<p>If no → open <a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a> and re-run the <strong>same</strong> profile after one change.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="share-the-pdf">Share the PDF<a href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/#share-the-pdf" class="hash-link" aria-label="Direct link to Share the PDF" title="Direct link to Share the PDF" translate="no">​</a></h2>
<p>Download PDF once the report is ready. Attach it to the launch checklist or incident doc so product and infra argue from the same numbers.</p>
<p>Product reference: <a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">Tests and reports</a>.</p>]]></content:encoded>
            <category>How-to guides</category>
            <category>load test report</category>
            <category>latency</category>
            <category>throughput</category>
            <category>RPS</category>
        </item>
        <item>
            <title><![CDATA[How to Verify a Domain for Load Testing (DNS TXT vs HTTP File)]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/</guid>
            <pubDate>Mon, 07 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn why Loadcurl requires domain verification, how DNS TXT and HTTP file challenges work, caps, expiry, and which method to choose.]]></description>
            <content:encoded><![CDATA[<p>Loadcurl will not send load-test traffic to arbitrary public URLs. Your workspace must <strong>verify</strong> the hostname first. That ownership gate protects the internet — and your own reputation — from accidental (or abusive) load.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-verification-exists">Why verification exists<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#why-verification-exists" class="hash-link" aria-label="Direct link to Why verification exists" title="Direct link to Why verification exists" translate="no">​</a></h2>
<p>Without it, any account could aim cloud generators at someone else’s API. Verification proves you control the DNS or the HTTP origin for that host.</p>
<p>A test URL is allowed when its hostname <strong>equals</strong> a verified domain or is a <strong>subdomain</strong> of one. Example: verifying <code>example.com</code> also covers <code>api.example.com</code> and <code>staging.example.com</code>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="where-to-do-it">Where to do it<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#where-to-do-it" class="hash-link" aria-label="Direct link to Where to do it" title="Direct link to Where to do it" translate="no">​</a></h2>
<p>In the dashboard: <strong>Domains</strong> (<code>/organization/domains</code>).</p>
<ul>
<li class="">Any member can <strong>view</strong> domains</li>
<li class=""><strong>Owner</strong> and <strong>Admin</strong> can add, verify, and remove</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="caps">Caps<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#caps" class="hash-link" aria-label="Direct link to Caps" title="Direct link to Caps" translate="no">​</a></h3>
<table><thead><tr><th>Workspace</th><th>Max domains</th></tr></thead><tbody><tr><td>Personal</td><td><strong>1</strong></td></tr><tr><td>Company</td><td><strong>10</strong></td></tr></tbody></table>
<p>The cap counts pending, failed, and verified rows.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="method-a-dns-txt-preferred">Method A: DNS TXT (preferred)<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#method-a-dns-txt-preferred" class="hash-link" aria-label="Direct link to Method A: DNS TXT (preferred)" title="Direct link to Method A: DNS TXT (preferred)" translate="no">​</a></h2>
<p>Add a TXT record:</p>
<table><thead><tr><th>Field</th><th>Value</th></tr></thead><tbody><tr><td><strong>Name / host</strong></td><td><code>_loadcurl.{your-domain}</code></td></tr><tr><td><strong>Value</strong></td><td><code>loadcurl-verify={token}</code></td></tr></tbody></table>
<p>The exact token is shown in the app when you add the domain. DNS can take a few minutes to propagate — then click <strong>Verify</strong> again.</p>
<p><strong>Choose DNS TXT when:</strong> you control DNS, want a durable proof, or the app sits behind a CDN that makes file checks awkward.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="method-b-http-file">Method B: HTTP file<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#method-b-http-file" class="hash-link" aria-label="Direct link to Method B: HTTP file" title="Direct link to Method B: HTTP file" translate="no">​</a></h2>
<p>Serve this path over HTTPS (HTTP is tried if HTTPS fails):</p>
<p><code>https://{your-domain}/.well-known/loadcurl-verification.txt</code></p>
<p>The body must be the challenge token. <strong>Redirects are rejected.</strong> The check times out after a few seconds.</p>
<p><strong>Choose HTTP file when:</strong> you can deploy a static file quickly but DNS changes are slow (or owned by another team).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="challenge-expiry-and-conflicts">Challenge expiry and conflicts<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#challenge-expiry-and-conflicts" class="hash-link" aria-label="Direct link to Challenge expiry and conflicts" title="Direct link to Challenge expiry and conflicts" translate="no">​</a></h2>
<ul>
<li class="">Pending challenges last <strong>7 days</strong>. If expired, add the domain again for a new token.</li>
<li class="">You cannot verify a hostname another organization already has <strong>verified</strong>.</li>
<li class="">Statuses: <strong>Pending</strong>, <strong>Verified</strong>, <strong>Failed</strong>.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-you-can-enter">What you can enter<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#what-you-can-enter" class="hash-link" aria-label="Direct link to What you can enter" title="Direct link to What you can enter" translate="no">​</a></h2>
<ul>
<li class="">A public DNS hostname (FQDN)</li>
<li class="">Not an IP address, port, wildcard, <code>localhost</code>, or platform apex names like <code>vercel.app</code></li>
</ul>
<p>Paste a full URL if you want — Loadcurl keeps the <strong>host</strong> only.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="recommended-setup-for-teams">Recommended setup for teams<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#recommended-setup-for-teams" class="hash-link" aria-label="Direct link to Recommended setup for teams" title="Direct link to Recommended setup for teams" translate="no">​</a></h2>
<ol>
<li class="">Verify the <strong>staging</strong> apex or API host first</li>
<li class="">Upgrade to a <strong>company</strong> workspace if you need multiple hosts (app, API, staging) — up to 10</li>
<li class="">Keep production verification only if you run planned game days</li>
<li class="">Document which method you used in the runbook</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="verification-is-not-a-safety-guarantee">Verification is not a safety guarantee<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#verification-is-not-a-safety-guarantee" class="hash-link" aria-label="Direct link to Verification is not a safety guarantee" title="Direct link to Verification is not a safety guarantee" translate="no">​</a></h2>
<p>Proving ownership does <strong>not</strong> make unlimited production load safe. Prefer staging, use ramp-up, and set abort criteria. See <a class="" href="https://docs.loadcurl.com/blog/staging-vs-production-load-testing/">Staging vs Production Load Testing</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="after-verification">After verification<a href="https://docs.loadcurl.com/blog/how-to-verify-a-domain-for-load-testing/#after-verification" class="hash-link" aria-label="Direct link to After verification" title="Direct link to After verification" translate="no">​</a></h2>
<p>Open <strong>New test</strong>, compose or paste curl / Postman, set duration / ramp-up / target RPS, and start. Only verified hosts (and their subdomains) are accepted.</p>
<p>Full product steps: <a class="" href="https://docs.loadcurl.com/docs/tutorial/domains/">docs — Verify a domain</a>.</p>]]></content:encoded>
            <category>Loadcurl platform</category>
            <category>domain verification</category>
            <category>DNS TXT</category>
            <category>security</category>
        </item>
        <item>
            <title><![CDATA[How to Load Test an API from Postman]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/</guid>
            <pubDate>Sun, 06 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Turn a working Postman request into an API load test: export or copy the call, paste into Loadcurl, set RPS and ramp-up, then read the report.]]></description>
            <content:encoded><![CDATA[<p>Postman is excellent for building and debugging one HTTP request. It is not a load generator. The fastest path to a trustworthy RPS run is: <strong>perfect the call in Postman, then replay it under a controlled load profile</strong>.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-postman-alone-is-not-enough">Why Postman alone is not enough<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#why-postman-alone-is-not-enough" class="hash-link" aria-label="Direct link to Why Postman alone is not enough" title="Direct link to Why Postman alone is not enough" translate="no">​</a></h2>
<p>Collection Runner and simple scripts can fire many requests, but they rarely give you:</p>
<ul>
<li class="">Precise <strong>target RPS</strong> with ramp-up</li>
<li class="">Clean <strong>p95 / p99</strong> under sustained hold</li>
<li class="">Throughput vs target and HTTP outcome mix in one report</li>
<li class="">Cloud generators that are not capped by your laptop</li>
</ul>
<p>Treat Postman as the <strong>authoring</strong> tool. Treat a load dashboard as the <strong>measurement</strong> tool.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-1-make-the-request-correct-in-postman">Step 1: Make the request correct in Postman<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#step-1-make-the-request-correct-in-postman" class="hash-link" aria-label="Direct link to Step 1: Make the request correct in Postman" title="Direct link to Step 1: Make the request correct in Postman" translate="no">​</a></h2>
<p>On staging (preferred):</p>
<ol>
<li class="">Method, URL, query params, headers, and JSON body match production shape</li>
<li class="">Auth works (Bearer, API key, etc.)</li>
<li class="">You get the expected status code and body</li>
<li class="">Secrets are staging-scoped — not production admin tokens</li>
</ol>
<p>Save that request. You will reuse the same shape under load.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-2-get-a-pasteable-snippet">Step 2: Get a pasteable snippet<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#step-2-get-a-pasteable-snippet" class="hash-link" aria-label="Direct link to Step 2: Get a pasteable snippet" title="Direct link to Step 2: Get a pasteable snippet" translate="no">​</a></h2>
<p>Depending on your Postman version:</p>
<ul>
<li class=""><strong>Code snippet → cURL</strong> from the request, or</li>
<li class="">Copy as curl / export the HTTP details your team already shares</li>
</ul>
<p>Loadcurl’s composer accepts <strong>curl / Postman paste</strong> and fills method, URL, headers, params, and body for you. You can also fill those fields manually on <strong>New test</strong>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-3-verify-the-hostname-in-loadcurl">Step 3: Verify the hostname in Loadcurl<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#step-3-verify-the-hostname-in-loadcurl" class="hash-link" aria-label="Direct link to Step 3: Verify the hostname in Loadcurl" title="Direct link to Step 3: Verify the hostname in Loadcurl" translate="no">​</a></h2>
<p>Loadcurl only sends traffic to hosts your workspace has verified. Open <strong>Domains</strong>, add the hostname from your Postman URL (or paste the full URL — only the host is kept), then verify with DNS TXT or HTTP file.</p>
<p>Verifying <code>example.com</code> also covers <code>api.example.com</code>. Personal workspaces: <strong>1</strong> domain. Company: up to <strong>10</strong>.</p>
<p>Details: <a class="" href="https://docs.loadcurl.com/docs/tutorial/domains/">Verify a domain</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-4-paste-into-new-test-and-set-the-load-profile">Step 4: Paste into New test and set the load profile<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#step-4-paste-into-new-test-and-set-the-load-profile" class="hash-link" aria-label="Direct link to Step 4: Paste into New test and set the load profile" title="Direct link to Step 4: Paste into New test and set the load profile" translate="no">​</a></h2>
<ol>
<li class="">Sign in at <a href="https://app.loadcurl.com/" target="_blank" rel="noopener noreferrer" class="">app.loadcurl.com</a></li>
<li class="">Open <strong>New test</strong></li>
<li class="">Paste the Postman/curl snippet (or fill the form)</li>
<li class="">Set <strong>duration</strong>, <strong>ramp-up</strong>, and <strong>target RPS</strong> within your plan caps</li>
<li class="">Start — the app checks remaining quota first (<code>duration × RPS</code> hold)</li>
</ol>
<p>Each Loadcurl test is <strong>one HTTP request</strong> repeated under that profile (no multi-step Postman collections yet).</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="step-5-watch-the-run-and-read-the-report">Step 5: Watch the run and read the report<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#step-5-watch-the-run-and-read-the-report" class="hash-link" aria-label="Direct link to Step 5: Watch the run and read the report" title="Direct link to Step 5: Watch the run and read the report" translate="no">​</a></h2>
<p>The run page polls about every <strong>3 seconds</strong> through pending → provisioned → running. When it finishes you get:</p>
<ul>
<li class="">Request summary (2xx–5xx, timeouts, success rates)</li>
<li class="">Throughput vs target RPS</li>
<li class="">Latency percentiles (p50–p99), often by scope (all / completed / successful)</li>
<li class="">PDF download for sharing</li>
</ul>
<p>See <a class="" href="https://docs.loadcurl.com/blog/how-to-read-an-api-load-test-report/">How to Read an API Load Test Report</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="postman-collection-tips-that-transfer-cleanly">Postman collection tips that transfer cleanly<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#postman-collection-tips-that-transfer-cleanly" class="hash-link" aria-label="Direct link to Postman collection tips that transfer cleanly" title="Direct link to Postman collection tips that transfer cleanly" translate="no">​</a></h2>
<ul>
<li class="">Prefer environment variables resolved <strong>before</strong> you copy curl (so the pasted URL is concrete)</li>
<li class="">Avoid Postman-only pre-request scripts that mint tokens unless you also set the final header in the paste</li>
<li class="">Keep body JSON identical to what you validated</li>
<li class="">Name the Loadcurl test after the Postman request so history stays searchable</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="common-mistakes">Common mistakes<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#common-mistakes" class="hash-link" aria-label="Direct link to Common mistakes" title="Direct link to Common mistakes" translate="no">​</a></h2>
<ul>
<li class="">Pasting a production URL you have not verified (or should not load-test)</li>
<li class="">Skipping ramp-up after a gentle Postman check</li>
<li class="">Judging success only by Collection Runner “pass” counts instead of p95/p99</li>
<li class="">Forgetting quota: a 600s × 200 RPS run holds <strong>120,000</strong> requests</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-guides">Related guides<a href="https://docs.loadcurl.com/blog/how-to-load-test-an-api-from-postman/#related-guides" class="hash-link" aria-label="Direct link to Related guides" title="Direct link to Related guides" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/">How to Perform Load Testing Using cURL</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-calculate-rps-for-api-load-testing/">How to Calculate RPS</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/getting-started/">Getting started</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>Postman</category>
            <category>API load testing</category>
            <category>HTTP</category>
        </item>
        <item>
            <title><![CDATA[Cloud-Based vs Local Load Testing]]></title>
            <link>https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/</link>
            <guid>https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/</guid>
            <pubDate>Sat, 05 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Compare cloud-based and local API load testing — accuracy, scale, ops overhead, and when a dashboard with cloud generators beats a laptop script.]]></description>
            <content:encoded><![CDATA[<p>Should you generate load from your laptop or from the cloud? Both work — for different jobs. Choosing wrong wastes time or produces misleading percentiles.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="local-load-testing">Local load testing<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#local-load-testing" class="hash-link" aria-label="Direct link to Local load testing" title="Direct link to Local load testing" translate="no">​</a></h2>
<p><strong>Local</strong> means traffic originates from your machine or a self-managed VM in your network (k6 on a laptop, Locust on a bastion, shell parallel curl, etc.).</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="strengths">Strengths<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#strengths" class="hash-link" aria-label="Direct link to Strengths" title="Direct link to Strengths" translate="no">​</a></h3>
<ul>
<li class="">Fast feedback while debugging a single endpoint</li>
<li class="">No extra SaaS account for a quick experiment</li>
<li class="">Full control over the generator process</li>
<li class="">Easy to poke private APIs on a VPN</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="weaknesses">Weaknesses<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#weaknesses" class="hash-link" aria-label="Direct link to Weaknesses" title="Direct link to Weaknesses" translate="no">​</a></h3>
<ul>
<li class="">Laptop CPU, Wi‑Fi, and file descriptors cap achievable RPS</li>
<li class="">Office networks and VPNs distort latency</li>
<li class="">Hard to produce clean, repeatable p95/p99 at scale</li>
<li class="">You own patching, scaling, and multi-machine coordination</li>
<li class="">Easy to accidentally DDoS a shared staging box from “just a script”</li>
</ul>
<p>Local is excellent for <strong>functional confidence</strong> and small smoke loads. It is a weak source of truth for launch capacity.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="cloud-based-load-testing">Cloud-based load testing<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#cloud-based-load-testing" class="hash-link" aria-label="Direct link to Cloud-based load testing" title="Direct link to Cloud-based load testing" translate="no">​</a></h2>
<p><strong>Cloud-based</strong> means managed generators run in provider infrastructure. You configure the HTTP request and load profile in a UI or API; workers elsewhere send traffic.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="strengths-1">Strengths<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#strengths-1" class="hash-link" aria-label="Direct link to Strengths" title="Direct link to Strengths" translate="no">​</a></h3>
<ul>
<li class="">Higher sustained RPS without turning your Mac into a heater</li>
<li class="">More stable generator capacity and networking</li>
<li class="">Dashboards, reports, and PDF export without building them</li>
<li class="">Team sharing of tests, domains, and quota</li>
<li class="">Less ops work than maintaining your own load cluster</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="weaknesses-1">Weaknesses<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#weaknesses-1" class="hash-link" aria-label="Direct link to Weaknesses" title="Direct link to Weaknesses" translate="no">​</a></h3>
<ul>
<li class="">Requires network path from cloud generators to your target (public staging or allowed ingress)</li>
<li class="">Usage is often gated by plan limits / request quota</li>
<li class="">You must still instrument <strong>your</strong> systems to find bottlenecks</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="accuracy-where-latency-is-measured">Accuracy: where latency is measured<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#accuracy-where-latency-is-measured" class="hash-link" aria-label="Direct link to Accuracy: where latency is measured" title="Direct link to Accuracy: where latency is measured" translate="no">​</a></h2>
<p>Latency always includes the path from <strong>generator → target</strong>.</p>
<ul>
<li class="">Local over VPN can look worse than real users</li>
<li class="">Cloud generators may sit closer to (or farther from) your region than your users</li>
<li class="">Absolute numbers matter less than <strong>trends</strong> across comparable runs</li>
</ul>
<p>Keep the generator location consistent when comparing releases.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="ops-and-safety">Ops and safety<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#ops-and-safety" class="hash-link" aria-label="Direct link to Ops and safety" title="Direct link to Ops and safety" translate="no">​</a></h2>
<table><thead><tr><th>Concern</th><th>Local</th><th>Cloud dashboard</th></tr></thead><tbody><tr><td>Install workers</td><td>Yes</td><td>No</td></tr><tr><td>Scale to high RPS</td><td>Manual</td><td>Built-in generators</td></tr><tr><td>Team sharing</td><td>Homegrown</td><td>Workspaces</td></tr><tr><td>Ownership controls</td><td>DIY</td><td>Domain verification (e.g. Loadcurl)</td></tr><tr><td>Reporting</td><td>DIY or CLI output</td><td>Latency, throughput, PDF</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-use-which">When to use which<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#when-to-use-which" class="hash-link" aria-label="Direct link to When to use which" title="Direct link to When to use which" translate="no">​</a></h2>
<p><strong>Use local when:</strong></p>
<ul>
<li class="">Validating curl/auth against staging</li>
<li class="">Reproducing a single bug</li>
<li class="">Hitting a private endpoint only reachable on VPN</li>
<li class="">Running tiny smokes (&lt; tens of RPS)</li>
</ul>
<p><strong>Use cloud when:</strong></p>
<ul>
<li class="">Validating peak RPS and p95/p99 for launch</li>
<li class="">You need repeatable reports for stakeholders</li>
<li class="">Multiple engineers share profiles and history</li>
<li class="">Local hardware or network is the limiter</li>
</ul>
<p>Many teams do both: curl locally, then paste the same curl into a cloud run.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-loadcurl-approaches-this">How Loadcurl approaches this<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#how-loadcurl-approaches-this" class="hash-link" aria-label="Direct link to How Loadcurl approaches this" title="Direct link to How Loadcurl approaches this" translate="no">​</a></h2>
<p><a href="https://loadcurl.com/" target="_blank" rel="noopener noreferrer" class="">Loadcurl</a> is cloud-based by design: no CLI or local workers to install. You verify a hostname, compose a request or paste <strong>curl / Postman</strong>, set duration, ramp-up, and target RPS, then start. Generators run in the cloud; the run page polls live status; you get a report with latency percentiles, throughput vs target, and HTTP outcomes.</p>
<p>That matches the “author with curl, execute in the cloud” workflow described in <a class="" href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/">How to Perform Load Testing Using cURL</a>.</p>
<p>Get started: <a class="" href="https://docs.loadcurl.com/docs/tutorial/intro/">docs intro</a> · <a href="https://app.loadcurl.com/auth/register" target="_blank" rel="noopener noreferrer" class="">app registration</a></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bottom-line">Bottom line<a href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/#bottom-line" class="hash-link" aria-label="Direct link to Bottom line" title="Direct link to Bottom line" translate="no">​</a></h2>
<p>Local scripts are a scalpel. Cloud load testing is a measuring bench. Use the scalpel to shape the request; use the bench to prove capacity.</p>]]></content:encoded>
            <category>Tools &amp; workflows</category>
            <category>cloud load testing</category>
            <category>local load testing</category>
            <category>RPS</category>
        </item>
        <item>
            <title><![CDATA[How to Identify API Bottlenecks]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/</guid>
            <pubDate>Fri, 04 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Find API bottlenecks during load tests using latency percentiles, throughput gaps, HTTP errors, and infrastructure signals — a practical debugging checklist.]]></description>
            <content:encoded><![CDATA[<p>A load test that “fails” is useful only if you can name the <strong>bottleneck</strong>. Otherwise you are left with a slow PDF and a vague urge to add more servers.</p>
<!-- -->
<p>Use the report as a symptom list, then confirm with infrastructure signals.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="start-with-four-report-signals">Start with four report signals<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#start-with-four-report-signals" class="hash-link" aria-label="Direct link to Start with four report signals" title="Direct link to Start with four report signals" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-throughput-vs-target-rps">1. Throughput vs target RPS<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#1-throughput-vs-target-rps" class="hash-link" aria-label="Direct link to 1. Throughput vs target RPS" title="Direct link to 1. Throughput vs target RPS" translate="no">​</a></h3>
<p>If achieved RPS stays well below target while the generators are healthy, the <strong>server side is refusing or delaying work</strong> — saturation, rate limits, or connection refusal.</p>
<p>If achieved RPS matches target but latency is terrible, you are successfully delivering pain at the requested rate.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-p95--p99-shape-over-time">2. p95 / p99 shape over time<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#2-p95--p99-shape-over-time" class="hash-link" aria-label="Direct link to 2. p95 / p99 shape over time" title="Direct link to 2. p95 / p99 shape over time" translate="no">​</a></h3>
<ul>
<li class=""><strong>Immediate</strong> high p99 → likely misconfig, cold dependency, or too-high starting RPS</li>
<li class=""><strong>Rising</strong> p99 during a hold → queues filling, pools exhausting, GC, lock contention</li>
<li class=""><strong>p50 flat, p99 rising</strong> → classic tail saturation</li>
</ul>
<p>See <a class="" href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/">What Is p95 and p99 Latency?</a>.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-http-status-mix">3. HTTP status mix<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#3-http-status-mix" class="hash-link" aria-label="Direct link to 3. HTTP status mix" title="Direct link to 3. HTTP status mix" translate="no">​</a></h3>
<ul>
<li class=""><strong>429</strong> — limiter or WAF; may be intentional protection</li>
<li class=""><strong>5xx</strong> — application or upstream failure under load</li>
<li class=""><strong>Timeouts</strong> — somewhere in the chain exceeded client or gateway budgets</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-successful-vs-all-latency-scopes">4. Successful vs all latency scopes<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#4-successful-vs-all-latency-scopes" class="hash-link" aria-label="Direct link to 4. Successful vs all latency scopes" title="Direct link to 4. Successful vs all latency scopes" translate="no">​</a></h3>
<p>If successful latency looks fine but “all” looks awful, failures/timeouts dominate the story. Fix errors before chasing micro-optimizations on the happy path.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="map-symptoms-to-likely-layers">Map symptoms to likely layers<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#map-symptoms-to-likely-layers" class="hash-link" aria-label="Direct link to Map symptoms to likely layers" title="Direct link to Map symptoms to likely layers" translate="no">​</a></h2>
<table><thead><tr><th>Symptom</th><th>Suspect</th></tr></thead><tbody><tr><td>High DB CPU / lock waits</td><td>Queries, missing indexes, hot rows</td></tr><tr><td>Pool wait time up</td><td>DB/Redis pool too small vs RPS</td></tr><tr><td>App CPU pegged</td><td>Inefficient code, crypto, serialization</td></tr><tr><td>App CPU low, latency high</td><td>Waiting on downstream I/O</td></tr><tr><td>LB 5xx / reconnect storms</td><td>Upstream crash loops, keep-alive issues</td></tr><tr><td>Sudden 429s</td><td>Gateway or app rate limits</td></tr><tr><td>Only one instance hot</td><td>Bad load balancing or sticky sessions</td></tr></tbody></table>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-debugging-loop-that-works">A debugging loop that works<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#a-debugging-loop-that-works" class="hash-link" aria-label="Direct link to A debugging loop that works" title="Direct link to A debugging loop that works" translate="no">​</a></h2>
<ol>
<li class=""><strong>Reproduce</strong> at the lowest RPS that shows the symptom</li>
<li class=""><strong>Capture</strong> report + app/DB dashboards for the same time window</li>
<li class=""><strong>Hypothesize</strong> one layer</li>
<li class=""><strong>Change</strong> one thing (index, pool size, cache, instance count)</li>
<li class=""><strong>Re-run</strong> the same profile and compare PDFs</li>
</ol>
<p>Do not climb to 10k RPS while debugging a failure that appears at 500.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="application-level-checks">Application-level checks<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#application-level-checks" class="hash-link" aria-label="Direct link to Application-level checks" title="Direct link to Application-level checks" translate="no">​</a></h2>
<ul>
<li class="">Slow query logs during the run</li>
<li class="">Contended locks or unique constraints on hot keys</li>
<li class="">N+1 calls hidden behind one API endpoint</li>
<li class="">Oversized payloads and unnecessary JSON work</li>
<li class="">Chatty logging or tracing at high RPS</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="dependency-checks">Dependency checks<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#dependency-checks" class="hash-link" aria-label="Direct link to Dependency checks" title="Direct link to Dependency checks" translate="no">​</a></h2>
<p>Fan-out multiplies load. If one user request triggers four internal calls, your dependency may see far more RPS than the edge. Load test the hotspot and watch the dependency’s saturation metrics.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="client-side-false-bottlenecks">Client-side false bottlenecks<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#client-side-false-bottlenecks" class="hash-link" aria-label="Direct link to Client-side false bottlenecks" title="Direct link to Client-side false bottlenecks" translate="no">​</a></h2>
<p>Before blaming the API:</p>
<ul>
<li class="">Confirm generators actually reached target RPS</li>
<li class="">Rule out laptop/network limits for local tools</li>
<li class="">Prefer cloud generators for serious profiles (<a class="" href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/">comparison</a>)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="using-loadcurl-in-the-loop">Using Loadcurl in the loop<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#using-loadcurl-in-the-loop" class="hash-link" aria-label="Direct link to Using Loadcurl in the loop" title="Direct link to Using Loadcurl in the loop" translate="no">​</a></h2>
<p>Run the same New test profile repeatedly: identical curl, RPS, ramp-up, and duration. Compare latency percentiles, throughput achievement, and HTTP outcomes across PDFs while you change infra. The run page’s polled status helps you see when provisioning vs testing vs report phases occur — useful when correlating with cloud metrics.</p>
<p>Details: <a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">report card docs</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="bottleneck-anti-patterns">Bottleneck anti-patterns<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#bottleneck-anti-patterns" class="hash-link" aria-label="Direct link to Bottleneck anti-patterns" title="Direct link to Bottleneck anti-patterns" translate="no">​</a></h2>
<ul>
<li class="">Scaling app pods when the DB is the limiter</li>
<li class="">Raising timeouts to “fix” p99 (hides the queue)</li>
<li class="">Disabling rate limits in production to pass a test</li>
<li class="">Tuning without a fixed RPS profile for comparison</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-test-an-api-for-10000-requests-per-second/">How to Test an API for 10,000 RPS</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/">API Performance Testing Best Practices</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/common-api-performance-testing-mistakes/">Common Mistakes</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>bottlenecks</category>
            <category>debugging</category>
            <category>latency</category>
            <category>throughput</category>
        </item>
        <item>
            <title><![CDATA[API Performance Testing Best Practices]]></title>
            <link>https://docs.loadcurl.com/blog/api-performance-testing-best-practices/</link>
            <guid>https://docs.loadcurl.com/blog/api-performance-testing-best-practices/</guid>
            <pubDate>Thu, 03 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Battle-tested API performance testing best practices: environments, RPS ladders, SLOs, realistic requests, observability, and repeatable reports.]]></description>
            <content:encoded><![CDATA[<p>Good API performance testing is less about exotic tools and more about <strong>discipline</strong>: realistic requests, clear SLOs, controlled RPS, and comparable reports.</p>
<!-- -->
<p>Use this checklist as your default playbook.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-define-success-before-you-generate-traffic">1. Define success before you generate traffic<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#1-define-success-before-you-generate-traffic" class="hash-link" aria-label="Direct link to 1. Define success before you generate traffic" title="Direct link to 1. Define success before you generate traffic" translate="no">​</a></h2>
<p>Write pass criteria in one line:</p>
<blockquote>
<p>At 200 RPS for 10 minutes with 60s ramp-up, successful p95 &lt; 250 ms, errors &lt; 0.5%, timeouts &lt; 0.1%.</p>
</blockquote>
<p>Without this, every run becomes a debate.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-prefer-staging-that-mirrors-production">2. Prefer staging that mirrors production<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#2-prefer-staging-that-mirrors-production" class="hash-link" aria-label="Direct link to 2. Prefer staging that mirrors production" title="Direct link to 2. Prefer staging that mirrors production" translate="no">​</a></h2>
<p>Match instance sizes, connection limits, cache configuration, and auth paths as closely as you can. Document gaps so you do not over-claim.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-author-realistic-http-requests">3. Author realistic HTTP requests<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#3-author-realistic-http-requests" class="hash-link" aria-label="Direct link to 3. Author realistic HTTP requests" title="Direct link to 3. Author realistic HTTP requests" translate="no">​</a></h2>
<p>Start from production traces or a known-good <strong>curl / Postman</strong> snippet. Include required headers and a representative JSON body. Avoid empty happy paths that skip validation or DB work.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-think-in-rps-ramp-up-and-duration">4. Think in RPS, ramp-up, and duration<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#4-think-in-rps-ramp-up-and-duration" class="hash-link" aria-label="Direct link to 4. Think in RPS, ramp-up, and duration" title="Direct link to 4. Think in RPS, ramp-up, and duration" translate="no">​</a></h2>
<ul>
<li class=""><strong>RPS</strong> — arrival rate you care about</li>
<li class=""><strong>Ramp-up</strong> — time to reach that rate</li>
<li class=""><strong>Duration</strong> — hold long enough to exit warmup</li>
</ul>
<p>Calculate RPS from traffic, not vibes — see <a class="" href="https://docs.loadcurl.com/blog/how-to-calculate-rps-for-api-load-testing/">How to Calculate RPS</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="5-climb-a-ladder">5. Climb a ladder<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#5-climb-a-ladder" class="hash-link" aria-label="Direct link to 5. Climb a ladder" title="Direct link to 5. Climb a ladder" translate="no">​</a></h2>
<p>Smoke → baseline → target → optional stress. Stop when SLOs fail; fix bottlenecks; continue. Jumping straight to peak hides the first breaking layer.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="6-watch-percentiles-and-errors-together">6. Watch percentiles and errors together<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#6-watch-percentiles-and-errors-together" class="hash-link" aria-label="Direct link to 6. Watch percentiles and errors together" title="Direct link to 6. Watch percentiles and errors together" translate="no">​</a></h2>
<p>Track p95/p99 on successful responses <strong>and</strong> error/timeout rates. Hitting target throughput with rising 5xx is not a pass. Background: <a class="" href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/">p95 and p99</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="7-keep-observability-open-during-the-run">7. Keep observability open during the run<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#7-keep-observability-open-during-the-run" class="hash-link" aria-label="Direct link to 7. Keep observability open during the run" title="Direct link to 7. Keep observability open during the run" translate="no">​</a></h2>
<p>Dashboards for CPU, memory, DB connections, lock waits, queue depth, and downstream latency turn “it got slow” into “the pool saturated at 2k RPS.”</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="8-change-one-variable-between-comparisons">8. Change one variable between comparisons<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#8-change-one-variable-between-comparisons" class="hash-link" aria-label="Direct link to 8. Change one variable between comparisons" title="Direct link to 8. Change one variable between comparisons" translate="no">​</a></h2>
<p>Same request, same RPS profile, one code or infra change. Export PDFs so reviews share the same artifact.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="9-verify-ownership-and-respect-safety">9. Verify ownership and respect safety<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#9-verify-ownership-and-respect-safety" class="hash-link" aria-label="Direct link to 9. Verify ownership and respect safety" title="Direct link to 9. Verify ownership and respect safety" translate="no">​</a></h2>
<p>Only test hosts you control. Use domain verification. Prefer staging. Coordinate production game days. Traffic is real.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="10-re-run-after-meaningful-deploys">10. Re-run after meaningful deploys<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#10-re-run-after-meaningful-deploys" class="hash-link" aria-label="Direct link to 10. Re-run after meaningful deploys" title="Direct link to 10. Re-run after meaningful deploys" translate="no">​</a></h2>
<p>A launch-week hero run goes stale. Keep a short regression profile in the team workspace and re-run when risk is high.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="11-separate-plan-capacity-from-vanity-peaks">11. Separate Plan capacity from vanity peaks<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#11-separate-plan-capacity-from-vanity-peaks" class="hash-link" aria-label="Direct link to 11. Separate Plan capacity from vanity peaks" title="Direct link to 11. Separate Plan capacity from vanity peaks" translate="no">​</a></h2>
<p>Know your tool and plan limits (max RPS, duration, monthly request quota). In Loadcurl, a start holds roughly <code>duration × RPS</code>. Check Usage before large rehearsals.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="12-share-results-in-the-language-of-the-product">12. Share results in the language of the product<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#12-share-results-in-the-language-of-the-product" class="hash-link" aria-label="Direct link to 12. Share results in the language of the product" title="Direct link to 12. Share results in the language of the product" translate="no">​</a></h2>
<p>Translate metrics for stakeholders: “We can sustain expected launch peak with p95 under budget” beats “p99 was 412.”</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-minimal-recurring-profile">A minimal recurring profile<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#a-minimal-recurring-profile" class="hash-link" aria-label="Direct link to A minimal recurring profile" title="Direct link to A minimal recurring profile" translate="no">​</a></h2>
<table><thead><tr><th>Step</th><th>RPS</th><th>Duration</th><th>Purpose</th></tr></thead><tbody><tr><td>Smoke</td><td>10</td><td>2 min</td><td>Sanity</td></tr><tr><td>Baseline</td><td>50% peak</td><td>5 min</td><td>Trend</td></tr><tr><td>Peak</td><td>100% peak</td><td>10 min</td><td>SLO check</td></tr></tbody></table>
<p>Store the curl, the criteria, and the last PDF next to the service runbook.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-loadcurl-supports-the-practice">How Loadcurl supports the practice<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#how-loadcurl-supports-the-practice" class="hash-link" aria-label="Direct link to How Loadcurl supports the practice" title="Direct link to How Loadcurl supports the practice" translate="no">​</a></h2>
<p><a href="https://loadcurl.com/" target="_blank" rel="noopener noreferrer" class="">Loadcurl</a> keeps the loop tight: verify domain → paste curl / compose request → set RPS profile → poll live run → read latency/throughput report → export PDF. Personal workspaces work for solo engineers; company workspaces share tests, domains, and quota.</p>
<p>Docs: <a class="" href="https://docs.loadcurl.com/docs/tutorial/getting-started/">getting started</a>, <a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">report card</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/api-performance-testing-best-practices/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/common-api-performance-testing-mistakes/">Common API Performance Testing Mistakes</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/load-testing-vs-stress-testing-vs-performance-testing/">Load vs Stress vs Performance Testing</a></li>
</ul>]]></content:encoded>
            <category>Best practices</category>
            <category>API performance</category>
            <category>RPS</category>
        </item>
        <item>
            <title><![CDATA[How to Perform Load Testing Using cURL]]></title>
            <link>https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/</link>
            <guid>https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/</guid>
            <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Learn how curl fits into API load testing — from single-request debugging to pasting curl into a cloud load dashboard for RPS-based runs and reports.]]></description>
            <content:encoded><![CDATA[<p><strong>curl</strong> is the universal language of HTTP. Developers copy it from docs, browsers, and gateways. That makes it a natural starting point for API load testing — but curl alone is not a load generator.</p>
<!-- -->
<p>Here is how to use curl the right way: debug with it, then scale with a proper load profile.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-curl-is-good-at">What curl is good at<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#what-curl-is-good-at" class="hash-link" aria-label="Direct link to What curl is good at" title="Direct link to What curl is good at" translate="no">​</a></h2>
<ul>
<li class="">Reproducing a single failing request</li>
<li class="">Confirming auth headers and status codes</li>
<li class="">Timing one call with <code>-w</code> / <code>-o</code></li>
<li class="">Exporting a canonical request teammates can paste</li>
</ul>
<p>Example:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">curl -sS -X POST 'https://api.example.com/v1/orders' \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -H 'Authorization: Bearer TOKEN' \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -H 'Content-Type: application/json' \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  -d '{"sku":"sku_123","qty":1}'</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="what-curl-is-bad-at-for-load">What curl is bad at (for load)<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#what-curl-is-bad-at-for-load" class="hash-link" aria-label="Direct link to What curl is bad at (for load)" title="Direct link to What curl is bad at (for load)" translate="no">​</a></h2>
<p>Naive loops like <code>for i in {1..1000}; do curl ...; done</code> are <strong>not</strong> load tests:</p>
<ul>
<li class="">They are usually sequential, not concurrent</li>
<li class="">They do not control RPS precisely</li>
<li class="">They skew latency with client overhead</li>
<li class="">They rarely produce p95/p99 or throughput reports</li>
<li class="">Your laptop becomes the bottleneck quickly</li>
</ul>
<p>Shell parallelism (<code>xargs -P</code>, background jobs) is still a rough hammer — fine for a smoke blast, weak for capacity claims.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="a-practical-workflow-curl--load-test">A practical workflow: curl → load test<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#a-practical-workflow-curl--load-test" class="hash-link" aria-label="Direct link to A practical workflow: curl → load test" title="Direct link to A practical workflow: curl → load test" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="1-perfect-one-request-with-curl">1. Perfect one request with curl<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#1-perfect-one-request-with-curl" class="hash-link" aria-label="Direct link to 1. Perfect one request with curl" title="Direct link to 1. Perfect one request with curl" translate="no">​</a></h3>
<p>Make sure the call returns the expected status and body on staging. Fix auth, headers, and JSON first.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="2-capture-the-curl-or-postman-snippet">2. Capture the curl (or Postman) snippet<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#2-capture-the-curl-or-postman-snippet" class="hash-link" aria-label="Direct link to 2. Capture the curl (or Postman) snippet" title="Direct link to 2. Capture the curl (or Postman) snippet" translate="no">​</a></h3>
<p>Keep it as the source of truth for the request shape.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="3-paste-into-a-load-testing-dashboard">3. Paste into a load testing dashboard<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#3-paste-into-a-load-testing-dashboard" class="hash-link" aria-label="Direct link to 3. Paste into a load testing dashboard" title="Direct link to 3. Paste into a load testing dashboard" translate="no">​</a></h3>
<p>Tools like <a href="https://loadcurl.com/" target="_blank" rel="noopener noreferrer" class="">Loadcurl</a> accept <strong>curl / Postman paste</strong> into the composer, then let you set:</p>
<ul>
<li class="">Target <strong>RPS</strong></li>
<li class=""><strong>Ramp-up</strong></li>
<li class=""><strong>Duration</strong></li>
</ul>
<p>Cloud generators send the traffic; you are not installing workers. You must <strong>verify the domain</strong> before runs can target that host.</p>
<h3 class="anchor anchorTargetStickyNavbar_Vzrq" id="4-read-percentiles-and-http-outcomes">4. Read percentiles and HTTP outcomes<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#4-read-percentiles-and-http-outcomes" class="hash-link" aria-label="Direct link to 4. Read percentiles and HTTP outcomes" title="Direct link to 4. Read percentiles and HTTP outcomes" translate="no">​</a></h3>
<p>Judge the run on p95/p99, achieved RPS vs target, and error/timeout rates — not on how fast your shell loop felt.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="timing-a-single-request-with-curl">Timing a single request with curl<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#timing-a-single-request-with-curl" class="hash-link" aria-label="Direct link to Timing a single request with curl" title="Direct link to Timing a single request with curl" translate="no">​</a></h2>
<p>For quick local checks:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_e6Vv"><div class="token-line" style="color:#393A34"><span class="token plain">curl -sS -o /dev/null -w 'time_total=%{time_total}\nhttp_code=%{http_code}\n' \</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  'https://staging.example.com/health'</span><br></div></code></pre></div></div>
<p>Useful for debugging. Not a substitute for a multi-minute RPS hold.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="security-and-safety">Security and safety<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#security-and-safety" class="hash-link" aria-label="Direct link to Security and safety" title="Direct link to Security and safety" translate="no">​</a></h2>
<ul>
<li class="">Prefer staging tokens in curl history and shared snippets</li>
<li class="">Do not load test hosts you do not own</li>
<li class="">Strip secrets before pasting into tickets; rotate if leaked</li>
<li class="">Ramp up; production traffic is real</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="curl--loadcurl-in-practice">Curl + Loadcurl in practice<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#curl--loadcurl-in-practice" class="hash-link" aria-label="Direct link to Curl + Loadcurl in practice" title="Direct link to Curl + Loadcurl in practice" translate="no">​</a></h2>
<ol>
<li class="">Register at <a href="https://app.loadcurl.com/auth/register" target="_blank" rel="noopener noreferrer" class="">app.loadcurl.com</a></li>
<li class="">Verify your domain (<a class="" href="https://docs.loadcurl.com/docs/tutorial/domains/">docs</a>)</li>
<li class="">Open <strong>New test</strong> and paste your curl</li>
<li class="">Set RPS, ramp-up, duration</li>
<li class="">Start — the run page polls live status about every 3 seconds</li>
<li class="">Download the report PDF when finished</li>
</ol>
<p>This keeps curl as the authoring format while cloud infrastructure handles concurrency and reporting.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="when-to-stay-local-vs-go-cloud">When to stay local vs go cloud<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#when-to-stay-local-vs-go-cloud" class="hash-link" aria-label="Direct link to When to stay local vs go cloud" title="Direct link to When to stay local vs go cloud" translate="no">​</a></h2>
<p>Stay local for functional curl debugging. Move to cloud generators when you need sustained RPS, clean percentiles, and isolation from laptop limits — covered in <a class="" href="https://docs.loadcurl.com/blog/cloud-based-vs-local-load-testing/">Cloud-Based vs Local Load Testing</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-guides">Related guides<a href="https://docs.loadcurl.com/blog/how-to-perform-load-testing-using-curl/#related-guides" class="hash-link" aria-label="Direct link to Related guides" title="Direct link to Related guides" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/what-is-api-load-testing/">What Is API Load Testing?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-calculate-rps-for-api-load-testing/">How to Calculate RPS</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/docs/tutorial/getting-started/">Getting started</a></li>
</ul>]]></content:encoded>
            <category>How-to guides</category>
            <category>curl</category>
            <category>API testing</category>
            <category>load testing</category>
        </item>
        <item>
            <title><![CDATA[What Is p95 and p99 Latency?]]></title>
            <link>https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/</link>
            <guid>https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/</guid>
            <pubDate>Tue, 01 Sep 2026 00:00:00 GMT</pubDate>
            <description><![CDATA[Understand p50, p95, and p99 latency percentiles for API load testing — why averages lie, how tails form, and how to read them in a load test report.]]></description>
            <content:encoded><![CDATA[<p>When an API load test finishes, latency numbers dominate the conversation. <strong>p95</strong> and <strong>p99</strong> are the ones that matter for user experience and SLOs — yet they are easy to misread.</p>
<!-- -->
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="percentiles-in-one-sentence">Percentiles in one sentence<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#percentiles-in-one-sentence" class="hash-link" aria-label="Direct link to Percentiles in one sentence" title="Direct link to Percentiles in one sentence" translate="no">​</a></h2>
<p>If you sort all request latencies from fastest to slowest:</p>
<ul>
<li class=""><strong>p50</strong> (median) — half of requests were faster than this</li>
<li class=""><strong>p95</strong> — 95% were faster; only 5% were slower</li>
<li class=""><strong>p99</strong> — 99% were faster; only 1% were slower</li>
</ul>
<p>So a p95 of 200 ms means <strong>most</strong> traffic finished within 200 ms, while a small slice took longer.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="why-averages-fail">Why averages fail<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#why-averages-fail" class="hash-link" aria-label="Direct link to Why averages fail" title="Direct link to Why averages fail" translate="no">​</a></h2>
<p>Suppose 99 requests take 50 ms and one takes 5,000 ms. The average is ~100 ms — sounds fine. The p99 is 5,000 ms — clients are timing out.</p>
<p>Retries make this worse: slow calls spawn more calls, which raise load and create more slow calls.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="which-percentile-should-you-slo-on">Which percentile should you SLO on?<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#which-percentile-should-you-slo-on" class="hash-link" aria-label="Direct link to Which percentile should you SLO on?" title="Direct link to Which percentile should you SLO on?" translate="no">​</a></h2>
<p>Common patterns:</p>
<ul>
<li class=""><strong>User-facing APIs:</strong> p95 or p99 against a budget (e.g. p95 &lt; 300 ms)</li>
<li class=""><strong>Internal high-QPS services:</strong> often p99, because rare stalls still cascade</li>
<li class=""><strong>Batch / async:</strong> sometimes p95 is enough</li>
</ul>
<p>Pick one primary percentile and stick to it across reports so trends are comparable.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="successful-vs-all-requests">Successful vs all requests<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#successful-vs-all-requests" class="hash-link" aria-label="Direct link to Successful vs all requests" title="Direct link to Successful vs all requests" translate="no">​</a></h2>
<p>A subtle trap: including timeouts and failed calls in the same latency distribution as successes.</p>
<p>Depending on how your tool measures:</p>
<ul>
<li class="">Failed or timed-out requests may appear as very large latencies</li>
<li class="">Or they may be excluded from latency and counted only in error metrics</li>
</ul>
<p>Loadcurl reports latency with scopes such as <strong>all</strong>, <strong>completed</strong>, and <strong>successful</strong> — compare them. If “all” p99 blows up while “successful” looks fine, you may have a timeout / error problem rather than a slow-happy-path problem.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="how-tails-form-under-load">How tails form under load<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#how-tails-form-under-load" class="hash-link" aria-label="Direct link to How tails form under load" title="Direct link to How tails form under load" translate="no">​</a></h2>
<p>p99 often rises before p50 when:</p>
<ul>
<li class="">Thread or connection pools saturate</li>
<li class="">GC pauses appear</li>
<li class="">Lock contention increases</li>
<li class="">Downstream dependency latency spikes</li>
<li class="">Queueing delay builds at the load balancer</li>
</ul>
<p>That is why climbing an RPS ladder while watching <strong>p99</strong> catches trouble earlier than watching averages.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="reading-a-loadcurl-style-report">Reading a Loadcurl-style report<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#reading-a-loadcurl-style-report" class="hash-link" aria-label="Direct link to Reading a Loadcurl-style report" title="Direct link to Reading a Loadcurl-style report" translate="no">​</a></h2>
<p>In a typical HTTP load report you will see min, average, max, and percentiles (p50–p99), plus throughput vs target RPS and HTTP status mix.</p>
<p>A healthy load run at target RPS usually shows:</p>
<ul>
<li class="">Achieved throughput near target</li>
<li class="">Stable p95/p99 after warmup</li>
<li class="">Low error and timeout rates</li>
</ul>
<p>A warning run shows p50 flat while p99 climbs across the hold period — classic saturation.</p>
<p>See the <a class="" href="https://docs.loadcurl.com/docs/tutorial/report-card/">report card documentation</a> for how Loadcurl surfaces these metrics and PDF export.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="practical-tips">Practical tips<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#practical-tips" class="hash-link" aria-label="Direct link to Practical tips" title="Direct link to Practical tips" translate="no">​</a></h2>
<ul>
<li class="">Ignore or annotate the ramp-up window when comparing percentiles</li>
<li class="">Compare the same percentile scope between runs</li>
<li class="">Pair latency with error rate — fast 500s are not success</li>
<li class="">Set SLOs on the percentile your clients feel (often p95/p99), not the mean</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="related-reading">Related reading<a href="https://docs.loadcurl.com/blog/what-is-p95-and-p99-latency/#related-reading" class="hash-link" aria-label="Direct link to Related reading" title="Direct link to Related reading" translate="no">​</a></h2>
<ul>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/what-is-api-load-testing/">What Is API Load Testing?</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/how-to-identify-api-bottlenecks/">How to Identify API Bottlenecks</a></li>
<li class=""><a class="" href="https://docs.loadcurl.com/blog/common-api-performance-testing-mistakes/">Common API Performance Testing Mistakes</a></li>
</ul>]]></content:encoded>
            <category>Metrics &amp; SLOs</category>
            <category>latency</category>
            <category>p95</category>
            <category>p99</category>
            <category>SLOs</category>
        </item>
    </channel>
</rss>