Shipping & Running
$defineobject-storage--plain-english
TLDRA giant bucket on the internet for files.
The database is a cabinet of facts. It is a terrible attic.
A photo, a pitch-deck PDF, the zip a teammate "just uploaded" — those are objects. Object storage is the loading dock: S3, R2, UploadThing. You put the crate in. You get a URL back. The cabinet stores the URL and the title. The dock stores the bytes.
Do not jam the crate into the cabinet. A row should say "user 41 has a headshot" and point. It should not swallow the headshot. Do not drop user uploads into public/ on the server disk either. Disks fill during a demo. The dock is built to take another crate.
What you keep where
The dock is dumb on purpose. It does not crop, rename, or peek inside. You replace a crate; you do not edit it in place. That boredom is why it is cheap and hard to lose. Copies sit in more than one building. A drive dies. Your crate was already on another hook.
The ticket can be public (the product shot on the landing page) or a short-lived signed URL (the receipt only that user should open). Same dock. Two kinds of key.
When the builder talks storage, this is the crate question, not the cabinet question. After npx create-hackhaton-space-stack@latest, your app can remember names tomorrow. It still needs a dock the moment someone pastes a screenshot. The schema stores a pointer. Deploy does not invent a warehouse for you.
What this unlocks
Facts in the cabinet. Stuff on the dock. A row that stores a URL instead of a blob. That split is how a hackathon upload feature survives past the first twenty files.
The dining room stays light. The attic is someone else's building.