What this is
face-engine is a small, stateless HTTP service for face recognition: given a photo, it detects the most prominent face, aligns it, and produces a 512-dimensional embedding. Given two photos, it tells you how similar the faces are and whether they’re likely the same person. It’s built to run as a horizontally-scaled backend service behind an API gateway or another application (e.g. an identity-verification flow) — it has no notion of users, sessions, or storage. Every request is independent.Quickstart
Build and run the service locally or with Docker
API Reference
/v1/embed and /v1/compare request/response contractsArchitecture
How the pieces fit together, module by module
Models
Which models are used, why, and what was verified about them
Stack
Design principles
- Stateless. No database, no session state. Scale by running more replicas behind a load balancer.
- Fail loudly on startup, fail gracefully per-request. If the models
can’t load, the process exits non-zero immediately (see
main.cpp) rather than serving broken responses. A single malformed upload returns a422with a specific error code; it never crashes the process. - I/O threads never do CPU work. Drogon’s event-loop threads only handle connection I/O. Every decode/align/inference call runs on a separate worker thread pool, so a burst of slow requests can’t starve the HTTP layer. See Architecture → Concurrency model.
- Verify, don’t assume. Every model-related assumption in this codebase (input tensor layout, alignment template, similarity threshold) was independently verified against the actual model weights and a manual same/different-person test set before being trusted — see Models for what was checked and how.
What’s intentionally not here
- No database or persistent storage of any kind — the service processes an image and forgets it.
- No auth — this is expected to sit behind a gateway or internal network boundary that handles authentication/authorization.
- No batching — each request runs its own detect+embed pass. Fine for CPU inference at moderate request rates; revisit if GPU throughput becomes the bottleneck (see Deployment).