Skip to content

Full Login Flow (Email Code) Load Test

ItemDetails
Test DateDecember 17, 2025
Target FlowComplete OAuth 2.0 login with Email Code
PurposeMeasure end-to-end login performance including Email Code verification
ShardingRegion Shards 32, Code Shards 8, Refresh Token 64

With 32-shard optimization, DO errors and latency spikes from the previous test (Dec 13) were completely eliminated. Stable operation confirmed at 150 LPS (Logins Per Second).

Target LPSCompleted FlowsSuccess RateP50P95P99DO P99Status
50 LPS7,312100%587ms688ms748ms2,846ms⚠️ Cold start
100 LPS14,624100%570ms696ms753ms1,393ms✅ Good
125 LPS18,232100%621ms761ms826ms1,153ms✅ Good
150 LPS21,937100%639ms756ms853ms955ms✅ Excellent
MetricDec 13 (16 shards)Dec 17 (32 shards)Improvement
100 LPS DO Errors443 (0.39%)0100% eliminated
150 LPS P953,015ms283ms91% reduction
150 LPS DO P991,648ms955ms42% reduction
Parameter50 LPS100 LPS125 LPS150 LPS
Executorramping-arrival-rateramping-arrival-rateramping-arrival-rateramping-arrival-rate
Test Duration3 min3 min3 min3 min
Preallocated VU200400500600
Max VU4006008001000
Seed Users500100012501500
Load Zoneamazon:us:portlandamazon:us:portlandamazon:us:portlandamazon:us:portland
StoreShardsGeneration
SessionStore32Gen 2
ChallengeStore32Gen 2
AuthCodeStore32Gen 2
RevocationStore32Gen 4
RefreshTokenRotator64Gen 4
flowchart LR
    A["1. AuthorizeInit<br/>(GET /authorize)"] --> B["2. Email Code Send<br/>(POST /api/v1/auth/direct/email-code/send)"]
    B --> C["3. Email Code Verify<br/>(POST /api/v1/auth/direct/email-code/verify)"]
    C --> D["4. AuthorizeCode<br/>(GET /authorize prompt=none)"]
    D --> E["5. Token<br/>(POST /token)"]
  1. AuthorizeInit: OAuth 2.0 authorization request, display login page
  2. EmailCodeSend: Generate and send email code (ChallengeStore)
  3. EmailCodeVerify: Verify email code, issue session (SessionStore)
  4. AuthorizeCode: Issue authorization code (AuthCodeStore)
  5. Token: Issue access token and ID token
  • P95 Latency < 5,000ms
  • Success Rate > 95%

Test Period: 2025-12-16T16:01:30Z - 16:06:30Z UTC

MetricValue
Worker Total Requests30,478
Worker P50 Duration22.6ms
Worker P99 Duration46.7ms
DO Total Requests45,688
DO Errors0
DO Wall Time P5046ms
DO Wall Time P992,846ms
D1 Read Queries1,143,239
D1 Write Queries28,478

⚠️ Note: High DO P99 due to cold starts. At 50 LPS with 32 shards, each shard receives only 1.56 req/s.

Test Period: 2025-12-16T16:09:00Z - 16:14:00Z UTC

MetricValue
Worker Total Requests59,761
Worker P99 Duration67.4ms
DO Total Requests89,531
DO Errors0
DO Wall Time P991,393ms
D1 Read Queries1,169,929
D1 Write Queries41,785

Good: Zero DO errors (vs 443 on Dec 13)

Test Period: 2025-12-16T16:15:50Z - 16:21:00Z UTC

MetricValue
Worker Total Requests74,176
Worker P99 Duration88.4ms
DO Total Requests111,184
DO Errors0
DO Wall Time P991,153ms
D1 Read Queries1,209,902
D1 Write Queries61,789

Good: DO Wall Time P99 continues to improve

Test Period: 2025-12-16T16:23:00Z - 16:28:00Z UTC

MetricValue
Total Requests89,000
HTTP Failures0
Peak RPS598 req/s
P95 Response Time283ms
Worker P99 Duration69.2ms
DO Total Requests133,400
DO Errors0
DO Wall Time P99955ms
D1 Read Queries1,248,445
D1 Write Queries81,019

Excellent: Best results across all metrics. DO P99 under 1 second.

StepCountAvgP50P95P99Max
AuthorizeInit21,937106ms103ms129ms173ms1,102ms
EmailCodeGenerate21,937217ms210ms279ms331ms1,202ms
EmailCodeVerify21,937260ms252ms336ms400ms2,627ms
AuthorizeCode21,93768ms63ms88ms104ms8,351ms
Full Flow21,937652ms639ms756ms853ms8,871ms
LPSLoad per ShardDO P99Status
501.56 req/s2,846ms⚠️ Cold starts frequent
1003.13 req/s1,393ms✅ Stable
1253.91 req/s1,153ms✅ Stable
1504.69 req/s955ms✅ Optimal

Finding: Each shard needs 3+ req/s to remain warm and perform optimally.

MetricDec 13 (16 shards)Dec 17 (32 shards)
K6 P953,015ms283ms
Worker P99365ms69ms
DO P991,648ms955ms
DO Errors20
Success Rate99.97%100%
Load LevelLPSMonthly LoginsExpected Service Scale
Low~50~130MSmall/Medium (use 16 shards)
Normal~100~260MMedium services
Recommended Max~150~390MLarge services
Limit200+520M+Not tested

1 Login = 5 HTTP requests:

  • 150 LPS × 5 = 750 RPS (HTTP request equivalent)
  • 390M monthly logins = ~19.5M monthly active users (weekly login)
  • 390M monthly logins = ~13M monthly active users (3 logins/month)
  • DO Errors: 443 → 0 (100% fix)
  • P95: 3,015ms → 283ms (91% reduction)
  • Spikes: Present (30s+) → None

Counterintuitively, DO P99 improves as load increases:

  • 50 LPS: 2,846ms (cold starts)
  • 150 LPS: 955ms (warm shards)

Worker P99 stays under 100ms even at 150 LPS.

At 260ms average (40% of total flow time), this step involves:

  • Email Code verification
  • Session creation
  • Multiple DO operations
xychart-beta
    title "DO Wall Time P99 (ms) - Improves with Higher Load"
    x-axis ["50 LPS", "100 LPS", "125 LPS", "150 LPS"]
    y-axis "Latency (ms)" 0 --> 3000
    bar [2846, 1393, 1153, 955]
LPSDO P99StatusNote
502,846ms⚠️Cold start frequent
1001,393msStable
1251,153msStable
150955msOptimal

Counter-intuitive finding: DO Wall Time improves as load increases due to reduced cold starts.

Layer50 LPS100 LPS125 LPS150 LPS
Worker P9947ms67ms88ms69ms
DO P992,846ms ⚠️1,393ms1,153ms955ms ✅
K6 P95688ms696ms761ms756ms
VerdictCold startGoodGoodOptimal
flowchart TB
    subgraph Test["Test Environment"]
        k6["k6 Cloud (Portland)"]
    end

    subgraph CF["Cloudflare Edge"]
        subgraph Workers["Workers"]
            OA["ar-auth Worker<br/>(66K req)"]
            OT["ar-token Worker"]
            OM["ar-management Worker<br/>(22K req)"]
        end

        subgraph DO["Durable Objects (shared)"]
            SS["SessionStore<br/>(32 shards)"]
            ACS["AuthCodeStore<br/>(32 shards)"]
            CS["ChallengeStore<br/>(32 shards)"]
        end

        subgraph DB["Database"]
            D1["D1 Database (conformance)"]
        end
    end

    k6 -->|HTTPS| OA
    k6 -->|HTTPS| OT
    k6 -->|HTTPS| OM
    OA --> SS
    OA --> ACS
    OA --> CS
    OT --> SS
    OM --> SS
    SS --> D1
    ACS --> D1
    CS --> D1

At 50 LPS, each shard receives only 1.56 req/s, causing cold starts.

Mitigation:

  • Use 16 shards for low load environments
  • Extend warmup period

P99 ranges from 955ms to 2,846ms depending on load.

Mitigation:

  • Choose shard count based on expected load
  • Dynamic shard adjustment (future)
TestURL
50 LPShttps://authrim.grafana.net/a/k6-app/runs/6338621
100 LPShttps://authrim.grafana.net/a/k6-app/runs/6338674
125 LPShttps://authrim.grafana.net/a/k6-app/runs/6338743
150 LPShttps://authrim.grafana.net/a/k6-app/runs/6338820

With 32-shard optimization, the Full Login Flow achieves:

  • 150 LPS (390M monthly logins) with stable performance
  • 100% success rate at all tested levels
  • DO errors eliminated (443 → 0)
  • P95 reduced by 91% (3,015ms → 283ms)

Key Improvements:

  • DO Errors: 443 → 0 (100% fix)
  • P95 Latency: 3,015ms → 283ms (91% reduction)
  • DO Wall Time P99: 1,648ms → 955ms (42% reduction)

Cold start at low load (50 LPS) is a known characteristic and can be mitigated by adjusting shard count based on expected traffic.