SD System Design In Depth
0%
lesson system-designimagesidentity

An avatar service

Module 5.2: Media Processing & CDN Distribution Updated Sep 18, 2026
📄 Cheat Sheet
How Apps Store Images | System Design | AWS S3, CDN
Irtiza Hafiz How Apps Store Images | System Design | AWS S3, CDN Watch on YouTube ↗

No dedicated avatar-service video exists; this clearly covers the exact serving path for profile images (object storage, metadata, CDN) that an avatar service is built on.

0:00 / --:--

Deterministic Avatar Lookup Architecture

A global avatar service (like Gravatar or GitHub identicons) maps account identifiers to profile images. It may need to serve very high request volume at low latency, but its lookup key must not quietly become a directory of users.

Hashing & Caching Strategy

  • Deterministic Key Derivation: A public protocol such as Gravatar may normalize an email address and hash it for a stable lookup key. This hides the literal address but does not anonymize it: common addresses can be guessed and hashed, and the stable digest remains pseudonymous data. For a private service that does not need public interoperability, prefer an opaque user ID or a keyed derivation whose secret is not exposed to clients.
  • Cache Headers: Avatars change infrequently. Response headers specify aggressive HTTP caching: Cache-Control: public, max-age=86400, s-maxage=604800, stale-while-revalidate=86400.
  • Fallback Identicon Generation: If an email has no uploaded photo, the service procedurally generates an identicon (SVG or geometric pixel matrix) based on the bits of the hash with zero database round-trips.

Worked example: traffic and caching

One billion avatar requests per day is about 11,600 per second on average and perhaps 35,000 per second at peak. With a 99 percent CDN hit ratio, origin sees about 350 requests per second at peak. Serving sizes 32, 64, 128 and 256 pixels in WebP at 2 to 15 KB each, total egress is a few TB per day, almost all from the CDN.

URL and caching strategies

StrategyExampleStaleness after changeNotes
Mutable URL, short max-age/avatar/42?s=64 with max-age=300Up to 5 minutesMore origin traffic and revalidation
Mutable URL, long max-agemax-age=86400, s-maxage=604800Up to a week at the CDN unless purgedNeeds purge on every change
Versioned URL/avatar/42/v7/64.webp with max-age=31536000, immutableNone: the page references the new versionRecommended; needs version in user metadata
Public hash key (Gravatar style)/avatar/HASH?s=64Depends on max-ageNeeded for cross-site interoperability; leaks a stable pseudonymous ID

Lookup key privacy

  • Gravatar historically used the MD5 of the trimmed, lowercased email; it now also accepts SHA-256. Both are fast hashes, so a list of a million candidate emails can be tested in well under a second on commodity hardware.
  • For a private service, key avatars by an opaque user ID or by HMAC(secret, user_id), and never expose the email-derived value to clients.

Fallback generation

  • Identicons: take bits of a hash of the key and fill a symmetric 5 by 5 grid in a colour derived from other bits, similar to GitHub's default avatars. Generation is pure CPU, needs no database read, and the result can be cached like any other variant.
  • Initials avatars: render the user's initials on a coloured circle; cache by (initials, colour, size), not per user.
flowchart LR P["Page renders avatar URL with version"] --> C["CDN"] C -- "miss" --> A["Avatar service"] A --> M["Metadata: has upload, version"] M -- "yes" --> S["Resized variant in object storage"] M -- "no" --> G["Generate identicon"] S --> C G --> C
Check yourself Question 1 of 3
Hashed emails are not anonymous recall
From: Hashing & Caching Strategy

A private company app plans to key avatar URLs by SHA-256 of the user's lowercased email, arguing that hashing makes them anonymous. What does the lesson say?

Key Takeaways

A public email hash avoids exposing the literal address but remains guessable pseudonymous data; prefer opaque IDs or keyed derivation for a private service.
Use aggressive Cache-Control with stale-while-revalidate for CDN efficiency.
Generate procedural identicons mathematically from hash bits when no user avatar exists.
Was this lesson helpful? Spot an issue or have a suggestion? Let us know on GitHub.
Report an issue