Accepted
2026-04-01
DTAT-OCR currently runs a single uvicorn worker with synchronous Textract calls and SQLite storage. This limits throughput to ~20-30 docs/minute with only 1 concurrent request. For client demos and production pilot workloads, we need 100+ docs/minute without moving to full AWS infrastructure (ECS, SQS, RDS).
The EC2 instance (t3.medium, 2 vCPU, 8GB RAM) has headroom — Textract processing is network-bound (not CPU-bound), so additional workers can run concurrently without saturating the CPU.
Implement application-level optimizations in this order:
- Multi-worker uvicorn — Run 4 workers to handle concurrent requests
- PostgreSQL storage — Replace SQLite (single-writer lock) with PostgreSQL (already installed on EC2)
- boto3 session reuse — Share Textract client across requests instead of creating per-request
- Async OCR endpoint — Make
/ocrtruly async withaioboto3 - Fire-and-forget endpoint — Add
/ocr/asyncthat returns job ID immediately, client polls for result - In-process queue —
asyncio.Queuewith background workers to absorb burst traffic
These changes stay within the single EC2 instance. Full AWS infrastructure (ECS auto-scaling, SQS, managed RDS) is a separate future effort.
- 10x throughput improvement measured: 250 docs/min direct, 41 docs/min via Boomi (from ~25)
- 50 concurrent requests with 0 failures (from 1)
- PostgreSQL enables concurrent writes — zero contention under load
- Async job system with PostgreSQL-backed state (works across all 4 workers)
- Queue monitoring with avg/p95 processing time metrics
- No new AWS services or cost increase
- Backward compatible — all existing endpoints continue to work
- Estimated ~20,000 docs/day through Boomi, ~120,000 docs/day direct
- PostgreSQL adds a service to manage on the EC2 (already installed, minor overhead)
- Multiple workers consume more RAM (~240MB total vs ~60MB single)
aioboto3andpsycopg2-binaryadd dependencies
- Docker images updated for multi-worker config
- systemd service updated with
--workers 4 .envupdated with PostgreSQL connection string- Boomi WSS throughput limited by synchronous request handling (~41 docs/min)