Date: October 11, 2025
Status: ✅ FULLY OPERATIONAL
- Old: 4M rows (4,194,304) = 129 MB
- New: 512K rows (524,288) = 16 MB
- File format: 8-byte header + (N+1) × 32-byte G1 points = 16,777,256 bytes
- Impact: Faster loading, lower memory footprint, more reliable deployments
- SRS files now embedded directly in Docker image (at
/tmp/srs_image/) - No more manual SRS initialization required
- Resilient to Railway volume issues (old files automatically replaced)
The entrypoint.sh now:
- ✅ Checks SRS files on Railway volume
- ✅ Detects wrong-sized files (old 2M/4M SRS)
- ✅ Automatically replaces with correct 512K SRS from Docker image
- ✅ Ensures correct permissions for
tinyzkpuser
Example from deployment logs:
❌ SRS files on volume are wrong size (found: 134217768 bytes, expected: ~16MB)
📦 Replacing with 512K SRS from Docker image...
✓ 512K SRS files copied to volume
- ✅ First proof request triggers background loading (returns 503 immediately)
- ✅ No HTTP timeouts during SRS initialization
- ✅ Loading completes in ~60 seconds (Railway CPU)
- ✅ Subsequent requests succeed immediately
- ✅
/v1/healthendpoint shows loading status
Loading Timeline:
| Time | Status | Action |
|---|---|---|
| 0s | SRS not loaded | First /v1/prove request received |
| 0s | srs_loading: true |
Returns 503, spawns background task |
| ~60s | srs_initialized: true |
Loading complete, ready for proofs |
| 60s+ | Ready | All requests succeed instantly |
{
"status": "ok",
"srs_initialized": true
}- ✅ Status: Success
- ✅ Proof size: 1,012 bytes
- ✅ SRS G1 digest:
0x3a3ed5d2703dd09cd7ce95e9c138d7bc4c55a1f9cf9d78c3c692cf4f3a61a505 - ✅ SRS G2 digest:
0x2cf0223d4b1cd1375c425e528420de13dad19143fe901d8190dbc1332591c669
{
"status": "ok"
}| Tier | Price | Monthly Proofs | Max Circuit Size | Memory | SRS Degree |
|---|---|---|---|---|---|
| Free | $0 | 250 | 32K rows | ~5 KB | 512K |
| Pro | $39/mo | 1,000 | 256K rows | ~10 KB | 512K |
| Scale | $99/mo | 2,500 | 512K rows | ~12 KB | 512K |
# SRS Configuration
TINYZKP_MAX_ROWS=524288 # 512K rows
TINYZKP_FREE_MAX_ROWS=32768 # 32K rows (Free tier)
TINYZKP_PRO_MAX_ROWS=262144 # 256K rows (Pro tier)
TINYZKP_SCALE_MAX_ROWS=524288 # 512K rows (Scale tier)
# Monthly Caps
TINYZKP_FREE_MONTHLY_CAP=250 # Free tier
TINYZKP_PRO_MONTHLY_CAP=1000 # Pro tier
TINYZKP_SCALE_MONTHLY_CAP=2500 # Scale tier-
Dockerfile- Copies
srs/to/tmp/srs_image/(prevents Railway volume shadowing)
- Copies
-
entrypoint.sh- Added SRS size validation
- Auto-replaces wrong-sized SRS files
- Robust error handling and logging
-
src/bin/tinyzkp_api.rs- Background SRS loading with
tokio::spawn - Immediate 503 response (no HTTP timeout)
SRS_LOADINGandSRS_INITIALIZEDflags- Updated
/v1/healthto show loading status
- Background SRS loading with
-
.gitignore- Removed
srs/G1.binandsrs/G2.bin(now tracked in Git)
- Removed
-
README.md- Updated to reflect 512K row capacity
- Updated pricing tiers and zkML capabilities
Offset | Size | Content
-------|------|--------
0x00 | 8 | Point count (524,289 = 0x00080001 little-endian)
0x08 | 32 | G1 point #0 (identity or base)
0x28 | 32 | G1 point #1
... | ... | ...
EOF | - | Total: 16,777,256 bytes (16 MB)
-
Docker Build:
- Image built with 512K SRS at
/tmp/srs_image/ - ~500 MB total image size
- Image built with 512K SRS at
-
Container Start (
entrypoint.sh):=== TinyZKP Entrypoint (running as root) === ❌ SRS files on volume are wrong size (found: 134217768 bytes, expected: ~16MB) 📦 Replacing with 512K SRS from Docker image... ✓ 512K SRS files copied to volume Files in /app/srs: -rw-r--r-- 1 tinyzkp tinyzkp 17M Oct 11 03:40 G1.bin -rw-r--r-- 1 tinyzkp tinyzkp 136 Oct 11 03:40 G2.bin
-
API Startup:
tinyzkp API listening on http://0.0.0.0:8080 SRS Initialization: Background loading enabled - Max degree: 524288 (512K rows, 16MB) - First request returns 503, loading in background (~60s) -
First Proof Request:
- Client sends
/v1/prove - API returns
503 Service Unavailableimmediately - Background task loads SRS (~60 seconds)
- Client retries after 60 seconds → Success!
- Client sends
Problem: Railway persistent volume at /app/srs was shadowing Docker image files
Solution: Copy SRS to /tmp/srs_image/ in Dockerfile, then entrypoint copies to volume
Problem: Old 2M/4M SRS files persisted on Railway volume
Solution: Entrypoint detects size mismatch and auto-replaces with 512K SRS
Problem: Loading 16MB SRS took ~60s, causing HTTP request timeout
Solution: Background loading with immediate 503 response
Problem: Initial estimate was "~30 seconds" but actual time was ~60 seconds
Root cause: Railway CPU slower for crypto operations than local testing
Status: Expected behavior, docs should reflect 60s estimate
- Update website to reflect 60-second SRS loading time (not 30s)
- Add note: "First proof after deployment may take 60s to initialize"
Current Railway variables can stay as-is, but ensure:
TINYZKP_SCALE_MONTHLY_CAP=2500 ← Should be 2500 (not 1000)- Watch for any SRS loading failures in Railway logs
- Confirm all users experience smooth operation after initial 60s warmup
- Parallel G1/G2 loading (currently sequential)
- Pre-deserialization (load + deserialize in parallel)
- SRS caching (Redis/memcached for multi-instance deployments)
# 1. Check health
curl https://api.tinyzkp.com/v1/health
# 2. Generate proof (triggers SRS loading)
curl -X POST https://api.tinyzkp.com/v1/prove \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"air": {"k": 3},
"domain": {"rows": 8, "b_blk": 2, "zh_c": "1"},
"pcs": {"basis_wires": "eval"},
"witness": {
"format": "json_rows",
"rows": [
[1,2,3], [2,4,6], [3,6,9], [4,8,12],
[5,10,15], [6,12,18], [7,14,21], [8,16,24]
]
},
"return_proof": true
}'
# If you get 503, wait 60 seconds and retry
# 3. Verify proof
# (save proof_b64 from step 2, decode, then:)
curl -X POST https://api.tinyzkp.com/v1/verify \
-H "X-API-Key: YOUR_API_KEY" \
-F "proof=@proof.bin"railway logs -fLook for:
- ✅
✓ 512K SRS files copied to volume - ✅
SRS Initialization: Background loading enabled - ✅
⏳ Starting background SRS loading (16MB, ~30 seconds)... - ✅ (No error messages after "Files exist, loading...")
The TinyZKP API is now successfully deployed with 512K SRS (16 MB), supporting:
✅ Free tier: 32K row circuits (MNIST inference)
✅ Pro tier: 256K row circuits (MNIST full, small CNNs)
✅ Scale tier: 512K row circuits (image classification, small transformers)
The system automatically handles SRS initialization, replaces outdated files, and gracefully manages background loading with no HTTP timeouts.
Status: Production-ready! 🚀
Generated: October 11, 2025