{
  "$comment": "MEASURED, not estimated and not authored. Four private repositories, cloned and run on one machine on the date below. Every number here came out of a script; none was typed by hand. The method is published beside the results because a bare figure in a comparison table is unfalsifiable, and this page's entire argument is that its numbers are not.",
  "measuredOn": "2026-07-27",
  "endpoint": "/api/auth/me",
  "environment": {
    "host": "Windows 11, Docker Desktop, containerd image store, Linux containers",
    "database": "one MySQL 8.4.10 container shared by all four, the same digest-pinned image every repository's compose file specifies, one schema per implementation",
    "network": "all four on one user-defined bridge network",
    "loadGenerator": "python:3.13-alpine running inside that same network, so Docker Desktop's host port-forwarding is not in the measured path"
  },
  "heldConstant": [
    "the same product: one access-control console, built four times",
    "the same database engine, image digest and schema",
    "the same endpoint, request shape, warm-up, request count and concurrency",
    "the production target of each repository's own Dockerfile, unmodified",
    "one server process per implementation, as each Dockerfile's prod stage ships it"
  ],
  "varied": [
    "the backend language and its runtime, and nothing else"
  ],
  "method": {
    "linesOfCode": "Hand-written source in the implementation's own language under its backend source roots. Counted: application code the server runs. Excluded: tests, database migration revisions and DDL, generated files (OpenAPI documents, build output), dependency manifests, lockfiles, vendored dependencies, and the React front end, which is identical in all four and held constant. Migration RUNNERS are counted, because how much of one each language forced its author to write is a real difference; migration CONTENT is not, because it is the same schema restated four times and Sharpbill's is written in Python, which would put Python lines in the C# row. The headline figure is code lines: physical lines minus blank lines minus comment-only lines. Blank and comment totals are published alongside it.",
    "imageSize": "docker build --target prod against each repository's own backend Dockerfile, unmodified. On-disk is the uncompressed size Docker reports; compressed is the content-store size a registry would transfer.",
    "coldStart": "The container is created once, which is not timed. Then ten times: start it, poll GET /api/health/live every 5 ms over the published port, stop it. Two figures come out of the same ten runs. medianApplicationOnly is measured from docker start returning — the application's own share, and the figure the pages print. median is measured from immediately before docker start is invoked, so it also carries the Docker CLI and daemon overhead, which is common to all four. /api/health/live is exempt from rate limiting in all four, so polling cannot distort it. The database was already running and already migrated.",
    "p95Latency": "GET /api/auth/me \u2014 the permission-check endpoint, present under that exact path in all four. It verifies the session JWT, reads the user and the session row under SELECT ... FOR UPDATE, writes the presence touch, and assembles the caller's effective permission set. Verified by reading all four: they do equivalent work, and the user_sessions table on that path carries identical indexes in all four schemas. 100 warm-up requests, then 500 measured requests at concurrency 4, closed loop, keep-alive per worker. Every implementation caps /api at 600 requests per minute per IP, so the measured phase is sized under that and begins after the window rolls over. All 500 returned HTTP 200 with the permission set resolved in every run; a concurrency-1 pass is published beside it because those FOR UPDATE locks are taken on the same row, so concurrency-4 alone cannot separate per-request cost from lock contention."
  },
  "caveats": [
    "One machine, one run each, not a multi-host average. Absolute numbers would move on other hardware; the ratios are the point.",
    "Kingfisher's schema head predates the other three: it is missing the secure-signup and query-index revisions they carry. Those indexes are on the user-directory queries, not on the measured endpoint, and the table it does use is index-identical in all four.",
    "The four builds are not perfectly identical products. Merlin's schema carries one permission key the other three do not (users.sensitive.read), so its response resolves 11 permissions where theirs resolve 10 \u2014 one extra row in a join and one extra string in the payload. It is recorded rather than corrected because correcting it would mean editing one of the four repositories to flatter the measurement.",
    "Latency was measured from inside the container network. A browser on the internet would add far more than the differences shown here.",
    "The four repositories are private, so these numbers cannot be reproduced by a reader from source. The method is published so the reasoning can be argued with even when the code cannot be read."
  ],
  "implementations": [
    {
      "name": "Kingfisher",
      "repository": "kingfisher-crm",
      "language": "Python 3.13",
      "languageFamily": "Python",
      "toolkit": "FastAPI, SQLAlchemy, Uvicorn",
      "baseImage": "Chainguard Wolfi + CPython 3.13",
      "process": "uvicorn, one worker (the prod Dockerfile's own CMD)",
      "linesOfCode": {
        "code": 7200,
        "nonBlank": 7857,
        "physical": 8950,
        "files": 69,
        "sourceRoots": [
          "backend/app"
        ]
      },
      "imageSize": {
        "onDisk": "664MB",
        "compressedMB": 182.6,
        "compressedBytes": 182615089
      },
      "coldStartMs": {
        "median": 852.3,
        "min": 829.3,
        "max": 936.4,
        "runs": 10,
        "medianApplicationOnly": 518.3,
        "allRuns": [
          829.3,
          829.3,
          830.2,
          847.3,
          851.1,
          853.4,
          860.7,
          866.1,
          872.4,
          936.4
        ]
      },
      "permissionCheckLatencyMs": {
        "concurrency4": {
          "p50": 38.175,
          "p95": 52.25,
          "p99": 63.267,
          "min": 21.558,
          "max": 93.461,
          "requests": 500,
          "throughputRps": 103.4,
          "statusCodes": {
            "200": 500
          }
        },
        "concurrency1": {
          "p50": 7.519,
          "p95": 9.894,
          "p99": 11.415,
          "requests": 500,
          "throughputRps": 127.2,
          "statusCodes": {
            "200": 500
          }
        },
        "permissionsResolved": 10
      }
    },
    {
      "name": "Sharpbill",
      "repository": "Sharpbill",
      "language": "C# / .NET 10",
      "languageFamily": "C#",
      "toolkit": "ASP.NET Core",
      "baseImage": "mcr.microsoft.com/dotnet/aspnet:10.0 noble-chiseled-extra",
      "process": "one Kestrel process",
      "linesOfCode": {
        "code": 20226,
        "nonBlank": 20297,
        "physical": 22475,
        "files": 182,
        "sourceRoots": [
          "backend/src"
        ]
      },
      "imageSize": {
        "onDisk": "263MB",
        "compressedMB": 78.7,
        "compressedBytes": 78700143
      },
      "coldStartMs": {
        "median": 606.7,
        "min": 568.5,
        "max": 750.6,
        "runs": 10,
        "medianApplicationOnly": 276.5,
        "allRuns": [
          568.5,
          590.9,
          592.6,
          600.1,
          600.1,
          613.4,
          615.8,
          645.4,
          646.1,
          750.6
        ]
      },
      "permissionCheckLatencyMs": {
        "concurrency4": {
          "p50": 3.682,
          "p95": 4.722,
          "p99": 17.901,
          "min": 2.539,
          "max": 22.223,
          "requests": 500,
          "throughputRps": 1018.7,
          "statusCodes": {
            "200": 500
          }
        },
        "concurrency1": {
          "p50": 2.829,
          "p95": 4.422,
          "p99": 7.199,
          "requests": 500,
          "throughputRps": 330.6,
          "statusCodes": {
            "200": 500
          }
        },
        "permissionsResolved": 10
      }
    },
    {
      "name": "Goldfinch",
      "repository": "Goldfinch",
      "language": "Go 1.26",
      "languageFamily": "Go",
      "toolkit": "Chi, database/sql",
      "baseImage": "gcr.io/distroless/static-debian12:nonroot",
      "process": "one static binary",
      "linesOfCode": {
        "code": 14942,
        "nonBlank": 15255,
        "physical": 16359,
        "files": 66,
        "sourceRoots": [
          "backend/cmd",
          "backend/internal",
          "backend/api",
          "backend/migrations"
        ]
      },
      "imageSize": {
        "onDisk": "62.4MB",
        "compressedMB": 13.0,
        "compressedBytes": 12999653
      },
      "coldStartMs": {
        "median": 402.0,
        "min": 379.0,
        "max": 441.9,
        "runs": 10,
        "medianApplicationOnly": 84.1,
        "allRuns": [
          379.0,
          382.8,
          390.7,
          396.5,
          399.8,
          404.2,
          416.8,
          429.4,
          433.4,
          441.9
        ]
      },
      "permissionCheckLatencyMs": {
        "concurrency4": {
          "p50": 2.05,
          "p95": 2.569,
          "p99": 3.645,
          "min": 1.729,
          "max": 14.891,
          "requests": 500,
          "throughputRps": 1806.7,
          "statusCodes": {
            "200": 500
          }
        },
        "concurrency1": {
          "p50": 1.941,
          "p95": 2.794,
          "p99": 4.651,
          "requests": 500,
          "throughputRps": 486.2,
          "statusCodes": {
            "200": 500
          }
        },
        "permissionsResolved": 10
      }
    },
    {
      "name": "Merlin",
      "repository": "Merlin",
      "language": "TypeScript",
      "languageFamily": "TypeScript",
      "toolkit": "NestJS, mysql2",
      "baseImage": "node:24-alpine",
      "process": "one Node process (the prod Dockerfile's own CMD)",
      "linesOfCode": {
        "code": 12775,
        "nonBlank": 12809,
        "physical": 13748,
        "files": 96,
        "sourceRoots": [
          "backend/src"
        ]
      },
      "imageSize": {
        "onDisk": "490MB",
        "compressedMB": 133.6,
        "compressedBytes": 133610576
      },
      "coldStartMs": {
        "median": 916.4,
        "min": 854.7,
        "max": 946.5,
        "runs": 10,
        "medianApplicationOnly": 581.5,
        "allRuns": [
          854.7,
          897.8,
          904.8,
          907.6,
          915.7,
          917.2,
          926.6,
          927.6,
          939.5,
          946.5
        ]
      },
      "permissionCheckLatencyMs": {
        "concurrency4": {
          "p50": 7.064,
          "p95": 9.693,
          "p99": 12.781,
          "min": 4.924,
          "max": 22.423,
          "requests": 500,
          "throughputRps": 544.5,
          "statusCodes": {
            "200": 500
          }
        },
        "concurrency1": {
          "p50": 1.963,
          "p95": 3.032,
          "p99": 3.757,
          "requests": 500,
          "throughputRps": 474.2,
          "statusCodes": {
            "200": 500
          }
        },
        "permissionsResolved": 11
      }
    }
  ]
}
