Homer

Talk to your machines.

The agents and models on your own computers, from your phone, tablet, desktop or browser.

Open Homer →

Upload retries

pop-os · Codex

  1. Sunday

  2. Moved uploads behind the proxyPR #203 · merged

  3. Monday

  4. Why do large uploads fail on the Android build? Check the proxy logs on pop-os.

  5. The queue gives up on the first 502 from the proxy and marks the job failed. Nothing retries it.

    PUT /uploads/IMG_4471.mov  502  31 s
    job 8812  failed  attempts=1
  6. Yesterday

  7. Fixed the flaky resume testPR #208 · merged

  8. Today

  9. Standup · upload queue

    Today 09:40 · 14 min · Joe, Maya, Sam

    • Uploads over 50 MB fail on the first 502 and are never retried.04:12
    • Retry with exponential backoff, at most five attempts.04:31
    • Maya reviews before the Thursday build.05:40

    Add retry with backoff to the upload queue

    Hand off to Codex Sent to Codex on pop-os

    1. 04:08

      Maya Anything over fifty megs dies on the first 502.

    2. 04:12

      Joe And the queue never retries it. The job is just marked failed.

    3. 04:31

      Maya Back off and try again. Five attempts, then show the error.

    4. 05:03

      Joe Fine. I'll hand it to Codex on pop-os now.

  10. Codex on pop-os · from standup 05:03

    Add retry with backoff to the upload queue

  11. Read 6 filesqueue.ts · http.ts · types.ts · +3
  12. Edited src/upload/queue.ts+38 −6
  13. Typesclean
  14. Tests48 passed · 3 new
  15. Opened PR #212Retry uploads with backoff
    + const response = await put(job.url, job.body);
    + if (attempt === MAX_ATTEMPTS) return response;
    + const delay = Math.random() * BASE_DELAY_MS * 2 ** attempt;
    + await sleep(delay);

    Resolved · Maya

  16. Review resolvedjitter added in 3f2a91c
  17. Checks settlingChecks passed4 of 55 of 5
  18. Merged into mainby Joe
  19. Deploying to productionLive in production
Feed the box…

src/upload/queue.ts

main

Retry uploads with backoff #212

codex/upload-retry → main

OpenMerged

src/upload/queue.ts+38 −6

−import { put } from "./http";
1+import { put, sleep } from "./http";
2import type { UploadJob, UploadQueue } from "./types";
3
4+const RETRYABLE = new Set([408, 429, 502, 503, 504]);
5+const MAX_ATTEMPTS = 5;
6+const BASE_DELAY_MS = 400;
7+
8export async function drain(queue: UploadQueue) {
9 for (const job of queue.pending()) {
− const response = await put(job.url, job.body);
10+ const response = await putWithRetry(job);
11 if (!response.ok) {
12 queue.fail(job, response.status);
13 continue;
14 }
15 queue.complete(job);
16 }
17}
18+
19+async function putWithRetry(job: UploadJob) {
20+ for (let attempt = 1; ; attempt++) {
21+ const response = await put(job.url, job.body);
22+ if (response.ok || !RETRYABLE.has(response.status)) return response;
23+ if (attempt === MAX_ATTEMPTS) return response;
24+ const delay = BASE_DELAY_MS * 2 ** attempt;
24+ const delay = Math.random() * BASE_DELAY_MS * 2 ** attempt;

Maya

Five clients backing off in lockstep will hit the same 502 again. Jitter?

Codex

Added full jitter in 3f2a91c.

Resolved · Maya · jitter added

25+ await sleep(delay);
26+ }
27+}
28
29export function enqueue(queue: UploadQueue, file: File) {
30 const job = queue.add({ url: uploadUrl(file), body: file });
31 queue.notify(job);
32 return job;
33}
34
35function uploadUrl(file: File) {
36 return `/api/uploads/${encodeURIComponent(file.name)}`;
37}
  1. Your computer is somewhere else.

    The desktop at home, the GPU box in the closet, the Mac at the office. Its agents and models live there.

  2. Homer puts it in front of you.

    Pair it once with a code. Then open it from your phone, tablet, desktop or browser and see what it actually has: which agents are signed in, which models load, whether it is online.

  3. Everything it runs, in one place.

    Start an agent from your phone, review its diff at your desk, pick the conversation up in a browser. The work stays on your machine.

Your Machines
Computers you own, paired once with a code
Agents
Codex, Claude Code, opencode, Cursor Agent
Models
Local models on your own GPUs, or Homer Cloud by invitation
What stays home
Provider credentials, executors and model runtimes stay on the Machine

talk to your machines.