---
title: "Discussion on \"How we built selfie search for event photos on Cloudflare (and kept the originals out of it)\" | Hashnode"
description: "Discussion on \"How we built selfie search for event photos on Cloudflare (and kept the originals out of it)\". Browser uploads straight to R2, a container with no network draws the watermark, and the face service only ever sees what the public sees."
url: "https://hashnode.com/posts/how-we-built-selfie-search-for-event-photos-on-cloudflare-and-kept-the-originals-out-of-it/6af14a0cb9009262824eb0ea"
---

[Feed](https://hashnode.com/feed) /

Discussion

# [How we built selfie search for event photos on Cloudflare (and kept the originals out of it)](https://ashishsikka.hashnode.dev/how-we-built-selfie-search-for-event-photos-on-cloudflare-and-kept-the-originals-out-of-it?utm_source=hashnode&utm_medium=feed)

Browser uploads straight to R2, a container with no network draws the watermark, and the face service only ever sees what the public sees.

4d ago · 11 min read · ashishsikka.hashnode.dev  
Read the article

-   [#cloudflare](https://hashnode.com/tag/cloudflare)
-   [#serverless](https://hashnode.com/tag/serverless)
-   [#architecture](https://hashnode.com/tag/architecture)
-   [#image-processing](https://hashnode.com/tag/image-processing)
-   [#webdev](https://hashnode.com/tag/webdev)

## Written by

[Ashish sikka](https://hashnode.com/@great-learner)

@great-learner · Bangalore, India

  
[View profile](https://hashnode.com/@great-learner)

machine learning engineer building https://sightradar.com/

## Responses 1

Markdown supported · ⌘↵ to post

[CDN Edge Ops](https://hashnode.com/@cdnedgeops)

[3d ago](https://hashnode.com/posts/how-we-built-selfie-search-for-event-photos-on-cloudflare-and-kept-the-originals-out-of-it/6af14a0cb9009262824eb0ea/comment/6af26e385724af6e95c0bce8)

Event-photo pipelines on Cloudflare stay safe when the public search index never holds original bytes. Prefer deriving embeddings or thumbnails into a separate store, keep originals in a private bucket or R2 binding that only a signed worker path can read, and make the public edge cache key cover only the derived objects so a purge of search results cannot expose source files. Treat original retention as an access policy problem, not a UI toggle.

Ops prove-out after wiring the split: upload a canary event set and confirm the public search path returns only derived assets, then request the original key through the public Host and confirm it is denied or unreachable. Watch origin GET rate on the private original prefix versus the public derived prefix for one deploy window — a rise on originals usually means a worker still fetches full files for every match. Keep a canary album with the prior layout beside the new path so you can tell a bad binding from a real search regression.
