Skip to content

Storage

Strategy

Storage is opt-in via FACE_API_STORAGE_ENABLED=true. When enabled:

  1. Every uploaded image is stored in S3 under originals/{image_id}/{filename}
  2. Every processing result creates a ProcessingJob row in PostgreSQL
  3. Masked images (from /mask endpoint) are stored under processed/{image_id}/{job_id}.{format}
  4. Storage failures are logged but never fail API responses (non-blocking)

When disabled, the API operates statelessly with zero persistence overhead.

Database

Engine: PostgreSQL 18 via SQLAlchemy 2.0 async + asyncpg

Schema

images table

Column Type Description
id UUID (PK) Auto-generated
filename VARCHAR(255) Original upload filename
content_type VARCHAR(100) MIME type
size_bytes BIGINT File size
width INT Image width in pixels
height INT Image height in pixels
s3_key VARCHAR(500) S3 object key for original
created_at TIMESTAMPTZ Upload timestamp

processing_jobs table

Column Type Description
id UUID (PK) Auto-generated
image_id UUID (FK) References images.id ON DELETE CASCADE
job_type VARCHAR(20) detect or mask
status VARCHAR(50) completed (currently only value)
confidence_threshold FLOAT Detection threshold used
nms_threshold FLOAT NMS threshold used
blur_method VARCHAR(50) Null for detect jobs
blur_strength INT Null for detect jobs
padding FLOAT Null for detect jobs
output_format VARCHAR(20) jpeg/png/webp, null for detect
output_quality INT 1-100, null for detect
face_count INT Number of faces detected
detections JSONB Full detection results
processed_s3_key VARCHAR(500) S3 key for masked image
processed_size_bytes BIGINT Masked image file size
inference_ms FLOAT SCRFD inference time
total_ms FLOAT Total request processing time
created_at TIMESTAMPTZ Job creation timestamp

Relationships

  • ImageProcessingJob (1:N, cascade delete)
  • Deleting an image removes all associated jobs and S3 objects

S3 Object Layout

{bucket}/
├── originals/
│   └── {image_id}/
│       └── {original_filename}
└── processed/
    └── {image_id}/
        └── {job_id}.{format}

Key Format Examples

originals/a1b2c3d4-e5f6-7890-abcd-ef1234567890/photo.jpg
processed/a1b2c3d4-e5f6-7890-abcd-ef1234567890/f0e1d2c3-b4a5-6789-0abc-def123456789.jpeg

Configuration

Variable Default Description
FACE_API_STORAGE_ENABLED false Enable/disable all storage
FACE_API_DATABASE_URL postgresql+asyncpg://postgres:postgres@localhost:5432/faceapi PostgreSQL connection
FACE_API_S3_ENDPOINT http://localhost:9000 S3 endpoint (MinIO for dev)
FACE_API_S3_ACCESS_KEY minioadmin S3 access key
FACE_API_S3_SECRET_KEY minioadmin S3 secret key
FACE_API_S3_BUCKET face-api S3 bucket name
FACE_API_S3_REGION us-east-1 S3 region