One URL shortener, pushed until it breaks.
One backend, 22 measured stages. Then six AI systems, from scratch.
The 7 projects
-
S
ScaleLab
Now on S3, docker.
A URL shortener platform, pushed further at each stage and load-tested after every one.
In progress3 of 22 stages done -
A1
Research Agent
Several AI agents research a question and write a sourced report.
Not started0 of 5 stages done -
A2
Advanced RAG Engine
Now on A2.1, ingestion.
Ask questions over your documents and get answers with citations.
In progress0 of 5 stages done -
A3
LLMOps Lab
Traces, tests and monitors the Research Agent and the RAG Engine.
Not started0 of 4 stages done -
A4
Model Lab
Fine-tune, compress and serve an open-weight model.
Not started0 of 5 stages done -
A5
AI Governance Gateway
A security layer in front of the LLM and its tools, with an attack test suite.
Not started0 of 4 stages done -
A6
Multimodal Studio
Image, voice, audio and video analysis.
Not started0 of 4 stages done
22 stages, 3 done
Each stage adds one layer to the same URL shortener: workers, a load balancer, a cache, queues, Kubernetes.
-
S0
Foundation
DonePython package, Postgres 17 schema for links and clicks, a migration runner, 35 tests.
Git tag: s0-foundation -
S1
Links API
DoneFastAPI CRUD and redirect, one error format, timeouts, health checks, graceful shutdown, 82 tests.
Git tag: s1-links-api -
S2
Load testing
Donek6 suite of six tests, Locust users, a resource monitor. First run on a busy machine: median 14.6 ms at 200 req/s, no failures up to 600 req/s, breaks between 700 and 750.
Git tag: s2-load-testing -
S3
Docker
In progressMulti-stage image, compose stack and container hardening are being built.
- ScalingS4Planned
- DatabaseS5Planned
- CachingS6Planned
- Rate limiter serviceS7Planned
- Auth and API securityS8Planned
- Notification serviceS9Planned
- Chat serviceS10Planned
- File serviceS11Planned
- Search serviceS12Planned
- Analytics pipelineS13Planned
- Architecture splitS14Planned
- Distributed patternsS15Planned
- Kubernetes (k3s)S16Planned
- CI/CDS17Planned
- AWS and TerraformS18Planned
- ObservabilityS19Planned
- ReliabilityS20Planned
- NetworkingS21Planned
First numbers, not final ones
Provisional. Measured once while other work used about half of the machine's CPU. The suite will be re-run on a quiet machine.
691 req/s
Achieved at the 700 req/s step of the breakpoint test, the last step before 1% or more of requests failed. p95 there was 388 ms. At 750 req/s, 10.99% of requests failed.
k6 against the S1 API on one machine: Gunicorn with 4 Uvicorn workers and Postgres 17, with the load generator on the same host.
Requests per second: achieved against target
p95 latency at each step, in milliseconds
- Measured
- Target rate
- Step where 1% or more of requests failed
Show the 24 steps as a table
| Target req/s | Achieved req/s | p50 | p95 | Failed | Dropped |
|---|---|---|---|---|---|
| 50 | 50 | 13.6 ms | 41.3 ms | 0.00% | 0 |
| 100 | 100 | 14.2 ms | 39.2 ms | 0.00% | 0 |
| 150 | 149 | 16.0 ms | 691 ms | 0.00% | 22 |
| 200 | 200 | 17.9 ms | 67.7 ms | 0.00% | 0 |
| 250 | 250 | 17.3 ms | 74.7 ms | 0.00% | 0 |
| 300 | 285 | 34.8 ms | 941 ms | 0.00% | 294 |
| 350 | 348 | 26.7 ms | 383 ms | 0.00% | 40 |
| 400 | 400 | 20.7 ms | 66.8 ms | 0.00% | 0 |
| 450 | 413 | 42.8 ms | 988 ms | 0.00% | 742 |
| 500 | 500 | 45.9 ms | 232 ms | 0.00% | 0 |
| 550 | 549 | 43.8 ms | 208 ms | 0.00% | 0 |
| 600 | 546 | 132 ms | 786 ms | 0.00% | 1,082 |
| 650 | 601 | 272 ms | 694 ms | 0.00% | 975 |
| 700 | 691 | 137 ms | 388 ms | 0.00% | 160 |
| 750 | 408 | 325 ms | 5,097 ms | 10.99% | 6,840 |
| 800 | 367 | 1,350 ms | 3,057 ms | 3.27% | 8,621 |
| 850 | 720 | 572 ms | 1,137 ms | 0.00% | 2,576 |
| 900 | 747 | 363 ms | 1,095 ms | 0.00% | 3,031 |
| 950 | 686 | 796 ms | 1,609 ms | 0.00% | 5,259 |
| 1,000 | 758 | 741 ms | 1,379 ms | 0.00% | 4,818 |
| 1,050 | 620 | 743 ms | 2,641 ms | 0.13% | 8,548 |
| 1,100 | 742 | 817 ms | 1,708 ms | 0.00% | 7,146 |
| 1,150 | 818 | 1,847 ms | 4,375 ms | 3.13% | 6,617 |
| 1,200 | 674 | 2,913 ms | 5,001 ms | 7.78% | 10,474 |
| Test | Traffic | Length | Requests | Average req/s | p50 | p95 | Failed |
|---|---|---|---|---|---|---|---|
| Baseline | Light, steady traffic | 1.0 min | 2,999 | 50 | 11.7 ms | 41.5 ms | 0.00% |
| Load | Expected normal traffic | 4.5 min | 44,919 | 166 | 14.4 ms | 113 ms | 0.00% |
| Stress | Steps up to three times normal | 5.0 min | 118,367 | 394 | 37.6 ms | 514 ms | 0.00% |
| Spike | A sudden burst to three times normal | 3.2 min | 26,975 | 142 | 33.1 ms | 637 ms | 0.00% |
| Soak | Moderate traffic for a long time | 20.0 min | 179,609 | 150 | 12.6 ms | 101 ms | 0.00% |
| Breakpoint | Climbs in small steps until it breaks | 8.1 min | 232,444 | 481 | 408 ms | 2,944 ms | 1.17% |
How a stage closes
- A git tag
- Each finished stage is committed and tagged, so any step can be checked out and compared.
- The same load suite
- After S2, every stage re-runs the same k6 profiles and is compared with the stage before.
- Written notes
- What was tried, why, and what happened, kept in the repo next to the code.