Section 4: The 2.8 KB Question - API Design
Executive Summary: Section 3 showed that the load lives in update checks (420,000/s peak) and update bytes (77% of egress), not in browsing, so the contracts are designed in that order. Three families serve three customers. The device family answers "anything new for me?" with a POST that carries the installed list and returns server-chosen delta-or-full files at immutable, content-addressed URLs, plus a server-dictated time for the next check. The storefront and commerce family keeps reads cacheable and makes the one money-moving call idempotent. The developer family is transactional: an edit stages binary, listing and rollout, then commits them as one submission. Four pushbacks test the shapes, and each one ends in a decision with a rejected alternative and a flip trigger.
The interviewer slides the marker across. "Show me the API." The tempting answer is a resource list: apps, users, reviews, purchases. That list is the Catalog Clerk's API, where every resource looks equally important. Section 3's arithmetic says they are not, so the candidate starts from the traffic instead.
| Family | Key endpoints | Peak rate (ledger) | What the shape optimises for |
|---|---|---|---|
| Device | updates:check, installs, device-profiles |
420k checks/s, 150k downloads/s | Statelessness, tiny requests, immutable byte URLs |
| Storefront | apps/{package}, search, storefront/home |
174k views/s, 35k searches/s | Edge cacheability |
| Commerce | purchases, entitlements, reviews |
1,740 purchases/s, 350 reviews/s | Correctness: idempotency, server-side truth |
| Developer | edits, tracks, :halt |
1.7 submissions/s | Atomicity and an instant brake |
The Device Contract: One Profile, One Question
Before a phone asks about updates, it describes itself once:
POST /v1/device-profiles
{ "abis": ["arm64-v8a"], "densityDpi": 420, "sdkInt": 34,
"locales": ["hi-IN", "en-IN"], "features": ["android.hardware.location.gps", "..."] }
200 OK
{ "deviceProfileId": "dp_7c41e9" }
The deviceProfileId is a hash of the configuration, not an identity. Every Pixel 7 on Android 14 with the same locales gets the same ID, so profiles are shared by millions of devices, cacheable everywhere, and safe to log. The device's own pseudonymous identity travels separately in its auth token, because the rollout cohort hash(deviceId, releaseId) mod 10,000 needs it and nothing else does.
Here is Priya's check, four times a day, on a check where her cohort is inside the Trailhead Maps 4.3.0 rollout:
POST /v1/updates:check
Authorization: Bearer <device token>
{ "deviceProfileId": "dp_7c41e9",
"installed": [
{ "package": "com.trailhead.maps", "versionCode": 4210, "certDigest": "sha256:9f2c..." },
... 39 more entries, about 2.8 KB in all
] }
200 OK
{ "updates": [
{ "package": "com.trailhead.maps", "targetVersionCode": 4300,
"delivery": { "type": "delta", "fromVersionCode": 4210,
"files": [
{ "url": "https://cdn-a.example.net/f/3b8e...", "sha256": "3b8e...", "size": 7200000 },
{ "url": "https://cdn-a.example.net/f/c91d...", "sha256": "c91d...", "size": 1800000 },
... 3 more patches (xxhdpi, hi, en), a few KB each ] } } ],
"nextCheckAfterSec": 22417,
"manifestSignature": "MEUCIQDx..." }
Three fields carry the design. certDigest lets the server refuse to offer an update to a copy whose certificate isn't in the app's signing lineage (a sideloaded, re-signed APK, say). files lists one patch per changed split; the language and density patches are tiny, so the 9 MB is almost all base and ABI, against 38 MB for a full download. And nextCheckAfterSec is roughly six hours plus server-added jitter: the server, not the device's clock, decides when the next question comes, which makes it a load-shedding lever Section 8 will pull. (manifestSignature signs the response with a store manifest key; Section 11 details it.)
POST /v1/installs (package, deviceProfileId) returns the same delivery shape for a first install. It is also where entitlement is checked: a paid app's manifest carries short-lived signed URL tokens, so the CDN never has to know who owns what. The update check never reads entitlements: for paid packages it marks the plan as needing tokens, which the device exchanges here.
Quick check before moving on:
Sign in to continue reading
The rest of this lesson is available with a free account. Signing in with Google or Microsoft is free.
Sign in to read the full lesson